Skip to contentSkip to conversation

Atari frame buffer fixes

PATCH In review Geert Uytterhoeven 2 participants 12 messages Dec 21, 2008 – Dec 23, 2008 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

cover Atari frame buffer fixes

This patchsets contains several fixes for the Atari frame buffer device, and includes a refactoring of the c2p (Chunky-to-Planar) code:
[1] fbdev: atafb - Fix line length handling
[2] fbdev: atafb - Fix 16 bpp console
[3] fbdev: c2p - Cleanups
[4] fbdev: c2p - Extract common c2p core to c2p_core.h
[5] fbdev: c2p/atafb - Add support for Atari interleaved bitplanes
[6] fbdev: c2p - Rename c2p to c2p_planar and correct indentation

If nobody objects, I'd like to push this to Linus via the m68k tree, as the c2p code is used by m68k drivers (atafb and amifb) only.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

#1 lore raw

PATCH 1/6 fbdev: atafb - Fix line length handling

- Make sure par->next_line is always set (this was done for Falcon only),

    as all the text console drawing operations need a valid par->next_line,

- Make sure fix->line_length is always set, as some userspace applications need it because they don't have fallback code for the case where it's zero.

---
 drivers/video/atafb.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/video/atafb.c +8 -4
@@ -614,7 +614,7 @@ static int tt_encode_fix(struct fb_fix_s
 	fix->xpanstep = 0;
 	fix->ypanstep = 1;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -691,6 +691,7 @@ static int tt_decode_var(struct fb_var_s
 		return -EINVAL;
 	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
+	par->next_line = linelen;
 	return 0;
 }
 
@@ -918,7 +919,7 @@ static int falcon_encode_fix(struct fb_f
 		fix->visual = FB_VISUAL_TRUECOLOR;
 		fix->xpanstep = 2;
 	}
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -1852,7 +1853,7 @@ static int stste_encode_fix(struct fb_fi
 		fix->ypanstep = 0;
 	}
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	fix->accel = FB_ACCEL_ATARIBLITT;
 	return 0;
 }
@@ -1910,6 +1911,7 @@ static int stste_decode_var(struct fb_va
 		return -EINVAL;
 	par->yres_virtual = yres_virtual;
 	par->screen_base = screen_base + var->yoffset * linelen;
+	par->next_line = linelen;
 	return 0;
 }
 
@@ -2169,7 +2171,7 @@ static int ext_encode_fix(struct fb_fix_
 	fix->xpanstep = 0;
 	fix->ypanstep = 0;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->next_line;
 	return 0;
 }
 
@@ -2184,6 +2186,8 @@ static int ext_decode_var(struct fb_var_
 	    var->xoffset > 0 ||
 	    var->yoffset > 0)
 		return -EINVAL;
+
+	par->next_line = external_xres_virtual * external_depth / 8;
 	return 0;
 }
 
Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#2 lore raw

PATCH 2/6 fbdev: atafb - Fix 16 bpp console

In reply to Geert Uytterhoeven

- 16 bpp must use the cfb_*() ops
- 16 bpp needs to set up info->pseudo_palette[] (was fbcon_cfb16_cmap[] in

    2.4.x)

- Kill commented out 2.4.x fbcon remnants

---
 drivers/video/atafb.c |   74 ++++++++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 44 deletions(-)
drivers/video/atafb.c +30 -44
@@ -149,6 +149,7 @@ static struct atafb_par {
 			short mono;
 			short ste_mode;
 			short bpp;
+			u32 pseudo_palette[16];
 		} falcon;
 #endif
 		/* Nothing needed for external mode */
