diff options
Diffstat (limited to 'drivers/video/cfbfillrect.c')
| -rw-r--r-- | drivers/video/cfbfillrect.c | 36 | 
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index 64b35766b2a..ba9f58b2a5e 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c @@ -9,10 +9,6 @@   *   * NOTES:   * - *  The code for depths like 24 that don't have integer number of pixels per - *  long is broken and needs to be fixed. For now I turned these types of - *  mode off. - *   *  Also need to add code to deal with cards endians that are different than   *  the native cpu endians. I also need to deal with MSB position in the word.   * @@ -139,7 +135,7 @@ bitfill_unaligned(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  		// Trailing bits  		if (last) -			FB_WRITEL(comp(pat, FB_READL(dst), first), dst); +			FB_WRITEL(comp(pat, FB_READL(dst), last), dst);  	}  } @@ -281,7 +277,7 @@ bitfill_unaligned_rev(struct fb_info *p, unsigned long __iomem *dst,  void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)  { -	unsigned long pat, fg; +	unsigned long pat, pat2, fg;  	unsigned long width = rect->width, height = rect->height;  	int bits = BITS_PER_LONG, bytes = bits >> 3;  	u32 bpp = p->var.bits_per_pixel; @@ -297,7 +293,7 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)  	else  		fg = rect->color; -	pat = pixel_to_pat( bpp, fg); +	pat = pixel_to_pat(bpp, fg);  	dst = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));  	dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8; @@ -333,17 +329,16 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)  			dst_idx += p->fix.line_length*8;  		}  	} else { -		int right; -		int r; -		int rot = (left-dst_idx) % bpp; +		int right, r;  		void (*fill_op)(struct fb_info *p, unsigned long __iomem *dst,  				int dst_idx, unsigned long pat, int left,  				int right, unsigned n, int bits) = NULL; - -		/* rotate pattern to correct start position */ -		pat = pat << rot | pat >> (bpp-rot); - -		right = bpp-left; +#ifdef __LITTLE_ENDIAN +		right = left; +		left = bpp - right; +#else +		right = bpp - left; +#endif  		switch (rect->rop) {  		case ROP_XOR:  			fill_op = bitfill_unaligned_rev; @@ -352,17 +347,18 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)  			fill_op = bitfill_unaligned;  			break;  		default: -			printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n"); +			printk(KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n");  			fill_op = bitfill_unaligned;  			break;  		}  		while (height--) { -			dst += dst_idx >> (ffs(bits) - 1); +			dst += dst_idx / bits;  			dst_idx &= (bits - 1); -			fill_op(p, dst, dst_idx, pat, left, right, +			r = dst_idx % bpp; +			/* rotate pattern to the correct start position */ +			pat2 = le_long_to_cpu(rolx(cpu_to_le_long(pat), r, bpp)); +			fill_op(p, dst, dst_idx, pat2, left, right,  				width*bpp, bits); -			r = (p->fix.line_length*8) % bpp; -			pat = pat << (bpp-r) | pat >> r;  			dst_idx += p->fix.line_length*8;  		}  	}  |