diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-08-05 21:05:29 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-14 00:53:08 -0400 |
commit | a140e94d92f82db7406e116b63e78bd024907657 (patch) | |
tree | dc0f2fb4d74eb20e11b81500ae5b395a26f885ed | |
parent | 6993bea1b6ff49312f19339b3469db5887dfd633 (diff) |
[CG6]: accelerated copyarea
This patch adds accelerated copyarea and sets READS_FAST flag.
This doubles scrolling speed on SparcStation20 85MHz.
It also fixes a comment in cg6_fillrect function.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/video/cg6.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 137e475bbd92..549891d76ef5 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -37,6 +37,7 @@ static void cg6_fillrect(struct fb_info *, const struct fb_fillrect *); | |||
37 | static int cg6_sync(struct fb_info *); | 37 | static int cg6_sync(struct fb_info *); |
38 | static int cg6_mmap(struct fb_info *, struct vm_area_struct *); | 38 | static int cg6_mmap(struct fb_info *, struct vm_area_struct *); |
39 | static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long); | 39 | static int cg6_ioctl(struct fb_info *, unsigned int, unsigned long); |
40 | static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area); | ||
40 | 41 | ||
41 | /* | 42 | /* |
42 | * Frame buffer operations | 43 | * Frame buffer operations |
@@ -47,7 +48,7 @@ static struct fb_ops cg6_ops = { | |||
47 | .fb_setcolreg = cg6_setcolreg, | 48 | .fb_setcolreg = cg6_setcolreg, |
48 | .fb_blank = cg6_blank, | 49 | .fb_blank = cg6_blank, |
49 | .fb_fillrect = cg6_fillrect, | 50 | .fb_fillrect = cg6_fillrect, |
50 | .fb_copyarea = cfb_copyarea, | 51 | .fb_copyarea = cg6_copyarea, |
51 | .fb_imageblit = cg6_imageblit, | 52 | .fb_imageblit = cg6_imageblit, |
52 | .fb_sync = cg6_sync, | 53 | .fb_sync = cg6_sync, |
53 | .fb_mmap = cg6_mmap, | 54 | .fb_mmap = cg6_mmap, |
@@ -292,10 +293,12 @@ static void cg6_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
292 | unsigned long flags; | 293 | unsigned long flags; |
293 | s32 val; | 294 | s32 val; |
294 | 295 | ||
295 | /* XXX doesn't handle ROP_XOR */ | 296 | /* CG6 doesn't handle ROP_XOR */ |
296 | 297 | ||
297 | spin_lock_irqsave(&par->lock, flags); | 298 | spin_lock_irqsave(&par->lock, flags); |
299 | |||
298 | cg6_sync(info); | 300 | cg6_sync(info); |
301 | |||
299 | sbus_writel(rect->color, &fbc->fg); | 302 | sbus_writel(rect->color, &fbc->fg); |
300 | sbus_writel(~(u32)0, &fbc->pixelm); | 303 | sbus_writel(~(u32)0, &fbc->pixelm); |
301 | sbus_writel(0xea80ff00, &fbc->alu); | 304 | sbus_writel(0xea80ff00, &fbc->alu); |
@@ -313,6 +316,48 @@ static void cg6_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
313 | } | 316 | } |
314 | 317 | ||
315 | /** | 318 | /** |
319 | * cg6_copyarea - Copies one area of the screen to another area. | ||
320 | * | ||
321 | * @info: frame buffer structure that represents a single frame buffer | ||
322 | * @area: Structure providing the data to copy the framebuffer contents | ||
323 | * from one region to another. | ||
324 | * | ||
325 | * This drawing operation copies a rectangular area from one area of the | ||
326 | * screen to another area. | ||
327 | */ | ||
328 | static void cg6_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
329 | { | ||
330 | struct cg6_par *par = (struct cg6_par *)info->par; | ||
331 | struct cg6_fbc __iomem *fbc = par->fbc; | ||
332 | unsigned long flags; | ||
333 | int i; | ||
334 | |||
335 | spin_lock_irqsave(&par->lock, flags); | ||
336 | |||
337 | cg6_sync(info); | ||
338 | |||
339 | sbus_writel(0xff, &fbc->fg); | ||
340 | sbus_writel(0x00, &fbc->bg); | ||
341 | sbus_writel(~0, &fbc->pixelm); | ||
342 | sbus_writel(0xe880cccc, &fbc->alu); | ||
343 | sbus_writel(0, &fbc->s); | ||
344 | sbus_writel(0, &fbc->clip); | ||
345 | |||
346 | sbus_writel(area->sy, &fbc->y0); | ||
347 | sbus_writel(area->sx, &fbc->x0); | ||
348 | sbus_writel(area->sy + area->height - 1, &fbc->y1); | ||
349 | sbus_writel(area->sx + area->width - 1, &fbc->x1); | ||
350 | sbus_writel(area->dy, &fbc->y2); | ||
351 | sbus_writel(area->dx, &fbc->x2); | ||
352 | sbus_writel(area->dy + area->height - 1, &fbc->y3); | ||
353 | sbus_writel(area->dx + area->width - 1, &fbc->x3); | ||
354 | do { | ||
355 | i = sbus_readl(&fbc->blit); | ||
356 | } while (i < 0 && (i & 0x20000000)); | ||
357 | spin_unlock_irqrestore(&par->lock, flags); | ||
358 | } | ||
359 | |||
360 | /** | ||
316 | * cg6_imageblit - Copies a image from system memory to the screen. | 361 | * cg6_imageblit - Copies a image from system memory to the screen. |
317 | * | 362 | * |
318 | * @info: frame buffer structure that represents a single frame buffer | 363 | * @info: frame buffer structure that represents a single frame buffer |
@@ -708,7 +753,8 @@ static int __devinit cg6_probe(struct of_device *op, | |||
708 | sizeof(u32), "cgsix fhc"); | 753 | sizeof(u32), "cgsix fhc"); |
709 | 754 | ||
710 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | | 755 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | |
711 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; | 756 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | |
757 | FBINFO_READS_FAST; | ||
712 | info->fbops = &cg6_ops; | 758 | info->fbops = &cg6_ops; |
713 | 759 | ||
714 | info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, | 760 | info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, |