Merge branch 'topic/hda' into for-linus
[pandora-kernel.git] / drivers / video / cfbfillrect.c
index 64b3576..ba9f58b 100644 (file)
@@ -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;
                }
        }