1*19757fc8STomi Valkeinen /* 2*19757fc8STomi Valkeinen * Generic fillrect for frame buffers with packed pixels of any depth. 3*19757fc8STomi Valkeinen * 4*19757fc8STomi Valkeinen * Copyright (C) 2000 James Simmons ([email protected]) 5*19757fc8STomi Valkeinen * 6*19757fc8STomi Valkeinen * This file is subject to the terms and conditions of the GNU General Public 7*19757fc8STomi Valkeinen * License. See the file COPYING in the main directory of this archive for 8*19757fc8STomi Valkeinen * more details. 9*19757fc8STomi Valkeinen * 10*19757fc8STomi Valkeinen * NOTES: 11*19757fc8STomi Valkeinen * 12*19757fc8STomi Valkeinen * Also need to add code to deal with cards endians that are different than 13*19757fc8STomi Valkeinen * the native cpu endians. I also need to deal with MSB position in the word. 14*19757fc8STomi Valkeinen * 15*19757fc8STomi Valkeinen */ 16*19757fc8STomi Valkeinen #include <linux/module.h> 17*19757fc8STomi Valkeinen #include <linux/string.h> 18*19757fc8STomi Valkeinen #include <linux/fb.h> 19*19757fc8STomi Valkeinen #include <asm/types.h> 20*19757fc8STomi Valkeinen #include "fb_draw.h" 21*19757fc8STomi Valkeinen 22*19757fc8STomi Valkeinen #if BITS_PER_LONG == 32 23*19757fc8STomi Valkeinen # define FB_WRITEL fb_writel 24*19757fc8STomi Valkeinen # define FB_READL fb_readl 25*19757fc8STomi Valkeinen #else 26*19757fc8STomi Valkeinen # define FB_WRITEL fb_writeq 27*19757fc8STomi Valkeinen # define FB_READL fb_readq 28*19757fc8STomi Valkeinen #endif 29*19757fc8STomi Valkeinen 30*19757fc8STomi Valkeinen /* 31*19757fc8STomi Valkeinen * Aligned pattern fill using 32/64-bit memory accesses 32*19757fc8STomi Valkeinen */ 33*19757fc8STomi Valkeinen 34*19757fc8STomi Valkeinen static void 35*19757fc8STomi Valkeinen bitfill_aligned(struct fb_info *p, unsigned long __iomem *dst, int dst_idx, 36*19757fc8STomi Valkeinen unsigned long pat, unsigned n, int bits, u32 bswapmask) 37*19757fc8STomi Valkeinen { 38*19757fc8STomi Valkeinen unsigned long first, last; 39*19757fc8STomi Valkeinen 40*19757fc8STomi Valkeinen if (!n) 41*19757fc8STomi Valkeinen return; 42*19757fc8STomi Valkeinen 43*19757fc8STomi Valkeinen first = fb_shifted_pixels_mask_long(p, dst_idx, bswapmask); 44*19757fc8STomi Valkeinen last = ~fb_shifted_pixels_mask_long(p, (dst_idx+n) % bits, bswapmask); 45*19757fc8STomi Valkeinen 46*19757fc8STomi Valkeinen if (dst_idx+n <= bits) { 47*19757fc8STomi Valkeinen // Single word 48*19757fc8STomi Valkeinen if (last) 49*19757fc8STomi Valkeinen first &= last; 50*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), first), dst); 51*19757fc8STomi Valkeinen } else { 52*19757fc8STomi Valkeinen // Multiple destination words 53*19757fc8STomi Valkeinen 54*19757fc8STomi Valkeinen // Leading bits 55*19757fc8STomi Valkeinen if (first!= ~0UL) { 56*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), first), dst); 57*19757fc8STomi Valkeinen dst++; 58*19757fc8STomi Valkeinen n -= bits - dst_idx; 59*19757fc8STomi Valkeinen } 60*19757fc8STomi Valkeinen 61*19757fc8STomi Valkeinen // Main chunk 62*19757fc8STomi Valkeinen n /= bits; 63*19757fc8STomi Valkeinen while (n >= 8) { 64*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 65*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 66*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 67*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 68*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 69*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 70*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 71*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 72*19757fc8STomi Valkeinen n -= 8; 73*19757fc8STomi Valkeinen } 74*19757fc8STomi Valkeinen while (n--) 75*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 76*19757fc8STomi Valkeinen 77*19757fc8STomi Valkeinen // Trailing bits 78*19757fc8STomi Valkeinen if (last) 79*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), last), dst); 80*19757fc8STomi Valkeinen } 81*19757fc8STomi Valkeinen } 82*19757fc8STomi Valkeinen 83*19757fc8STomi Valkeinen 84*19757fc8STomi Valkeinen /* 85*19757fc8STomi Valkeinen * Unaligned generic pattern fill using 32/64-bit memory accesses 86*19757fc8STomi Valkeinen * The pattern must have been expanded to a full 32/64-bit value 87*19757fc8STomi Valkeinen * Left/right are the appropriate shifts to convert to the pattern to be 88*19757fc8STomi Valkeinen * used for the next 32/64-bit word 89*19757fc8STomi Valkeinen */ 90*19757fc8STomi Valkeinen 91*19757fc8STomi Valkeinen static void 92*19757fc8STomi Valkeinen bitfill_unaligned(struct fb_info *p, unsigned long __iomem *dst, int dst_idx, 93*19757fc8STomi Valkeinen unsigned long pat, int left, int right, unsigned n, int bits) 94*19757fc8STomi Valkeinen { 95*19757fc8STomi Valkeinen unsigned long first, last; 96*19757fc8STomi Valkeinen 97*19757fc8STomi Valkeinen if (!n) 98*19757fc8STomi Valkeinen return; 99*19757fc8STomi Valkeinen 100*19757fc8STomi Valkeinen first = FB_SHIFT_HIGH(p, ~0UL, dst_idx); 101*19757fc8STomi Valkeinen last = ~(FB_SHIFT_HIGH(p, ~0UL, (dst_idx+n) % bits)); 102*19757fc8STomi Valkeinen 103*19757fc8STomi Valkeinen if (dst_idx+n <= bits) { 104*19757fc8STomi Valkeinen // Single word 105*19757fc8STomi Valkeinen if (last) 106*19757fc8STomi Valkeinen first &= last; 107*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), first), dst); 108*19757fc8STomi Valkeinen } else { 109*19757fc8STomi Valkeinen // Multiple destination words 110*19757fc8STomi Valkeinen // Leading bits 111*19757fc8STomi Valkeinen if (first) { 112*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), first), dst); 113*19757fc8STomi Valkeinen dst++; 114*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 115*19757fc8STomi Valkeinen n -= bits - dst_idx; 116*19757fc8STomi Valkeinen } 117*19757fc8STomi Valkeinen 118*19757fc8STomi Valkeinen // Main chunk 119*19757fc8STomi Valkeinen n /= bits; 120*19757fc8STomi Valkeinen while (n >= 4) { 121*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 122*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 123*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 124*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 125*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 126*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 127*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 128*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 129*19757fc8STomi Valkeinen n -= 4; 130*19757fc8STomi Valkeinen } 131*19757fc8STomi Valkeinen while (n--) { 132*19757fc8STomi Valkeinen FB_WRITEL(pat, dst++); 133*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 134*19757fc8STomi Valkeinen } 135*19757fc8STomi Valkeinen 136*19757fc8STomi Valkeinen // Trailing bits 137*19757fc8STomi Valkeinen if (last) 138*19757fc8STomi Valkeinen FB_WRITEL(comp(pat, FB_READL(dst), last), dst); 139*19757fc8STomi Valkeinen } 140*19757fc8STomi Valkeinen } 141*19757fc8STomi Valkeinen 142*19757fc8STomi Valkeinen /* 143*19757fc8STomi Valkeinen * Aligned pattern invert using 32/64-bit memory accesses 144*19757fc8STomi Valkeinen */ 145*19757fc8STomi Valkeinen static void 146*19757fc8STomi Valkeinen bitfill_aligned_rev(struct fb_info *p, unsigned long __iomem *dst, 147*19757fc8STomi Valkeinen int dst_idx, unsigned long pat, unsigned n, int bits, 148*19757fc8STomi Valkeinen u32 bswapmask) 149*19757fc8STomi Valkeinen { 150*19757fc8STomi Valkeinen unsigned long val = pat, dat; 151*19757fc8STomi Valkeinen unsigned long first, last; 152*19757fc8STomi Valkeinen 153*19757fc8STomi Valkeinen if (!n) 154*19757fc8STomi Valkeinen return; 155*19757fc8STomi Valkeinen 156*19757fc8STomi Valkeinen first = fb_shifted_pixels_mask_long(p, dst_idx, bswapmask); 157*19757fc8STomi Valkeinen last = ~fb_shifted_pixels_mask_long(p, (dst_idx+n) % bits, bswapmask); 158*19757fc8STomi Valkeinen 159*19757fc8STomi Valkeinen if (dst_idx+n <= bits) { 160*19757fc8STomi Valkeinen // Single word 161*19757fc8STomi Valkeinen if (last) 162*19757fc8STomi Valkeinen first &= last; 163*19757fc8STomi Valkeinen dat = FB_READL(dst); 164*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ val, dat, first), dst); 165*19757fc8STomi Valkeinen } else { 166*19757fc8STomi Valkeinen // Multiple destination words 167*19757fc8STomi Valkeinen // Leading bits 168*19757fc8STomi Valkeinen if (first!=0UL) { 169*19757fc8STomi Valkeinen dat = FB_READL(dst); 170*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ val, dat, first), dst); 171*19757fc8STomi Valkeinen dst++; 172*19757fc8STomi Valkeinen n -= bits - dst_idx; 173*19757fc8STomi Valkeinen } 174*19757fc8STomi Valkeinen 175*19757fc8STomi Valkeinen // Main chunk 176*19757fc8STomi Valkeinen n /= bits; 177*19757fc8STomi Valkeinen while (n >= 8) { 178*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 179*19757fc8STomi Valkeinen dst++; 180*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 181*19757fc8STomi Valkeinen dst++; 182*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 183*19757fc8STomi Valkeinen dst++; 184*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 185*19757fc8STomi Valkeinen dst++; 186*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 187*19757fc8STomi Valkeinen dst++; 188*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 189*19757fc8STomi Valkeinen dst++; 190*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 191*19757fc8STomi Valkeinen dst++; 192*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 193*19757fc8STomi Valkeinen dst++; 194*19757fc8STomi Valkeinen n -= 8; 195*19757fc8STomi Valkeinen } 196*19757fc8STomi Valkeinen while (n--) { 197*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ val, dst); 198*19757fc8STomi Valkeinen dst++; 199*19757fc8STomi Valkeinen } 200*19757fc8STomi Valkeinen // Trailing bits 201*19757fc8STomi Valkeinen if (last) { 202*19757fc8STomi Valkeinen dat = FB_READL(dst); 203*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ val, dat, last), dst); 204*19757fc8STomi Valkeinen } 205*19757fc8STomi Valkeinen } 206*19757fc8STomi Valkeinen } 207*19757fc8STomi Valkeinen 208*19757fc8STomi Valkeinen 209*19757fc8STomi Valkeinen /* 210*19757fc8STomi Valkeinen * Unaligned generic pattern invert using 32/64-bit memory accesses 211*19757fc8STomi Valkeinen * The pattern must have been expanded to a full 32/64-bit value 212*19757fc8STomi Valkeinen * Left/right are the appropriate shifts to convert to the pattern to be 213*19757fc8STomi Valkeinen * used for the next 32/64-bit word 214*19757fc8STomi Valkeinen */ 215*19757fc8STomi Valkeinen 216*19757fc8STomi Valkeinen static void 217*19757fc8STomi Valkeinen bitfill_unaligned_rev(struct fb_info *p, unsigned long __iomem *dst, 218*19757fc8STomi Valkeinen int dst_idx, unsigned long pat, int left, int right, 219*19757fc8STomi Valkeinen unsigned n, int bits) 220*19757fc8STomi Valkeinen { 221*19757fc8STomi Valkeinen unsigned long first, last, dat; 222*19757fc8STomi Valkeinen 223*19757fc8STomi Valkeinen if (!n) 224*19757fc8STomi Valkeinen return; 225*19757fc8STomi Valkeinen 226*19757fc8STomi Valkeinen first = FB_SHIFT_HIGH(p, ~0UL, dst_idx); 227*19757fc8STomi Valkeinen last = ~(FB_SHIFT_HIGH(p, ~0UL, (dst_idx+n) % bits)); 228*19757fc8STomi Valkeinen 229*19757fc8STomi Valkeinen if (dst_idx+n <= bits) { 230*19757fc8STomi Valkeinen // Single word 231*19757fc8STomi Valkeinen if (last) 232*19757fc8STomi Valkeinen first &= last; 233*19757fc8STomi Valkeinen dat = FB_READL(dst); 234*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ pat, dat, first), dst); 235*19757fc8STomi Valkeinen } else { 236*19757fc8STomi Valkeinen // Multiple destination words 237*19757fc8STomi Valkeinen 238*19757fc8STomi Valkeinen // Leading bits 239*19757fc8STomi Valkeinen if (first != 0UL) { 240*19757fc8STomi Valkeinen dat = FB_READL(dst); 241*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ pat, dat, first), dst); 242*19757fc8STomi Valkeinen dst++; 243*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 244*19757fc8STomi Valkeinen n -= bits - dst_idx; 245*19757fc8STomi Valkeinen } 246*19757fc8STomi Valkeinen 247*19757fc8STomi Valkeinen // Main chunk 248*19757fc8STomi Valkeinen n /= bits; 249*19757fc8STomi Valkeinen while (n >= 4) { 250*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ pat, dst); 251*19757fc8STomi Valkeinen dst++; 252*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 253*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ pat, dst); 254*19757fc8STomi Valkeinen dst++; 255*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 256*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ pat, dst); 257*19757fc8STomi Valkeinen dst++; 258*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 259*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ pat, dst); 260*19757fc8STomi Valkeinen dst++; 261*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 262*19757fc8STomi Valkeinen n -= 4; 263*19757fc8STomi Valkeinen } 264*19757fc8STomi Valkeinen while (n--) { 265*19757fc8STomi Valkeinen FB_WRITEL(FB_READL(dst) ^ pat, dst); 266*19757fc8STomi Valkeinen dst++; 267*19757fc8STomi Valkeinen pat = pat << left | pat >> right; 268*19757fc8STomi Valkeinen } 269*19757fc8STomi Valkeinen 270*19757fc8STomi Valkeinen // Trailing bits 271*19757fc8STomi Valkeinen if (last) { 272*19757fc8STomi Valkeinen dat = FB_READL(dst); 273*19757fc8STomi Valkeinen FB_WRITEL(comp(dat ^ pat, dat, last), dst); 274*19757fc8STomi Valkeinen } 275*19757fc8STomi Valkeinen } 276*19757fc8STomi Valkeinen } 277*19757fc8STomi Valkeinen 278*19757fc8STomi Valkeinen void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) 279*19757fc8STomi Valkeinen { 280*19757fc8STomi Valkeinen unsigned long pat, pat2, fg; 281*19757fc8STomi Valkeinen unsigned long width = rect->width, height = rect->height; 282*19757fc8STomi Valkeinen int bits = BITS_PER_LONG, bytes = bits >> 3; 283*19757fc8STomi Valkeinen u32 bpp = p->var.bits_per_pixel; 284*19757fc8STomi Valkeinen unsigned long __iomem *dst; 285*19757fc8STomi Valkeinen int dst_idx, left; 286*19757fc8STomi Valkeinen 287*19757fc8STomi Valkeinen if (p->state != FBINFO_STATE_RUNNING) 288*19757fc8STomi Valkeinen return; 289*19757fc8STomi Valkeinen 290*19757fc8STomi Valkeinen if (p->fix.visual == FB_VISUAL_TRUECOLOR || 291*19757fc8STomi Valkeinen p->fix.visual == FB_VISUAL_DIRECTCOLOR ) 292*19757fc8STomi Valkeinen fg = ((u32 *) (p->pseudo_palette))[rect->color]; 293*19757fc8STomi Valkeinen else 294*19757fc8STomi Valkeinen fg = rect->color; 295*19757fc8STomi Valkeinen 296*19757fc8STomi Valkeinen pat = pixel_to_pat(bpp, fg); 297*19757fc8STomi Valkeinen 298*19757fc8STomi Valkeinen dst = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1)); 299*19757fc8STomi Valkeinen dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8; 300*19757fc8STomi Valkeinen dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp; 301*19757fc8STomi Valkeinen /* FIXME For now we support 1-32 bpp only */ 302*19757fc8STomi Valkeinen left = bits % bpp; 303*19757fc8STomi Valkeinen if (p->fbops->fb_sync) 304*19757fc8STomi Valkeinen p->fbops->fb_sync(p); 305*19757fc8STomi Valkeinen if (!left) { 306*19757fc8STomi Valkeinen u32 bswapmask = fb_compute_bswapmask(p); 307*19757fc8STomi Valkeinen void (*fill_op32)(struct fb_info *p, 308*19757fc8STomi Valkeinen unsigned long __iomem *dst, int dst_idx, 309*19757fc8STomi Valkeinen unsigned long pat, unsigned n, int bits, 310*19757fc8STomi Valkeinen u32 bswapmask) = NULL; 311*19757fc8STomi Valkeinen 312*19757fc8STomi Valkeinen switch (rect->rop) { 313*19757fc8STomi Valkeinen case ROP_XOR: 314*19757fc8STomi Valkeinen fill_op32 = bitfill_aligned_rev; 315*19757fc8STomi Valkeinen break; 316*19757fc8STomi Valkeinen case ROP_COPY: 317*19757fc8STomi Valkeinen fill_op32 = bitfill_aligned; 318*19757fc8STomi Valkeinen break; 319*19757fc8STomi Valkeinen default: 320*19757fc8STomi Valkeinen printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n"); 321*19757fc8STomi Valkeinen fill_op32 = bitfill_aligned; 322*19757fc8STomi Valkeinen break; 323*19757fc8STomi Valkeinen } 324*19757fc8STomi Valkeinen while (height--) { 325*19757fc8STomi Valkeinen dst += dst_idx >> (ffs(bits) - 1); 326*19757fc8STomi Valkeinen dst_idx &= (bits - 1); 327*19757fc8STomi Valkeinen fill_op32(p, dst, dst_idx, pat, width*bpp, bits, 328*19757fc8STomi Valkeinen bswapmask); 329*19757fc8STomi Valkeinen dst_idx += p->fix.line_length*8; 330*19757fc8STomi Valkeinen } 331*19757fc8STomi Valkeinen } else { 332*19757fc8STomi Valkeinen int right, r; 333*19757fc8STomi Valkeinen void (*fill_op)(struct fb_info *p, unsigned long __iomem *dst, 334*19757fc8STomi Valkeinen int dst_idx, unsigned long pat, int left, 335*19757fc8STomi Valkeinen int right, unsigned n, int bits) = NULL; 336*19757fc8STomi Valkeinen #ifdef __LITTLE_ENDIAN 337*19757fc8STomi Valkeinen right = left; 338*19757fc8STomi Valkeinen left = bpp - right; 339*19757fc8STomi Valkeinen #else 340*19757fc8STomi Valkeinen right = bpp - left; 341*19757fc8STomi Valkeinen #endif 342*19757fc8STomi Valkeinen switch (rect->rop) { 343*19757fc8STomi Valkeinen case ROP_XOR: 344*19757fc8STomi Valkeinen fill_op = bitfill_unaligned_rev; 345*19757fc8STomi Valkeinen break; 346*19757fc8STomi Valkeinen case ROP_COPY: 347*19757fc8STomi Valkeinen fill_op = bitfill_unaligned; 348*19757fc8STomi Valkeinen break; 349*19757fc8STomi Valkeinen default: 350*19757fc8STomi Valkeinen printk(KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY\n"); 351*19757fc8STomi Valkeinen fill_op = bitfill_unaligned; 352*19757fc8STomi Valkeinen break; 353*19757fc8STomi Valkeinen } 354*19757fc8STomi Valkeinen while (height--) { 355*19757fc8STomi Valkeinen dst += dst_idx / bits; 356*19757fc8STomi Valkeinen dst_idx &= (bits - 1); 357*19757fc8STomi Valkeinen r = dst_idx % bpp; 358*19757fc8STomi Valkeinen /* rotate pattern to the correct start position */ 359*19757fc8STomi Valkeinen pat2 = le_long_to_cpu(rolx(cpu_to_le_long(pat), r, bpp)); 360*19757fc8STomi Valkeinen fill_op(p, dst, dst_idx, pat2, left, right, 361*19757fc8STomi Valkeinen width*bpp, bits); 362*19757fc8STomi Valkeinen dst_idx += p->fix.line_length*8; 363*19757fc8STomi Valkeinen } 364*19757fc8STomi Valkeinen } 365*19757fc8STomi Valkeinen } 366*19757fc8STomi Valkeinen 367*19757fc8STomi Valkeinen EXPORT_SYMBOL(cfb_fillrect); 368*19757fc8STomi Valkeinen 369*19757fc8STomi Valkeinen MODULE_AUTHOR("James Simmons <[email protected]>"); 370*19757fc8STomi Valkeinen MODULE_DESCRIPTION("Generic software accelerated fill rectangle"); 371*19757fc8STomi Valkeinen MODULE_LICENSE("GPL"); 372