Re: [PATCH] fbdev: atafb: Restrict SuperBlitter to supported formats
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2026-09-07 08:39:05
Also in:
dri-devel, linux-m68k, lkml
Hi Michael, CC linux-m68k On Sun, 6 Sept 2026 at 03:49, Michael Schmitz [off-list ref] wrote:
quoted hunk ↗ jump to hunk
Am 27.08.2026 um 21:39 schrieb Linmao Li:quoted
The SuperBlitter operations derive an integer byte count per pixel. The accelerated fill path handles only one-, two- and four-byte pixels. However, the operations are currently installed for every external framebuffer in SuperVidel RAM, including planar 1/2/4/8-bpp and 24-bpp truecolor modes accepted by the external video parser. For 1/2/4-bpp modes, the byte count becomes zero, so accelerated copies do nothing and fills fall through to 32-bit stores. Planar 8-bpp uses an incompatible memory layout. For 24-bpp modes, fills also use 32-bit stores despite advancing addresses by three bytes per pixel. These cases can corrupt the framebuffer beyond the requested rectangle.I believe 24 bpp mode can be rescued using something like this (entirely untested):--- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c@@ -2463,6 +2463,11 @@ static void svblit_fillrect(struct fb_info *info, case 2: memset16((u16 *)line, pix, rect->width); break; + case 3: + memset(line, pix, ((rect->width * bytespp) % 4)); + line += ((rect->width * bytespp) % 4); + memset32((u32 *)line, pix, (rect->width * bytespp) / 4);
This uses unaligned writes for the largest part. You can avoid that by doing the memset32() first.
+ break; default: memset32((u32 *)line, pix, rect->width); break; Can't test this on hardware, and would need Miro to confirm it works as intended.quoted
Enable the SuperBlitter operations only for the layouts they implement: 8-bpp packed pixels and 16/32-bpp truecolor. Keep the existing software operations for all other external formats. Fixes: d463633d63e6 ("fbdev: atafb: Add support for SuperVidel's SuperBlitter") Signed-off-by: Linmao Li <redacted> --- drivers/video/fbdev/atafb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index 5bca34c45cef3..c3011b61a94b9 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c@@ -3360,7 +3360,11 @@ static int __init atafb_probe(struct platform_device *pdev) memset (screen_base, 0, external_len); /* framebuffer in SV RAM: enable the SuperBlitter */ - if (external_addr >= 0xa0000000) { + if (external_addr >= 0xa0000000 && + ((external_pmode == FB_TYPE_PACKED_PIXELS && + external_depth == 8) || + (external_pmode == -1 && + (external_depth == 16 || external_depth == 32)))) { svblit_regs = ioremap(SVBLIT_REGS_PHYS, 0x100); if (svblit_regs) { svblit_fw = svblit_rd(SVBLIT_VERSION) & 0x1ff;Otherwise, LGTM. @Geert: can you remember if pixel format or bit depth of an external framebuffer can be changed at runtime using fbset??
I am no Atari expert, but IIRC all external framebuffers rely on
being fully set-up before Linux boots?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds