* [PATCH 1/5] m68k: Fix atari mouse movement
2026-08-14 3:17 [PATCH 0/5] m68k SuperVidel patches Michael Schmitz
@ 2026-08-14 3:17 ` Michael Schmitz
2026-08-14 7:53 ` Geert Uytterhoeven
2026-08-14 3:17 ` [PATCH 2/5] fbdev: Give atafb proper parent Michael Schmitz
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Michael Schmitz @ 2026-08-14 3:17 UTC (permalink / raw)
To: linux-m68k, geert; +Cc: schmitzmic, Miro Kropacek
From: Miro Kropacek <miro.kropacek@gmail.com>
Kernels are built with -funsigned-char since version 6.2, resulting
in signed mouse position deltas getting misinterpreted as unsigned.
Cast deltas passed in (unsigned) scancode buffer to correctly
interpret sign.
Fixes: 3bc753c06dd02a35 ("kbuild: treat char as always unsigned")
Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/input/mouse/atarimouse.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c
index b1219cc4d9a2..351aab69e905 100644
--- a/drivers/input/mouse/atarimouse.c
+++ b/drivers/input/mouse/atarimouse.c
@@ -70,9 +70,12 @@ static void atamouse_interrupt(char *buf)
atari_mouse_buttons = buttons;
#endif
- /* only relative events get here */
- dx = buf[1];
- dy = buf[2];
+ /* only relative events get here; the IKBD sends signed 8-bit
+ * deltas, and the kernel builds with -funsigned-char since 6.2,
+ * so an explicit signed cast is required
+ */
+ dx = (s8)buf[1];
+ dy = (s8)buf[2];
input_report_rel(atamouse_dev, REL_X, dx);
input_report_rel(atamouse_dev, REL_Y, dy);
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/5] m68k: Fix atari mouse movement
2026-08-14 3:17 ` [PATCH 1/5] m68k: Fix atari mouse movement Michael Schmitz
@ 2026-08-14 7:53 ` Geert Uytterhoeven
0 siblings, 0 replies; 9+ messages in thread
From: Geert Uytterhoeven @ 2026-08-14 7:53 UTC (permalink / raw)
To: Michael Schmitz; +Cc: linux-m68k, Miro Kropacek, linux-input
Hi Michael,
CC linux-input
On Fri, 14 Aug 2026 at 05:17, Michael Schmitz <schmitzmic@gmail.com> wrote:
> From: Miro Kropacek <miro.kropacek@gmail.com>
>
> Kernels are built with -funsigned-char since version 6.2, resulting
> in signed mouse position deltas getting misinterpreted as unsigned.
>
> Cast deltas passed in (unsigned) scancode buffer to correctly
> interpret sign.
>
> Fixes: 3bc753c06dd02a35 ("kbuild: treat char as always unsigned")
> Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
> Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
> Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Since you're now in the path to upstream, you should add your SoB here
(applies to all patches).
> --- a/drivers/input/mouse/atarimouse.c
> +++ b/drivers/input/mouse/atarimouse.c
> @@ -70,9 +70,12 @@ static void atamouse_interrupt(char *buf)
Alternative, you could change/restore the function's signature to take a
"signed char *".
> atari_mouse_buttons = buttons;
> #endif
>
> - /* only relative events get here */
> - dx = buf[1];
> - dy = buf[2];
> + /* only relative events get here; the IKBD sends signed 8-bit
> + * deltas, and the kernel builds with -funsigned-char since 6.2,
> + * so an explicit signed cast is required
> + */
> + dx = (s8)buf[1];
> + dy = (s8)buf[2];
>
> input_report_rel(atamouse_dev, REL_X, dx);
> input_report_rel(atamouse_dev, REL_Y, dy);
Regardless:
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] fbdev: Give atafb proper parent
2026-08-14 3:17 [PATCH 0/5] m68k SuperVidel patches Michael Schmitz
2026-08-14 3:17 ` [PATCH 1/5] m68k: Fix atari mouse movement Michael Schmitz
@ 2026-08-14 3:17 ` Michael Schmitz
2026-08-14 7:50 ` Helge Deller
2026-08-14 3:17 ` [PATCH 3/5] fbdev: Add support for further video bit depths on atafb:external Michael Schmitz
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Michael Schmitz @ 2026-08-14 3:17 UTC (permalink / raw)
To: linux-m68k, geert; +Cc: schmitzmic, Miro Kropacek, linux-fbdev
From: Miro Kropacek <miro.kropacek@gmail.com>
The atafb fb device registers no parent, causing a missing symlink
(/sys/class/graphics/fb0/device). Xorg fbdevhw driver looks for that
symlink when scanning for devices, so add a parent node for atafb.
Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Cc: <linux-fbdev@vger.kernel.org>
Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
---
drivers/video/fbdev/atafb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index b8ed1c537293..3d540803dc2b 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -3101,6 +3101,11 @@ static int __init atafb_probe(struct platform_device *pdev)
#endif /* ATAFB_EXT */
// strcpy(fb_info.mode->name, "Atari Builtin ");
+ /* Parent the fb device properly: without this fb0 registers as a
+ * virtual sysfs device with no /sys/class/graphics/fb0/device link,
+ * which makes Xorg's fbdevhw reject it ("No devices detected").
+ */
+ fb_info.device = &pdev->dev;
fb_info.fbops = &atafb_ops;
// try to set default (detected; requested) var
do_fb_set_var(&atafb_predefined[default_par - 1], 1);
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 3/5] fbdev: Add support for further video bit depths on atafb:external
2026-08-14 3:17 [PATCH 0/5] m68k SuperVidel patches Michael Schmitz
2026-08-14 3:17 ` [PATCH 1/5] m68k: Fix atari mouse movement Michael Schmitz
2026-08-14 3:17 ` [PATCH 2/5] fbdev: Give atafb proper parent Michael Schmitz
@ 2026-08-14 3:17 ` Michael Schmitz
2026-08-14 3:17 ` [PATCH 4/5] fbdev: Add support for SuperVidel's SuperBlitter Michael Schmitz
2026-08-14 3:17 ` [PATCH 5/5] m68k: Add support for Svethlana Michael Schmitz
4 siblings, 0 replies; 9+ messages in thread
From: Michael Schmitz @ 2026-08-14 3:17 UTC (permalink / raw)
To: linux-m68k, geert; +Cc: schmitzmic, Miro Kropacek, linux-fbdev
From: Miro Kropacek <miro.kropacek@gmail.com>
Supervidel offers additional video bit depths (8-bit chunky, 16-bit
RGB565 (also on the originaln Videl) and ARGB888.
Add code to support these bit depths.
Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Cc: <linux-fbdev@vger.kernel.org>
Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
---
drivers/video/fbdev/atafb.c | 89 ++++++++++++++++++++++++++++++++++---
1 file changed, 82 insertions(+), 7 deletions(-)
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index 3d540803dc2b..50853d7a08e3 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -2081,8 +2081,12 @@ static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
external_pmode == FB_TYPE_PACKED_PIXELS) ?
FB_VISUAL_MONO10 : FB_VISUAL_MONO01;
} else {
- /* Use STATIC if we don't know how to access color registers */
- int visual = external_vgaiobase ?
+ /* Use STATIC if we don't know how to access color registers;
+ * SuperVidel 8bpp chunky (fb in SV RAM) uses the Falcon palette
+ */
+ int visual = (external_vgaiobase ||
+ (external_depth == 8 &&
+ external_addr >= 0xa0000000)) ?
FB_VISUAL_PSEUDOCOLOR :
FB_VISUAL_STATIC_PSEUDOCOLOR;
switch (external_pmode) {
@@ -2159,6 +2163,35 @@ static int ext_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
var->transp.offset = 0;
var->transp.length = 0;
var->transp.msb_right = 0;
+ if (external_pmode == -1 && external_depth == 16) {
+ /* RGB565 truecolor (e.g. SuperVidel native mode) */
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ } else if (external_pmode == -1 && external_depth == 32) {
+ /* ARGB8888 truecolor (e.g. SuperVidel native mode) */
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ } else if (external_pmode == FB_TYPE_PACKED_PIXELS &&
+ external_depth == 8 && external_addr >= 0xa0000000) {
+ /* SuperVidel 8bpp chunky: palette has 8 bits per channel.
+ * Without this, fb_get_color_depth() sees length 0 and
+ * fbcon falls back to its 2-color palette — the console
+ * text (color 7) stays black on black.
+ */
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ }
var->yres_virtual = var->yres;
var->xoffset = 0;
var->yoffset = 0;
@@ -2193,6 +2226,38 @@ static int ext_setcolreg(unsigned int regno, unsigned int red,
{
unsigned char colmask = (1 << external_bitspercol) - 1;
+ if (external_pmode == -1 && external_depth == 16) {
+ /* truecolor: only the pseudo palette for fbcon is needed */
+ if (regno > 15)
+ return 1;
+ ((u32 *)info->pseudo_palette)[regno] = (red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+ return 0;
+ }
+ if (external_pmode == -1 && external_depth == 32) {
+ /* ARGB8888, alpha forced opaque */
+ if (regno > 15)
+ return 1;
+ ((u32 *)info->pseudo_palette)[regno] = 0xff000000 |
+ ((red & 0xff00) << 8) |
+ (green & 0xff00) |
+ ((blue & 0xff00) >> 8);
+ return 0;
+ }
+ if (external_pmode == FB_TYPE_PACKED_PIXELS && external_depth == 8 &&
+ external_addr >= 0xa0000000) {
+ /* SuperVidel native 8bpp chunky scans out via the Falcon
+ * palette registers, honoring all 8 bits per channel
+ */
+ if (regno > 255)
+ return 1;
+ f030_col[regno] = ((red & 0xff00) << 16) |
+ ((green & 0xff00) << 8) |
+ ((blue & 0xff00) >> 8);
+ return 0;
+ }
+
if (!external_vgaiobase)
return 1;
@@ -2422,7 +2487,9 @@ static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
return;
#ifdef ATAFB_FALCON
- if (info->var.bits_per_pixel == 16) {
+ /* chunky modes (Falcon hicolor, external packed/truecolor) */
+ if (info->fix.type == FB_TYPE_PACKED_PIXELS &&
+ info->var.bits_per_pixel > 1) {
cfb_fillrect(info, rect);
return;
}
@@ -2463,7 +2530,9 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
int rev_copy = 0;
#ifdef ATAFB_FALCON
- if (info->var.bits_per_pixel == 16) {
+ /* chunky modes (Falcon hicolor, external packed/truecolor) */
+ if (info->fix.type == FB_TYPE_PACKED_PIXELS &&
+ info->var.bits_per_pixel > 1) {
cfb_copyarea(info, area);
return;
}
@@ -2517,7 +2586,9 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
u32 dx, dy, width, height, pitch;
#ifdef ATAFB_FALCON
- if (info->var.bits_per_pixel == 16) {
+ /* chunky modes (Falcon hicolor, external packed/truecolor) */
+ if (info->fix.type == FB_TYPE_PACKED_PIXELS &&
+ info->var.bits_per_pixel > 1) {
cfb_imageblit(info, image);
return;
}
@@ -2753,7 +2824,7 @@ static void __init atafb_setup_ext(char *spec)
return;
depth = simple_strtoul(p, NULL, 10);
if (depth != 1 && depth != 2 && depth != 4 && depth != 8 &&
- depth != 16 && depth != 24)
+ depth != 16 && depth != 24 && depth != 32)
return;
p = strsep(&spec, ";");
@@ -3131,7 +3202,11 @@ static int __init atafb_probe(struct platform_device *pdev)
atafb_set_disp(&fb_info);
- fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
+ /* truecolor visuals only need the 16-entry console palette; this
+ * also avoids 1 << 32 overflowing at 32bpp
+ */
+ fb_alloc_cmap(&(fb_info.cmap), fb_info.var.bits_per_pixel > 8 ?
+ 16 : 1 << fb_info.var.bits_per_pixel, 0);
dev_info(&pdev->dev, "Determined %dx%d, depth %d\n", fb_info.var.xres,
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 4/5] fbdev: Add support for SuperVidel's SuperBlitter
2026-08-14 3:17 [PATCH 0/5] m68k SuperVidel patches Michael Schmitz
` (2 preceding siblings ...)
2026-08-14 3:17 ` [PATCH 3/5] fbdev: Add support for further video bit depths on atafb:external Michael Schmitz
@ 2026-08-14 3:17 ` Michael Schmitz
2026-08-14 3:17 ` [PATCH 5/5] m68k: Add support for Svethlana Michael Schmitz
4 siblings, 0 replies; 9+ messages in thread
From: Michael Schmitz @ 2026-08-14 3:17 UTC (permalink / raw)
To: linux-m68k, geert; +Cc: schmitzmic, Miro Kropacek, linux-fbdev
From: Miro Kropacek <miro.kropacek@gmail.com>
The SuperVidel graphics FPGA includes a hardware blitter (bit block
transfer engine) operating within the SuperVidel DDR2 video RAM.
Two versions of this blitter exist. Later versions (>= 9) of the
SuperVidel firmware support an asynchronous command FIFO, older
versions must be polled for command completion.
Add hardware-accelerated copyarea, fillrect and imageblit fb
operations (falling back to the non-accelerated versions for
anything that exceeds blitter capabilities).
Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Cc: <linux-fbdev@vger.kernel.org>
Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
---
drivers/video/fbdev/atafb.c | 197 ++++++++++++++++++++++++++++++++++++
1 file changed, 197 insertions(+)
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index 50853d7a08e3..dc2d4154e1b6 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -2304,6 +2304,185 @@ static int ext_detect(void)
return 1;
}
+/* ------------------- SuperVidel SuperBlitter ---------------------- */
+
+/*
+ * Hardware blitter in the SuperVidel FPGA, operating within SV DDR2 RAM.
+ * FW revision >= 9 provides a command FIFO (async operation); older
+ * revisions are programmed directly with busy-polling.
+ */
+#define SVBLIT_REGS_PHYS 0x80010000
+#define SVBLIT_SRC1 0x58 /* bits 26:0 */
+#define SVBLIT_SRC2 0x5c
+#define SVBLIT_DST 0x60
+#define SVBLIT_COUNT 0x64 /* bytes per line - 1 */
+#define SVBLIT_SRC1_OFFSET 0x68 /* line start to next line start */
+#define SVBLIT_SRC2_OFFSET 0x6c
+#define SVBLIT_DST_OFFSET 0x70
+#define SVBLIT_MASK_AND_LINES 0x74 /* bits 11:0: number of lines */
+#define SVBLIT_CONTROL 0x78 /* bit 0: busy/start, bits 4:1: mode */
+#define SVBLIT_VERSION 0x7c /* bits 9:0: FW revision */
+#define SVBLIT_FIFO 0x80 /* wr: data; rd: bit 0 empty, bit 1 full */
+
+/*
+ * SuperBlitter bug: Instead of declared 2048 bytes, 2032 is the real maximum.
+ */
+#define SVBLIT_MAX_SPAN 2032
+
+static void __iomem *svblit_regs;
+static int svblit_fw;
+
+static inline u32 svblit_rd(unsigned int reg)
+{
+ return __raw_readl(svblit_regs + reg);
+}
+
+static inline void svblit_wr(unsigned int reg, u32 val)
+{
+ __raw_writel(val, svblit_regs + reg);
+}
+
+/* wait until all queued blits have finished */
+static void svblit_wait(void)
+{
+ if (svblit_fw >= 9)
+ /* FIFO empty flag = fewer than 9 longwords queued */
+ while (!(svblit_rd(SVBLIT_FIFO) & 1))
+ cpu_relax();
+ while (svblit_rd(SVBLIT_CONTROL) & 1)
+ cpu_relax();
+}
+
+/*
+ * FW >= 9 queues commands through the 512-longword FIFO: a command is
+ * 9 longwords (registers 0x58..0x78 in order), executed whenever >= 9
+ * words are queued and the blitter is idle. The full flag rises at
+ * >= 500 queued words, so below it there is always room for a whole
+ * command — one flag check per command prevents overflow (dropped
+ * words would desync the 9-word framing until an SV reinit, which is
+ * exactly what overflowing did before this guard existed). Older FW
+ * is programmed directly with busy-polling.
+ *
+ * The line byte count field is 11 bits but see SVBLIT_MAX_SPAN.
+ */
+static void svblit_copy(u32 src, u32 dst, u32 nbytes, u32 src_offset,
+ u32 dst_offset, u32 lines)
+{
+ while (nbytes) {
+ u32 chunk = min(nbytes, SVBLIT_MAX_SPAN);
+
+ if (svblit_fw >= 9) {
+ while (svblit_rd(SVBLIT_FIFO) & 2)
+ cpu_relax();
+ svblit_wr(SVBLIT_FIFO, src);
+ svblit_wr(SVBLIT_FIFO, 0);
+ svblit_wr(SVBLIT_FIFO, dst);
+ svblit_wr(SVBLIT_FIFO, chunk - 1);
+ svblit_wr(SVBLIT_FIFO, src_offset);
+ svblit_wr(SVBLIT_FIFO, 0);
+ svblit_wr(SVBLIT_FIFO, dst_offset);
+ svblit_wr(SVBLIT_FIFO, lines);
+ svblit_wr(SVBLIT_FIFO, 0x01);
+ } else {
+ while (svblit_rd(SVBLIT_CONTROL) & 1)
+ cpu_relax();
+ svblit_wr(SVBLIT_SRC1, src);
+ svblit_wr(SVBLIT_SRC2, 0);
+ svblit_wr(SVBLIT_DST, dst);
+ svblit_wr(SVBLIT_COUNT, chunk - 1);
+ svblit_wr(SVBLIT_SRC1_OFFSET, src_offset);
+ svblit_wr(SVBLIT_SRC2_OFFSET, 0);
+ svblit_wr(SVBLIT_DST_OFFSET, dst_offset);
+ svblit_wr(SVBLIT_MASK_AND_LINES, lines);
+ svblit_wr(SVBLIT_CONTROL, 0x01);
+ }
+
+ src += chunk;
+ dst += chunk;
+ nbytes -= chunk;
+ }
+}
+
+static int svblit_sync(struct fb_info *info)
+{
+ svblit_wait();
+ return 0;
+}
+
+static void svblit_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ u32 bytespp = info->var.bits_per_pixel / 8;
+ u32 pitch = info->fix.line_length;
+
+ /*
+ * The blitter walks lines in ascending order, so overlapping
+ * moves down/right would read already overwritten data. Those
+ * are rare for fbcon (scrolling backwards); leave them and
+ * oversized areas to the CPU.
+ */
+ if (area->height > 4095 ||
+ area->dy > area->sy ||
+ (area->dy == area->sy && area->dx > area->sx)) {
+ svblit_wait();
+ cfb_copyarea(info, area);
+ return;
+ }
+
+ svblit_copy(external_addr + area->sy * pitch + area->sx * bytespp,
+ external_addr + area->dy * pitch + area->dx * bytespp,
+ area->width * bytespp, pitch, pitch, area->height);
+ /* async: every CPU access to the fb goes through svblit_wait() */
+}
+
+static void svblit_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ u32 bytespp = info->var.bits_per_pixel / 8;
+ u32 pitch = info->fix.line_length;
+ u8 *line;
+ u32 pix;
+
+ svblit_wait(); /* the CPU is about to touch the fb */
+
+ if (rect->rop != ROP_COPY || rect->height <= 1 ||
+ rect->height > 4096) {
+ cfb_fillrect(info, rect);
+ return;
+ }
+
+ pix = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+ ((u32 *)info->pseudo_palette)[rect->color] : rect->color;
+
+ /* draw the first line with the CPU ... */
+ line = (u8 *)info->screen_base + rect->dy * pitch +
+ rect->dx * bytespp;
+ switch (bytespp) {
+ case 1:
+ memset(line, pix, rect->width);
+ break;
+ case 2:
+ memset16((u16 *)line, pix, rect->width);
+ break;
+ default:
+ memset32((u32 *)line, pix, rect->width);
+ break;
+ }
+
+ /* ... and let the blitter replicate it into the other lines */
+ svblit_copy(external_addr + rect->dy * pitch + rect->dx * bytespp,
+ external_addr + (rect->dy + 1) * pitch +
+ rect->dx * bytespp,
+ rect->width * bytespp, 0, pitch, rect->height - 1);
+}
+
+static void svblit_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ svblit_wait(); /* CPU rendering must not race queued blits */
+ cfb_imageblit(info, image);
+}
+
#endif /* ATAFB_EXT */
/* ------ This is the same for most hardware types -------- */
@@ -3168,6 +3347,24 @@ static int __init atafb_probe(struct platform_device *pdev)
phys_screen_base = external_addr;
screen_len = external_len & PAGE_MASK;
memset (screen_base, 0, external_len);
+
+ /* framebuffer in SV RAM: enable the SuperBlitter */
+ if (external_addr >= 0xa0000000) {
+ svblit_regs = ioremap(SVBLIT_REGS_PHYS, 0x100);
+ if (svblit_regs) {
+ svblit_fw = svblit_rd(SVBLIT_VERSION) & 0x1ff;
+ atafb_ops.fb_fillrect = svblit_fillrect;
+ atafb_ops.fb_copyarea = svblit_copyarea;
+ atafb_ops.fb_imageblit = svblit_imageblit;
+ atafb_ops.fb_sync = svblit_sync;
+ fb_info.flags |= FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
+ dev_info(&pdev->dev,
+ "SuperBlitter enabled, FW revision %d (%s)\n",
+ svblit_fw, svblit_fw >= 9 ?
+ "async FIFO" : "sync");
+ }
+ }
}
#endif /* ATAFB_EXT */
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 5/5] m68k: Add support for Svethlana
2026-08-14 3:17 [PATCH 0/5] m68k SuperVidel patches Michael Schmitz
` (3 preceding siblings ...)
2026-08-14 3:17 ` [PATCH 4/5] fbdev: Add support for SuperVidel's SuperBlitter Michael Schmitz
@ 2026-08-14 3:17 ` Michael Schmitz
2026-08-14 8:07 ` Geert Uytterhoeven
4 siblings, 1 reply; 9+ messages in thread
From: Michael Schmitz @ 2026-08-14 3:17 UTC (permalink / raw)
To: linux-m68k, geert; +Cc: schmitzmic, Miro Kropacek
From: Miro Kropacek <miro.kropacek@gmail.com>
The SuperVidel FPGA contains an OpenCore ethernet package. Add
platform device data and other necessary definitions to support
this device on Atari.
The ethoc module must be enabled separately by the user.
Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
---
arch/m68k/Kconfig.devices | 12 ++++++
arch/m68k/atari/config.c | 71 +++++++++++++++++++++++++++++++
arch/m68k/include/asm/atariints.h | 2 +-
arch/m68k/include/asm/irq.h | 6 +--
4 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
index e6e3efac1840..48f964d1615e 100644
--- a/arch/m68k/Kconfig.devices
+++ b/arch/m68k/Kconfig.devices
@@ -67,6 +67,18 @@ config ATARI_ETHERNAT
To compile the actual ethernet driver, choose Y or M for the SMC91X
option in the network device section; the module will be called smc91x.
+config ATARI_SVETHLANA
+ bool "Atari SuperVidel SVEthlana Ethernet support"
+ depends on ATARI
+ help
+ Say Y to include support for the SVEthlana network adapter built
+ into the SuperVidel FPGA. SuperVidel firmware version 10 or newer
+ is required (older firmware lacks the Ethernet DMA).
+
+ To compile the actual ethernet driver, choose Y or M for the ETHOC
+ option in the network device section; the module will be called
+ ethoc.
+
config ATARI_ETHERNEC
bool "Atari EtherNEC Ethernet support"
depends on ATARI_ROM_ISA
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index ee2d061efb2a..86f07d0b85e0 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -34,6 +34,7 @@
#include <linux/platform_device.h>
#include <linux/usb/isp116x.h>
#include <linux/module.h>
+#include <net/ethoc.h>
#include <asm/bootinfo.h>
#include <asm/bootinfo-atari.h>
@@ -748,6 +749,62 @@ static struct platform_device *atari_ethernat_devices[] __initdata = {
};
#endif /* CONFIG_ATARI_ETHERNAT */
+#ifdef CONFIG_ATARI_SVETHLANA
+/*
+ * SVEthlana: OpenCores 10/100 Mbps Ethernet MAC in the SuperVidel FPGA,
+ * handled by the ethoc driver. Requires SuperVidel firmware version 10
+ * or newer (Ethernet DMA).
+ *
+ * The MAC can only DMA within the SuperVidel DDR RAM, so the packet
+ * buffers are carved out of the top of the DDR; the framebuffer lives
+ * at the bottom.
+ */
+
+#define ATARI_SVETHLANA_PHYS_ADDR 0x80012000
+#define ATARI_SVETHLANA_IRQ 141 /* vector 0xc5 */
+
+#define ATARI_SV_VERSION_PHYS_ADDR 0x8001007c
+#define ATARI_SV_DDR_END 0xa8000000
+/* 128 packet buffers of 1536 bytes each, the maximum ethoc supports */
+#define SVETHLANA_BUF_SIZE (128 * 1536)
+
+static struct resource svethlana_resources[] = {
+ [0] = {
+ .name = "ethoc-regs",
+ .start = ATARI_SVETHLANA_PHYS_ADDR,
+ .end = ATARI_SVETHLANA_PHYS_ADDR + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "ethoc-buf",
+ .start = ATARI_SV_DDR_END - SVETHLANA_BUF_SIZE,
+ .end = ATARI_SV_DDR_END - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .name = "ethoc-irq",
+ .start = ATARI_SVETHLANA_IRQ,
+ .end = ATARI_SVETHLANA_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ethoc_platform_data svethlana_platform_data = {
+ .phy_id = -1,
+ .big_endian = true,
+};
+
+static struct platform_device svethlana_device = {
+ .name = "ethoc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(svethlana_resources),
+ .resource = svethlana_resources,
+ .dev = {
+ .platform_data = &svethlana_platform_data,
+ },
+};
+#endif /* CONFIG_ATARI_SVETHLANA */
+
#ifdef CONFIG_ATARI_ETHERNEC
/*
* EtherNEC: RTL8019 (NE2000 compatible) Ethernet chipset,
@@ -892,6 +949,20 @@ static int __init atari_platform_init(void)
}
#endif
+#ifdef CONFIG_ATARI_SVETHLANA
+ {
+ void __iomem *sv_version;
+
+ sv_version = ioremap(ATARI_SV_VERSION_PHYS_ADDR, 4);
+ if (sv_version) {
+ if (hwreg_present(sv_version) &&
+ (__raw_readl(sv_version) & 0x3ff) >= 10)
+ rv = platform_device_register(&svethlana_device);
+ iounmap(sv_version);
+ }
+ }
+#endif
+
#ifdef CONFIG_ATARI_ETHERNEC
{
int error;
diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h
index 6321c4495620..cb15361d14e9 100644
--- a/arch/m68k/include/asm/atariints.h
+++ b/arch/m68k/include/asm/atariints.h
@@ -32,7 +32,7 @@
#define VME_SOURCE_BASE 56
#define VME_MAX_SOURCES 16
-#define NUM_ATARI_SOURCES 141
+#define NUM_ATARI_SOURCES 142
/* convert vector number to int source number */
#define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8)))
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index 2263e92d418a..8bac43d0f49d 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -10,8 +10,8 @@
* different m68k hosts compiled into the kernel.
* Currently the Atari has 72 and the Amiga 24, but if both are
* supported in the kernel it is better to make room for 72.
- * With EtherNAT add-on card on Atari, the highest interrupt
- * number is 140 so NR_IRQS needs to be 141.
+ * With the SVEthlana adapter in the SuperVidel on Atari, the highest
+ * interrupt number is 141 so NR_IRQS needs to be 142.
*/
#if defined(CONFIG_COLDFIRE)
#define NR_IRQS 256
@@ -19,7 +19,7 @@
defined(CONFIG_SUN3X) || defined(CONFIG_VIRT)
#define NR_IRQS 200
#elif defined(CONFIG_ATARI)
-#define NR_IRQS 141
+#define NR_IRQS 142
#elif defined(CONFIG_MAC)
#define NR_IRQS 72
#elif defined(CONFIG_Q40)
--
2.17.1
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 5/5] m68k: Add support for Svethlana
2026-08-14 3:17 ` [PATCH 5/5] m68k: Add support for Svethlana Michael Schmitz
@ 2026-08-14 8:07 ` Geert Uytterhoeven
0 siblings, 0 replies; 9+ messages in thread
From: Geert Uytterhoeven @ 2026-08-14 8:07 UTC (permalink / raw)
To: Michael Schmitz; +Cc: linux-m68k, Miro Kropacek
Hi Michael,
Thanks for your patch!
On Fri, 14 Aug 2026 at 05:18, Michael Schmitz <schmitzmic@gmail.com> wrote:
> From: Miro Kropacek <miro.kropacek@gmail.com>
>
> The SuperVidel FPGA contains an OpenCore ethernet package. Add
> platform device data and other necessary definitions to support
> this device on Atari.
>
> The ethoc module must be enabled separately by the user.
>
> Signed-off-by: Miro Kropacek <miro.kropacek@gmail.com>
> Reviewed-by: Michael Schmitz <schmitzmic@gmail.com>
> Link: https://lists.debian.org/debian-68k/2026/08/msg00000.html
Since you're now in the path to upstream, you should add your SoB here
> --- a/arch/m68k/atari/config.c
> +++ b/arch/m68k/atari/config.c
> @@ -34,6 +34,7 @@
> #include <linux/platform_device.h>
> #include <linux/usb/isp116x.h>
> #include <linux/module.h>
> +#include <net/ethoc.h>
>
> #include <asm/bootinfo.h>
> #include <asm/bootinfo-atari.h>
> @@ -748,6 +749,62 @@ static struct platform_device *atari_ethernat_devices[] __initdata = {
> };
> #endif /* CONFIG_ATARI_ETHERNAT */
>
> +#ifdef CONFIG_ATARI_SVETHLANA
> +/*
> + * SVEthlana: OpenCores 10/100 Mbps Ethernet MAC in the SuperVidel FPGA,
> + * handled by the ethoc driver. Requires SuperVidel firmware version 10
> + * or newer (Ethernet DMA).
> + *
> + * The MAC can only DMA within the SuperVidel DDR RAM, so the packet
> + * buffers are carved out of the top of the DDR; the framebuffer lives
> + * at the bottom.
> + */
> +
> +#define ATARI_SVETHLANA_PHYS_ADDR 0x80012000
> +#define ATARI_SVETHLANA_IRQ 141 /* vector 0xc5 */
> +
> +#define ATARI_SV_VERSION_PHYS_ADDR 0x8001007c
> +#define ATARI_SV_DDR_END 0xa8000000
> +/* 128 packet buffers of 1536 bytes each, the maximum ethoc supports */
> +#define SVETHLANA_BUF_SIZE (128 * 1536)
> +
> +static struct resource svethlana_resources[] = {
> + [0] = {
> + .name = "ethoc-regs",
> + .start = ATARI_SVETHLANA_PHYS_ADDR,
> + .end = ATARI_SVETHLANA_PHYS_ADDR + 0x7ff,
> + .flags = IORESOURCE_MEM,
> + },
> + [1] = {
> + .name = "ethoc-buf",
> + .start = ATARI_SV_DDR_END - SVETHLANA_BUF_SIZE,
> + .end = ATARI_SV_DDR_END - 1,
> + .flags = IORESOURCE_MEM,
> + },
> + [2] = {
> + .name = "ethoc-irq",
> + .start = ATARI_SVETHLANA_IRQ,
> + .end = ATARI_SVETHLANA_IRQ,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +static struct ethoc_platform_data svethlana_platform_data = {
> + .phy_id = -1,
> + .big_endian = true,
Does SVEthlana contain a unique MAC address? Without this, you probably
get a different random MAC, and thus a different IP address from DHCP.
> +};
> +
> +static struct platform_device svethlana_device = {
> + .name = "ethoc",
> + .id = -1,
> + .num_resources = ARRAY_SIZE(svethlana_resources),
> + .resource = svethlana_resources,
> + .dev = {
> + .platform_data = &svethlana_platform_data,
> + },
> +};
> +#endif /* CONFIG_ATARI_SVETHLANA */
> +
> #ifdef CONFIG_ATARI_ETHERNEC
> /*
> * EtherNEC: RTL8019 (NE2000 compatible) Ethernet chipset,
> @@ -892,6 +949,20 @@ static int __init atari_platform_init(void)
> }
> #endif
>
> +#ifdef CONFIG_ATARI_SVETHLANA
> + {
> + void __iomem *sv_version;
> +
> + sv_version = ioremap(ATARI_SV_VERSION_PHYS_ADDR, 4);
> + if (sv_version) {
> + if (hwreg_present(sv_version) &&
> + (__raw_readl(sv_version) & 0x3ff) >= 10)
> + rv = platform_device_register(&svethlana_device);
This unconditionally writes to rv, potentially overwriting an error
code stored by a failed EtherNAT registration attempt.
> + iounmap(sv_version);
> + }
> + }
> +#endif
> +
> #ifdef CONFIG_ATARI_ETHERNEC
> {
> int error;
The rest LGTM.
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
^ permalink raw reply [flat|nested] 9+ messages in thread