@@ -885,10 +886,6 @@ static int vdl_prescale[4][3] = {
 /* Default hsync timing [mon_type] in picoseconds */
 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
 
-#ifdef FBCON_HAS_CFB16
-static u16 fbcon_cfb16_cmap[16];
-#endif
-
 static inline int hxx_prescale(struct falcon_hw *hw)
 {
 	return hw->ste_mode ? 16
@@ -1736,10 +1733,10 @@ static int falcon_setcolreg(unsigned int
 			(((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
 			(((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
 			((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
-#ifdef FBCON_HAS_CFB16
-		fbcon_cfb16_cmap[regno] = ((red & 0xf800) |
-					   ((green & 0xfc00) >> 5) |
-					   ((blue & 0xf800) >> 11));
+#ifdef ATAFB_FALCON
+		((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
+						       ((green & 0xfc00) >> 5) |
+						       ((blue & 0xf800) >> 11));
 #endif
 	}
 	return 0;
@@ -2447,42 +2444,6 @@ static void atafb_set_disp(struct fb_inf
 	atafb_get_fix(&info->fix, info);
 
 	info->screen_base = (void *)info->fix.smem_start;
-
-	switch (info->fix.type) {
-	case FB_TYPE_INTERLEAVED_PLANES:
-		switch (info->var.bits_per_pixel) {
-		case 2:
-			// display->dispsw = &fbcon_iplan2p2;
-			break;
-		case 4:
-			// display->dispsw = &fbcon_iplan2p4;
-			break;
-		case 8:
-			// display->dispsw = &fbcon_iplan2p8;
-			break;
-		}
-		break;
-	case FB_TYPE_PACKED_PIXELS:
-		switch (info->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-		case 1:
-			// display->dispsw = &fbcon_mfb;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB8
-		case 8:
-			// display->dispsw = &fbcon_cfb8;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-			// display->dispsw = &fbcon_cfb16;
-			// display->dispsw_data = fbcon_cfb16_cmap;
-			break;
-#endif
-		}
-		break;
-	}
 }
 
 static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@@ -2553,6 +2514,13 @@ static void atafb_fillrect(struct fb_inf
 	if (!rect->width || !rect->height)
 		return;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_fillrect(info, rect);
+		return;
+	}
+#endif
+
 	/*
 	 * We could use hardware clipping but on many cards you get around
 	 * hardware clipping by writing to framebuffer directly.
@@ -2587,6 +2555,13 @@ static void atafb_copyarea(struct fb_inf
 	u32 dx, dy, sx, sy, width, height;
 	int rev_copy = 0;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_copyarea(info, area);
+		return;
+	}
+#endif
+
 	/* clip the destination */
 	x2 = area->dx + area->width;
 	y2 = area->dy + area->height;
@@ -2636,6 +2611,13 @@ static void atafb_imageblit(struct fb_in
 	const char *src;
 	u32 dx, dy, width, height, pitch;
 
+#ifdef ATAFB_FALCON
+	if (info->var.bits_per_pixel == 16) {
+		cfb_imageblit(info, image);
+		return;
+	}
+#endif
+
 	/*
 	 * We could use hardware clipping but on many cards you get around
 	 * hardware clipping by writing to framebuffer directly like we are
@@ -3229,6 +3211,10 @@ int __init atafb_init(void)
 	// tries to read from HW which may not be initialized yet
 	// so set sane var first, then call atafb_set_par
 	atafb_get_var(&fb_info.var, &fb_info);
+
+#ifdef ATAFB_FALCON
+	fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
+#endif
 	fb_info.flags = FBINFO_FLAG_DEFAULT;
 
 	if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#3 lore raw

PATCH 3/6 fbdev: c2p - Cleanups

In reply to Geert Uytterhoeven

- Improve comments and naming
- Use void * for arbitrary pointers
- Use a union to represent pixels/words, to avoid casts

---
 drivers/video/c2p.c |   80 +++++++++++++++++++++++++++-------------------------
 drivers/video/c2p.h |    6 +--
 2 files changed, 45 insertions(+), 41 deletions(-)
drivers/video/c2p.c +42 -38
@@ -54,7 +54,7 @@ static inline u32 get_mask(int n)
     return 0;
 }
 
-#define transp_nx1(d, n)				\
+#define transp8_nx1(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -67,7 +67,7 @@ static inline u32 get_mask(int n)
 	_transp(d, 6, 7, n, mask);			\
     } while (0)
 
-#define transp_nx2(d, n)				\
+#define transp8_nx2(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -78,40 +78,41 @@ static inline u32 get_mask(int n)
 	_transp(d, 5, 7, n, mask);			\
     } while (0)
 
-#define transp_nx4(d, n)				\
+#define transp8_nx4(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
+	/* Single block */				\
 	_transp(d, 0, 4, n, mask);			\
 	_transp(d, 1, 5, n, mask);			\
 	_transp(d, 2, 6, n, mask);			\
 	_transp(d, 3, 7, n, mask);			\
     } while (0)
 
-#define transp(d, n, m)	transp_nx ## m(d, n)
+#define transp8(d, n, m)	transp8_nx ## m(d, n)
 
 
     /*
      *  Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words
      *  containing
      *    - 32 8-bit chunky pixels on input
-     *    - permuted planar data on output
+     *    - permutated planar data (1 plane per 32-bit word) on output
      */
 
-static void c2p_8bpp(u32 d[8])
+static void c2p_32x8(u32 d[8])
 {
-    transp(d, 16, 4);
-    transp(d, 8, 2);
-    transp(d, 4, 1);
-    transp(d, 2, 4);
-    transp(d, 1, 2);
+    transp8(d, 16, 4);
+    transp8(d, 8, 2);
+    transp8(d, 4, 1);
+    transp8(d, 2, 4);
+    transp8(d, 1, 2);
 }
 
 
     /*
-     *  Array containing the permution indices of the planar data after c2p
+     *  Array containing the permutation indices of the planar data after c2p
      */
 
-static const int perm_c2p_8bpp[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
+static const int perm_c2p_32x8[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
 
 
     /*
@@ -130,12 +131,12 @@ static inline unsigned long comp(unsigne
      *  Store a full block of planar data after c2p conversion
      */
 
-static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
 {
     int i;
 
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = d[perm_c2p_8bpp[i]];
+	*(u32 *)dst = d[perm_c2p_32x8[i]];
 }
 
 
@@ -143,13 +144,13 @@ static inline void store_planar(char *ds
      *  Store a partial block of planar data after c2p conversion
      */
 
-static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
 				       u32 d[8], u32 mask)
 {
     int i;
 
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+	*(u32 *)dst = comp(d[perm_c2p_32x8[i]], *(u32 *)dst, mask);
 }
 
 
@@ -166,18 +167,21 @@ static inline void store_planar_masked(c
      *  @bpp: Bits per pixel of the planar frame buffer (1-8)
      */
 
-void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
+void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width, u32 height,
 	 u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
 {
-    int dst_idx;
-    u32 d[8], first, last, w;
+    union {
+	u8 pixels[32];
+	u32 words[8];
+    } d;
+    u32 dst_idx, first, last, w;
     const u8 *c;
-    u8 *p;
+    void *p;
 
     dst += dy*dst_nextline+(dx & ~31);
     dst_idx = dx % 32;
-    first = ~0UL >> dst_idx;
-    last = ~(~0UL >> ((dst_idx+width) % 32));
+    first = 0xffffffffU >> dst_idx;
+    last = ~(0xffffffffU >> ((dst_idx+width) % 32));
     while (height--) {
 	c = src;
 	p = dst;
@@ -185,11 +189,11 @@ void c2p(u8 *dst, const u8 *src, u32 dx,
 	if (dst_idx+width <= 32) {
 	    /* Single destination word */
 	    first &= last;
-	    memset(d, 0, sizeof(d));
-	    memcpy((u8 *)d+dst_idx, c, width);
+	    memset(d.pixels, 0, sizeof(d));
+	    memcpy(d.pixels+dst_idx, c, width);
 	    c += width;
-	    c2p_8bpp(d);
-	    store_planar_masked(p, dst_nextplane, bpp, d, first);
+	    c2p_32x8(d.words);
+	    store_planar_masked(p, dst_nextplane, bpp, d.words, first);
 	    p += 4;
 	} else {
 	    /* Multiple destination words */
@@ -197,30 +201,30 @@ void c2p(u8 *dst, const u8 *src, u32 dx,
 	    /* Leading bits */
 	    if (dst_idx) {
 		w = 32 - dst_idx;
-		memset(d, 0, dst_idx);
-		memcpy((u8 *)d+dst_idx, c, w);
+		memset(d.pixels, 0, dst_idx);
+		memcpy(d.pixels+dst_idx, c, w);
 		c += w;
-		c2p_8bpp(d);
-		store_planar_masked(p, dst_nextplane, bpp, d, first);
+		c2p_32x8(d.words);
+		store_planar_masked(p, dst_nextplane, bpp, d.words, first);
 		p += 4;
 		w = width-w;
 	    }
 	    /* Main chunk */
 	    while (w >= 32) {
-		memcpy(d, c, 32);
+		memcpy(d.pixels, c, 32);
 		c += 32;
-		c2p_8bpp(d);
-		store_planar(p, dst_nextplane, bpp, d);
+		c2p_32x8(d.words);
+		store_planar(p, dst_nextplane, bpp, d.words);
 		p += 4;
 		w -= 32;
 	    }
 	    /* Trailing bits */
 	    w %= 32;
 	    if (w > 0) {
-		memcpy(d, c, w);
-		memset((u8 *)d+w, 0, 32-w);
-		c2p_8bpp(d);
-		store_planar_masked(p, dst_nextplane, bpp, d, last);
+		memcpy(d.pixels, c, w);
+		memset(d.pixels+w, 0, 32-w);
+		c2p_32x8(d.words);
+		store_planar_masked(p, dst_nextplane, bpp, d.words, last);
 	    }
 	}
 	src += src_nextline;
drivers/video/c2p.h +3 -3
@@ -10,7 +10,7 @@
 
 #include <linux/types.h>
 
-extern void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
-		u32 dst_nextline, u32 dst_nextplane, u32 src_nextline,
-		u32 bpp);
+extern void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+	        u32 height, u32 dst_nextline, u32 dst_nextplane,
+		u32 src_nextline, u32 bpp);
 
Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#4 lore raw

Re: [patch 3/6] fbdev: c2p - Cleanups

drivers/video/c2p.c static inline u32 get_mask(int n)

Quoted 30 lines · On Sun, 21 Dec 2008 16:01:02 +0100 Geert Uytterhoeven <[email protected]>…

- Improve comments and naming
- Use void * for arbitrary pointers
- Use a union to represent pixels/words, to avoid casts

---
 drivers/video/c2p.c |   80 +++++++++++++++++++++++++++-------------------------
 drivers/video/c2p.h |    6 +--
 2 files changed, 45 insertions(+), 41 deletions(-)
drivers/video/c2p.c +2 -2
@@ -54,7 +54,7 @@ static inline u32 get_mask(int n)
     return 0;
 }
 
-#define transp_nx1(d, n)				\
+#define transp8_nx1(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -67,7 +67,7 @@ static inline u32 get_mask(int n)
 	_transp(d, 6, 7, n, mask);			\
     } while (0)
-#define transp_nx2(d, n)				\
+#define transp8_nx2(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -78,40 +78,41 @@ static inline u32 get_mask(int n)

I was going to say:

- these don't need to be implemented as macros

- these reference their arguments multiple times and will cause problems when passed an expression with side-effects.

- they should be converted to inlined C function, but those functions will be waaaaaaaay to big to inline.

but happily, they appear to not have any callers?

Quoted 6 lines
drivers/video/c2p.c +1 -1
 	_transp(d, 5, 7, n, mask);			\
     } while (0)
 
-#define transp_nx4(d, n)				\
+#define transp8_nx4(d, n)				\
     do {						\

drivers/video/c2p.c static inline u32 get_mask(int n) · line 91

Quoted 10 lines
drivers/video/c2p.c +2 -1
 	u32 mask = get_mask(n);				\
+	/* Single block */				\
 	_transp(d, 0, 4, n, mask);			\
 	_transp(d, 1, 5, n, mask);			\
 	_transp(d, 2, 6, n, mask);			\
 	_transp(d, 3, 7, n, mask);			\
     } while (0)
 
-#define transp(d, n, m)	transp_nx ## m(d, n)
+#define transp8(d, n, m)	transp8_nx ## m(d, n)

ah, yes they do. Tricky!

Quoted 21 lines
drivers/video/c2p.c +2 -2
     /*
@@ -130,12 +131,12 @@ static inline unsigned long comp(unsigne
      *  Store a full block of planar data after c2p conversion
      */
 
-static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
 {
     int i;
 
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = d[perm_c2p_8bpp[i]];
+	*(u32 *)dst = d[perm_c2p_32x8[i]];
 }
 
 
@@ -143,13 +144,13 @@ static inline void store_planar(char *ds
      *  Store a partial block of planar data after c2p conversion
      */
 

drivers/video/c2p.c static inline void store_planar(char *ds · line 154

Quoted 10 lines
drivers/video/c2p.c +2 -2
-static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
 				       u32 d[8], u32 mask)
 {
     int i;
 
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+	*(u32 *)dst = comp(d[perm_c2p_32x8[i]], *(u32 *)dst, mask);
 }

This driver needs a inlineectomy.

#5 lore raw

Re: [patch 3/6] fbdev: c2p - Cleanups

Quoted 36 lines · Andrew Morton

drivers/video/c2p.c static inline u32 get_mask(int n)

Quoted 30 lines · On Sun, 21 Dec 2008 16:01:02 +0100 Geert Uytterhoeven <[email protected]>…

- Improve comments and naming
- Use void * for arbitrary pointers
- Use a union to represent pixels/words, to avoid casts

---
 drivers/video/c2p.c |   80 +++++++++++++++++++++++++++-------------------------
 drivers/video/c2p.h |    6 +--
 2 files changed, 45 insertions(+), 41 deletions(-)
drivers/video/c2p.c +2 -2
@@ -54,7 +54,7 @@ static inline u32 get_mask(int n)
     return 0;
 }
 
-#define transp_nx1(d, n)				\
+#define transp8_nx1(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -67,7 +67,7 @@ static inline u32 get_mask(int n)
 	_transp(d, 6, 7, n, mask);			\
     } while (0)
-#define transp_nx2(d, n)				\
+#define transp8_nx2(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
 	/* First block */				\
@@ -78,40 +78,41 @@ static inline u32 get_mask(int n)

I was going to say:

Quoted 4 lines

- these don't need to be implemented as macros

- these reference their arguments multiple times and will cause problems when passed an expression with side-effects.

You're right. These could be inline functions.

Quoted 2 lines

- they should be converted to inlined C function, but those functions will be waaaaaaaay to big to inline.

They're actually not _that_ big. And "n" is known at compile-time.

Quoted 16 lines

but happily, they appear to not have any callers?

Quoted 14 lines
drivers/video/c2p.c +2 -1
 	_transp(d, 5, 7, n, mask);			\
     } while (0)
 
-#define transp_nx4(d, n)				\
+#define transp8_nx4(d, n)				\
     do {						\
 	u32 mask = get_mask(n);				\
+	/* Single block */				\
 	_transp(d, 0, 4, n, mask);			\
 	_transp(d, 1, 5, n, mask);			\
 	_transp(d, 2, 6, n, mask);			\
 	_transp(d, 3, 7, n, mask);			\
     } while (0)
 
Quoted 4 lines

drivers/video/c2p.c static inline u32 get_mask(int n) · line 91

Quoted 2 lines
drivers/video/c2p.c +1 -1
-#define transp(d, n, m)	transp_nx ## m(d, n)
+#define transp8(d, n, m)	transp8_nx ## m(d, n)

ah, yes they do. Tricky!

But this macro exist to provide one single transp8(d, n, m) API. Perhaps it'll work as one big inline function too. I'll check if gcc is smart enough to optimize it ("m" is known at compile-time, too).

Quoted 26 lines
Quoted 26 lines
drivers/video/c2p.c +3 -3
     /*
@@ -130,12 +131,12 @@ static inline unsigned long comp(unsigne
      *  Store a full block of planar data after c2p conversion
      */
 
-static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
 {
     int i;
 
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = d[perm_c2p_8bpp[i]];
+	*(u32 *)dst = d[perm_c2p_32x8[i]];
 }
 
 
@@ -143,13 +144,13 @@ static inline void store_planar(char *ds
      *  Store a partial block of planar data after c2p conversion
      */
 
-static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
 				       u32 d[8], u32 mask)
 {
     int i;
 
Quoted 6 lines

drivers/video/c2p.c static inline void store_planar(char *ds · line 154

Quoted 4 lines
drivers/video/c2p.c +1 -1
     for (i = 0; i < bpp; i++, dst += dst_inc)
-	*(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
+	*(u32 *)dst = comp(d[perm_c2p_32x8[i]], *(u32 *)dst, mask);
 }

This driver needs a inlineectomy.

I actually want it to be inlined.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

#6 lore raw

PATCH 4/6 fbdev: c2p - Extract common c2p core to c2p_core.h

In reply to Geert Uytterhoeven
---
 drivers/video/c2p.c      |   87 ----------------------------------------
 drivers/video/c2p_core.h |  101 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 86 deletions(-)
drivers/video/c2p.c +1 -86
@@ -15,80 +15,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include "c2p.h"
-
-
-    /*
-     *  Basic transpose step
-     */
-
-#define _transp(d, i1, i2, shift, mask)			\
-    do {						\
-	u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;	\
-	d[i1] ^= t;					\
-	d[i2] ^= t << shift;				\
-    } while (0)
-
-static inline u32 get_mask(int n)
-{
-    switch (n) {
-	case 1:
-	    return 0x55555555;
-	    break;
-
-	case 2:
-	    return 0x33333333;
-	    break;
-
-	case 4:
-	    return 0x0f0f0f0f;
-	    break;
-
-	case 8:
-	    return 0x00ff00ff;
-	    break;
-
-	case 16:
-	    return 0x0000ffff;
-	    break;
-    }
-    return 0;
-}
-
-#define transp8_nx1(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	/* First block */				\
-	_transp(d, 0, 1, n, mask);			\
-	/* Second block */				\
-	_transp(d, 2, 3, n, mask);			\
-	/* Third block */				\
-	_transp(d, 4, 5, n, mask);			\
-	/* Fourth block */				\
-	_transp(d, 6, 7, n, mask);			\
-    } while (0)
-
-#define transp8_nx2(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	/* First block */				\
-	_transp(d, 0, 2, n, mask);			\
-	_transp(d, 1, 3, n, mask);			\
-	/* Second block */				\
-	_transp(d, 4, 6, n, mask);			\
-	_transp(d, 5, 7, n, mask);			\
-    } while (0)
-
-#define transp8_nx4(d, n)				\
-    do {						\
-	u32 mask = get_mask(n);				\
-	/* Single block */				\
-	_transp(d, 0, 4, n, mask);			\
-	_transp(d, 1, 5, n, mask);			\
-	_transp(d, 2, 6, n, mask);			\
-	_transp(d, 3, 7, n, mask);			\
-    } while (0)
-
-#define transp8(d, n, m)	transp8_nx ## m(d, n)
+#include "c2p_core.h"
 
 
     /*
@@ -116,18 +43,6 @@ static const int perm_c2p_32x8[8] = { 7,
 
 
     /*
-     *  Compose two values, using a bitmask as decision value
-     *  This is equivalent to (a & mask) | (b & ~mask)
-     */
-
-static inline unsigned long comp(unsigned long a, unsigned long b,
-				 unsigned long mask)
-{
-	return ((a ^ b) & mask) ^ b;
-}
-
-
-    /*
      *  Store a full block of planar data after c2p conversion
      */
 
drivers/video/c2p_core.h new file +101 -0

101 lines not on this page · raw message

Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#7 lore raw

PATCH 5/6 fbdev: c2p/atafb - Add support for Atari interleaved bitplanes

In reply to Geert Uytterhoeven

The c2p() for normal bitplanes is not suitable for interleaved bitplanes with 2 bytes of interleave, causing a garbled penguin logo. Add c2p_iplan2().

---
 drivers/video/Makefile     |    2 
 drivers/video/atafb.c      |   15 ----
 drivers/video/c2p.h        |    5 +
 drivers/video/c2p_core.h   |   39 +++++++++++
 drivers/video/c2p_iplan2.c |  153 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 200 insertions(+), 14 deletions(-)
drivers/video/Makefile +1 -1
@@ -72,7 +72,7 @@ obj-$(CONFIG_FB_TCX)              += tcx
 obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o
 obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o
 obj-$(CONFIG_FB_ACORN)            += acornfb.o
-obj-$(CONFIG_FB_ATARI)            += atafb.o c2p.o atafb_mfb.o \
+obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \
                                      atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
 obj-$(CONFIG_FB_MAC)              += macfb.o
 obj-$(CONFIG_FB_HECUBA)           += hecubafb.o
drivers/video/atafb.c +3 -12
@@ -122,7 +122,6 @@ static struct atafb_par {
 	void *screen_base;
 	int yres_virtual;
 	u_long next_line;
-	u_long next_plane;
 #if defined ATAFB_TT || defined ATAFB_STE
 	union {
 		struct {
@@ -1392,14 +1391,7 @@ set_screen_base:
 	par->screen_base = screen_base + var->yoffset * linelen;
 	par->hw.falcon.xoffset = 0;
 
-	// FIXME!!! sort of works, no crash
-	//par->next_line = linelen;
-	//par->next_plane = yres_virtual * linelen;
 	par->next_line = linelen;
-	par->next_plane = 2;
-	// crashes
-	//par->next_plane = linelen;
-	//par->next_line  = yres_virtual * linelen;
 
 	return 0;
 }
@@ -2662,10 +2654,9 @@ static void atafb_imageblit(struct fb_in
 			src += pitch;
 		}
 	} else {
-		// only used for logo; broken
-		c2p(info->screen_base, image->data, dx, dy, width, height,
-		    par->next_line, par->next_plane, image->width,
-		    info->var.bits_per_pixel);
+		c2p_iplan2(info->screen_base, image->data, dx, dy, width,
+			   height, par->next_line, image->width,
+			   info->var.bits_per_pixel);
 	}
 }
 
drivers/video/c2p.h +4 -1
@@ -1,7 +1,7 @@
 /*
  *  Fast C2P (Chunky-to-Planar) Conversion
  *
- *  Copyright (C) 2003 Geert Uytterhoeven
+ *  Copyright (C) 2003-2008 Geert Uytterhoeven
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive
@@ -14,3 +14,6 @@ extern void c2p(void *dst, const void *s
 	        u32 height, u32 dst_nextline, u32 dst_nextplane,
 		u32 src_nextline, u32 bpp);
 
+extern void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		       u32 height, u32 dst_nextline, u32 src_nextline,
+		       u32 bpp);
drivers/video/c2p_core.h +39 -0
@@ -90,6 +90,45 @@ static inline u32 get_mask(int n)
 
 
     /*
+     *  Transpose operations on 4 32-bit words
+     */
+
+#define transp4_nx1(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		/* First block */				\
+		_transp(d, 0, 1, n, mask);			\
+		/* Second block */				\
+		_transp(d, 2, 3, n, mask);			\
+	} while (0)
+
+#define transp4_nx2(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		/* Single block */				\
+		_transp(d, 0, 2, n, mask);			\
+		_transp(d, 1, 3, n, mask);			\
+	} while (0)
+
+#define transp4(d, n, m)	transp4_nx ## m(d, n)
+
+
+    /*
+     *  Transpose operations on 4 32-bit words (reverse order)
+     */
+
+#define transp4x_nx2(d, n)					\
+	do {							\
+		u32 mask = get_mask(n);				\
+		/* Single block */				\
+		_transp(d, 2, 0, n, mask);			\
+		_transp(d, 3, 1, n, mask);			\
+	} while (0)
+
+#define transp4x(d, n, m)	transp4x_nx ## m(d, n)
+
+
+    /*
      *  Compose two values, using a bitmask as decision value
      *  This is equivalent to (a & mask) | (b & ~mask)
      */
drivers/video/c2p_iplan2.c new file +153 -0

153 lines not on this page · raw message

Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#8 lore raw

PATCH 6/6 fbdev: c2p - Rename c2p to c2p_planar and correct indentation

In reply to Geert Uytterhoeven
---
 drivers/video/Makefile     |    2 
 drivers/video/amifb.c      |    6 -
 drivers/video/c2p.c        |  151 -------------------------------------------
 drivers/video/c2p.h        |    6 -
 drivers/video/c2p_planar.c |  156 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 163 insertions(+), 158 deletions(-)
drivers/video/Makefile +1 -1
@@ -28,7 +28,7 @@ obj-$(CONFIG_FB_DDC)           += fb_ddc
 obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
 
 # Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
+obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
drivers/video/amifb.c +3 -3
@@ -2159,9 +2159,9 @@ static void amifb_imageblit(struct fb_in
 			src += pitch;
 		}
 	} else {
-		c2p(info->screen_base, image->data, dx, dy, width, height,
-		    par->next_line, par->next_plane, image->width,
-		    info->var.bits_per_pixel);
+		c2p_planar(info->screen_base, image->data, dx, dy, width,
+			   height, par->next_line, par->next_plane,
+			   image->width, info->var.bits_per_pixel);
 	}
 }
 
drivers/video/c2p.c deleted +0 -151

151 lines not on this page · raw message

drivers/video/c2p.h +3 -3
@@ -10,9 +10,9 @@
 
 #include <linux/types.h>
 
-extern void c2p(void *dst, const void *src, u32 dx, u32 dy, u32 width,
-	        u32 height, u32 dst_nextline, u32 dst_nextplane,
-		u32 src_nextline, u32 bpp);
+extern void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+		       u32 height, u32 dst_nextline, u32 dst_nextplane,
+		       u32 src_nextline, u32 bpp);
 
 extern void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
 		       u32 height, u32 dst_nextline, u32 src_nextline,
drivers/video/c2p_planar.c new file +156 -0

156 lines not on this page · raw message

Signature · 10 lines
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
#9 lore raw

Re: [patch 6/6] fbdev: c2p - Rename c2p to c2p_planar and correct indentation

Quoted 15 lines · On Sun, 21 Dec 2008 16:01:05 +0100 Geert Uytterhoeven <[email protected]>…
drivers/video/c2p_planar.c new file +15 -0
+    /*
+     *  Store a full block of planar data after c2p conversion
+     */
+
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
+{
+	int i;
+
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = d[perm_c2p_32x8[i]];
+}
+
+
+    /*
+     *  Store a partial block of planar data after c2p conversion

drivers/video/c2p_planar.c line 70

Quoted 10 lines
drivers/video/c2p_planar.c new file +10 -0
+     */
+
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
+				       u32 d[8], u32 mask)
+{
+	int i;
+
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = comp(d[perm_c2p_32x8[i]], *(u32 *)dst, mask);
+}

Why not just make the first arg of these (too large to be inlined) functions have type u32*, then do away with the casts?

#10 lore raw

Re: [patch 6/6] fbdev: c2p - Rename c2p to c2p_planar and correct indentation

Quoted 23 lines · Andrew Morton
Quoted 20 lines · On Sun, 21 Dec 2008 16:01:05 +0100 Geert Uytterhoeven <[email protected]>…
drivers/video/c2p_planar.c new file +20 -0
+    /*
+     *  Store a full block of planar data after c2p conversion
+     */
+
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
+{
+	int i;
+
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = d[perm_c2p_32x8[i]];
+}
+
+
+    /*
+     *  Store a partial block of planar data after c2p conversion
+     */
+
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
+				       u32 d[8], u32 mask)
+{
Quoted 8 lines

drivers/video/c2p_planar.c line 70

Quoted 5 lines
drivers/video/c2p_planar.c new file +5 -0
+	int i;
+
+	for (i = 0; i < bpp; i++, dst += dst_inc)
+		*(u32 *)dst = comp(d[perm_c2p_32x8[i]], *(u32 *)dst, mask);
+}

Why not just make the first arg of these (too large to be inlined) functions have type u32*, then do away with the casts?

If I make dst u32 *, then "dst += dst_inc" needs even more ugly casting (dst_inc is not always a multiple of 4).

Anyway, as it may be an unaligned access, I'll switch to {get,put}_unaligned(), which has the side effect of hiding the casts.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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

#11 lore raw
In reply to Geert Uytterhoeven
Quoted 9 lines · On Sun, 21 Dec 2008 16:00:59 +0100 Geert Uytterhoeven <[email protected]>…

This patchsets contains several fixes for the Atari frame buffer device, and includes a refactoring of the c2p (Chunky-to-Planar) code:
[1] fbdev: atafb - Fix line length handling
[2] fbdev: atafb - Fix 16 bpp console
[3] fbdev: c2p - Cleanups
[4] fbdev: c2p - Extract common c2p core to c2p_core.h
[5] fbdev: c2p/atafb - Add support for Atari interleaved bitplanes
[6] fbdev: c2p - Rename c2p to c2p_planar and correct indentation

Quoted 3 lines

If nobody objects, I'd like to push this to Linus via the m68k tree, as the c2p code is used by m68k drivers (atafb and amifb) only.

OK by me.

CONFIG_ATAFB_FALCON looks like a serial ATA thing.