Commit ecac8e31 authored by David S. Miller's avatar David S. Miller

[FRAMEBUFFER]: Use u32 not long in cfbimgblt.

cfbimgblit.c did not support 64-bit platforms correctly.
In order to do so we would need to grow the cfb_tabX tables
to be absolutely enormous.

So the simplest fix is to use u32 throughout.
parent eaa535e7
...@@ -73,16 +73,11 @@ static u32 cfb_tab32[] = { ...@@ -73,16 +73,11 @@ static u32 cfb_tab32[] = {
0x00000000, 0xffffffff 0x00000000, 0xffffffff
}; };
#if BITS_PER_LONG == 32
#define FB_WRITEL fb_writel #define FB_WRITEL fb_writel
#define FB_READL fb_readl #define FB_READL fb_readl
#else
#define FB_WRITEL fb_writeq
#define FB_READL fb_readq
#endif
#if defined (__BIG_ENDIAN) #if defined (__BIG_ENDIAN)
#define LEFT_POS(bpp) (BITS_PER_LONG - bpp) #define LEFT_POS(bpp) (32 - bpp)
#define NEXT_POS(pos, bpp) ((pos) -= (bpp)) #define NEXT_POS(pos, bpp) ((pos) -= (bpp))
#define SHIFT_HIGH(val, bits) ((val) >> (bits)) #define SHIFT_HIGH(val, bits) ((val) >> (bits))
#define SHIFT_LOW(val, bits) ((val) << (bits)) #define SHIFT_LOW(val, bits) ((val) << (bits))
...@@ -94,26 +89,25 @@ static u32 cfb_tab32[] = { ...@@ -94,26 +89,25 @@ static u32 cfb_tab32[] = {
#endif #endif
static inline void color_imageblit(struct fb_image *image, struct fb_info *p, static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long start_index, u8 *dst1, u32 start_index,
unsigned long pitch_index) u32 pitch_index)
{ {
/* Draw the penguin */ /* Draw the penguin */
unsigned long *dst, *dst2, color = 0, val, shift; u32 *dst, *dst2, color = 0, val, shift;
int i, n, bpp = p->var.bits_per_pixel; int i, n, bpp = p->var.bits_per_pixel;
unsigned long null_bits = BITS_PER_LONG - bpp; u32 null_bits = 32 - bpp;
u32 *palette = (u32 *) p->pseudo_palette; u32 *palette = (u32 *) p->pseudo_palette;
u8 *src = image->data; u8 *src = image->data;
dst2 = (unsigned long *) dst1; dst2 = (u32 *) dst1;
for (i = image->height; i--; ) { for (i = image->height; i--; ) {
n = image->width; n = image->width;
dst = (unsigned long *) dst1; dst = (u32 *) dst1;
shift = 0; shift = 0;
val = 0; val = 0;
if (start_index) { if (start_index) {
unsigned long start_mask = ~(SHIFT_HIGH(~0UL, u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
start_index));
val = FB_READL(dst) & start_mask; val = FB_READL(dst) & start_mask;
shift = start_index; shift = start_index;
} }
...@@ -129,14 +123,14 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -129,14 +123,14 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
FB_WRITEL(val, dst++); FB_WRITEL(val, dst++);
val = (shift == null_bits) ? 0 : val = (shift == null_bits) ? 0 :
SHIFT_LOW(color,BITS_PER_LONG - shift); SHIFT_LOW(color, 32 - shift);
} }
shift += bpp; shift += bpp;
shift &= (BITS_PER_LONG - 1); shift &= (32 - 1);
src++; src++;
} }
if (shift) { if (shift) {
unsigned long end_mask = SHIFT_HIGH(~0UL, shift); u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
} }
...@@ -144,40 +138,39 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -144,40 +138,39 @@ static inline void color_imageblit(struct fb_image *image, struct fb_info *p,
if (pitch_index) { if (pitch_index) {
dst2 += p->fix.line_length; dst2 += p->fix.line_length;
dst1 = (char *) dst2; dst1 = (char *) dst2;
(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1); (unsigned long) dst1 &= ~(sizeof(u32) - 1);
start_index += pitch_index; start_index += pitch_index;
start_index &= BITS_PER_LONG - 1; start_index &= 32 - 1;
} }
} }
} }
static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long fgcolor, u8 *dst1, u32 fgcolor,
unsigned long bgcolor, u32 bgcolor,
unsigned long start_index, u32 start_index,
unsigned long pitch_index) u32 pitch_index)
{ {
unsigned long shift, color = 0, bpp = p->var.bits_per_pixel; u32 shift, color = 0, bpp = p->var.bits_per_pixel;
unsigned long *dst, *dst2, val, pitch = p->fix.line_length; u32 *dst, *dst2, val, pitch = p->fix.line_length;
unsigned long null_bits = BITS_PER_LONG - bpp; u32 null_bits = 32 - bpp;
unsigned long spitch = (image->width+7)/8; u32 spitch = (image->width+7)/8;
u8 *src = image->data, *s; u8 *src = image->data, *s;
unsigned long i, j, l; u32 i, j, l;
dst2 = (unsigned long *) dst1; dst2 = (u32 *) dst1;
for (i = image->height; i--; ) { for (i = image->height; i--; ) {
shift = val = 0; shift = val = 0;
l = 8; l = 8;
j = image->width; j = image->width;
dst = (unsigned long *) dst1; dst = (u32 *) dst1;
s = src; s = src;
/* write leading bits */ /* write leading bits */
if (start_index) { if (start_index) {
unsigned long start_mask = ~(SHIFT_HIGH(~0UL, u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
start_index));
val = FB_READL(dst) & start_mask; val = FB_READL(dst) & start_mask;
shift = start_index; shift = start_index;
} }
...@@ -192,16 +185,16 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -192,16 +185,16 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
if (shift >= null_bits) { if (shift >= null_bits) {
FB_WRITEL(val, dst++); FB_WRITEL(val, dst++);
val = (shift == null_bits) ? 0 : val = (shift == null_bits) ? 0 :
SHIFT_LOW(color,BITS_PER_LONG - shift); SHIFT_LOW(color,32 - shift);
} }
shift += bpp; shift += bpp;
shift &= (BITS_PER_LONG - 1); shift &= (32 - 1);
if (!l) { l = 8; s++; }; if (!l) { l = 8; s++; };
} }
/* write trailing bits */ /* write trailing bits */
if (shift) { if (shift) {
unsigned long end_mask = SHIFT_HIGH(~0UL, shift); u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
} }
...@@ -211,10 +204,10 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -211,10 +204,10 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
if (pitch_index) { if (pitch_index) {
dst2 += pitch; dst2 += pitch;
dst1 = (char *) dst2; dst1 = (char *) dst2;
(unsigned long) dst1 &= ~(sizeof(unsigned long) - 1); (unsigned long) dst1 &= ~(sizeof(u32) - 1);
start_index += pitch_index; start_index += pitch_index;
start_index &= BITS_PER_LONG - 1; start_index &= 32 - 1;
} }
} }
...@@ -229,14 +222,14 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -229,14 +222,14 @@ static inline void slow_imageblit(struct fb_image *image, struct fb_info *p,
* beginning and end of a scanline is dword aligned * beginning and end of a scanline is dword aligned
*/ */
static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
u8 *dst1, unsigned long fgcolor, u8 *dst1, u32 fgcolor,
unsigned long bgcolor) u32 bgcolor)
{ {
unsigned long fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
unsigned long ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8; u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
unsigned long bit_mask, end_mask, eorx, shift; u32 bit_mask, end_mask, eorx, shift;
char *s = image->data, *src; char *s = image->data, *src;
unsigned long *dst; u32 *dst;
u32 *tab = NULL; u32 *tab = NULL;
int i, j, k; int i, j, k;
...@@ -264,7 +257,7 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -264,7 +257,7 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
k = image->width/ppw; k = image->width/ppw;
for (i = image->height; i--; ) { for (i = image->height; i--; ) {
dst = (unsigned long *) dst1, shift = 8; src = s; dst = (u32 *) dst1, shift = 8; src = s;
for (j = k; j--; ) { for (j = k; j--; ) {
shift -= ppw; shift -= ppw;
...@@ -279,8 +272,8 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, ...@@ -279,8 +272,8 @@ static inline void fast_imageblit(struct fb_image *image, struct fb_info *p,
void cfb_imageblit(struct fb_info *p, struct fb_image *image) void cfb_imageblit(struct fb_info *p, struct fb_image *image)
{ {
unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel; u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
int x2, y2, vxres, vyres; int x2, y2, vxres, vyres;
u8 *dst1; u8 *dst1;
...@@ -304,7 +297,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image) ...@@ -304,7 +297,7 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
image->height = y2 - image->dy; image->height = y2 - image->dy;
bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp); bitstart = (image->dy * p->fix.line_length * 8) + (image->dx * bpp);
start_index = bitstart & (BITS_PER_LONG - 1); start_index = bitstart & (32 - 1);
pitch_index = (p->fix.line_length & (bpl - 1)) * 8; pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
bitstart /= 8; bitstart /= 8;
...@@ -324,8 +317,8 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image) ...@@ -324,8 +317,8 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
bgcolor = image->bg_color; bgcolor = image->bg_color;
} }
if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index && if (32 % bpp == 0 && !start_index && !pitch_index &&
((image->width & (BITS_PER_LONG/bpp-1)) == 0) && ((image->width & (32/bpp-1)) == 0) &&
bpp >= 8 && bpp <= 32) bpp >= 8 && bpp <= 32)
fast_imageblit(image, p, dst1, fgcolor, bgcolor); fast_imageblit(image, p, dst1, fgcolor, bgcolor);
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment