Lines Matching +full:blit +full:- +full:engine
4 * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
14 * TODO: - handle dual screen display (CRT and LCD at the same time).
15 * - check_var(), mode change, etc.
16 * - probably not SMP safe :)
17 * - support all bitblt operations on all cards
40 #define BLIT "s1d13xxxfb_bitblt: " macro
55 #define dbg_blit(fmt, args...) do { printk(KERN_INFO BLIT fmt, ## args); } while (0)
99 return readb(par->regs + regno); in s1d13xxxfb_readreg()
105 writeb(value, par->regs + regno); in s1d13xxxfb_writereg()
161 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; in s1d13xxxfb_setup_pseudocolour()
163 info->var.red.length = 4; in s1d13xxxfb_setup_pseudocolour()
164 info->var.green.length = 4; in s1d13xxxfb_setup_pseudocolour()
165 info->var.blue.length = 4; in s1d13xxxfb_setup_pseudocolour()
171 info->fix.visual = FB_VISUAL_TRUECOLOR; in s1d13xxxfb_setup_truecolour()
172 info->var.bits_per_pixel = 16; in s1d13xxxfb_setup_truecolour()
174 info->var.red.length = 5; in s1d13xxxfb_setup_truecolour()
175 info->var.red.offset = 11; in s1d13xxxfb_setup_truecolour()
177 info->var.green.length = 6; in s1d13xxxfb_setup_truecolour()
178 info->var.green.offset = 5; in s1d13xxxfb_setup_truecolour()
180 info->var.blue.length = 5; in s1d13xxxfb_setup_truecolour()
181 info->var.blue.offset = 0; in s1d13xxxfb_setup_truecolour()
185 * s1d13xxxfb_set_par - Alters the hardware state.
201 struct s1d13xxxfb_par *s1dfb = info->par; in s1d13xxxfb_set_par()
204 dbg("s1d13xxxfb_set_par: bpp=%d\n", info->var.bits_per_pixel); in s1d13xxxfb_set_par()
206 if ((s1dfb->display & 0x01)) /* LCD */ in s1d13xxxfb_set_par()
213 switch (info->var.bits_per_pixel) { in s1d13xxxfb_set_par()
232 return -EINVAL; in s1d13xxxfb_set_par()
237 if ((s1dfb->display & 0x01)) /* LCD */ in s1d13xxxfb_set_par()
242 info->fix.line_length = info->var.xres * info->var.bits_per_pixel; in s1d13xxxfb_set_par()
243 info->fix.line_length /= 8; in s1d13xxxfb_set_par()
245 dbg("setting line_length to %d\n", info->fix.line_length); in s1d13xxxfb_set_par()
253 * s1d13xxxfb_setcolreg - sets a color register.
267 struct s1d13xxxfb_par *s1dfb = info->par; in s1d13xxxfb_setcolreg()
271 return -EINVAL; in s1d13xxxfb_setcolreg()
276 if (info->var.grayscale) in s1d13xxxfb_setcolreg()
279 switch (info->fix.visual) { in s1d13xxxfb_setcolreg()
282 return -EINVAL; in s1d13xxxfb_setcolreg()
284 /* deal with creating pseudo-palette entries */ in s1d13xxxfb_setcolreg()
286 pseudo_val = (red >> 11) << info->var.red.offset; in s1d13xxxfb_setcolreg()
287 pseudo_val |= (green >> 10) << info->var.green.offset; in s1d13xxxfb_setcolreg()
288 pseudo_val |= (blue >> 11) << info->var.blue.offset; in s1d13xxxfb_setcolreg()
293 ((u32 *)info->pseudo_palette)[regno] = pseudo_val; in s1d13xxxfb_setcolreg()
304 return -ENOSYS; in s1d13xxxfb_setcolreg()
313 * s1d13xxxfb_blank - blanks the display.
318 * blanking succeeded, != 0 if un-/blanking failed due to e.g. a
330 struct s1d13xxxfb_par *par = info->par; in s1d13xxxfb_blank()
337 if ((par->display & 0x01) != 0) in s1d13xxxfb_blank()
339 if ((par->display & 0x02) != 0) in s1d13xxxfb_blank()
350 return -EINVAL; in s1d13xxxfb_blank()
358 * s1d13xxxfb_pan_display - Pans the display.
364 * If the values don't fit, return -EINVAL.
371 struct s1d13xxxfb_par *par = info->par; in s1d13xxxfb_pan_display()
374 if (var->xoffset != 0) /* not yet ... */ in s1d13xxxfb_pan_display()
375 return -EINVAL; in s1d13xxxfb_pan_display()
377 if (var->yoffset + info->var.yres > info->var.yres_virtual) in s1d13xxxfb_pan_display()
378 return -EINVAL; in s1d13xxxfb_pan_display()
380 start = (info->fix.line_length >> 1) * var->yoffset; in s1d13xxxfb_pan_display()
382 if ((par->display & 0x01)) { in s1d13xxxfb_pan_display()
402 * bltbit_wait_bitclear - waits for change in register value
413 while (s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit) { in bltbit_wait_bitclear()
415 if (!--timeout) { in bltbit_wait_bitclear()
425 * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function
438 u16 sx = area->sx, sy = area->sy; in s1d13xxxfb_bitblt_copyarea()
439 u16 dx = area->dx, dy = area->dy; in s1d13xxxfb_bitblt_copyarea()
440 u16 width = area->width, height = area->height; in s1d13xxxfb_bitblt_copyarea()
446 bpp = (info->var.bits_per_pixel >> 3); in s1d13xxxfb_bitblt_copyarea()
447 stride = bpp * info->var.xres; in s1d13xxxfb_bitblt_copyarea()
451 dst = (((dy + height - 1) * stride) + (bpp * (dx + width - 1))); in s1d13xxxfb_bitblt_copyarea()
452 src = (((sy + height - 1) * stride) + (bpp * (sx + width - 1))); in s1d13xxxfb_bitblt_copyarea()
461 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff)); in s1d13xxxfb_bitblt_copyarea()
462 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff); in s1d13xxxfb_bitblt_copyarea()
463 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff); in s1d13xxxfb_bitblt_copyarea()
466 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff)); in s1d13xxxfb_bitblt_copyarea()
467 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff); in s1d13xxxfb_bitblt_copyarea()
468 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff); in s1d13xxxfb_bitblt_copyarea()
471 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, (width & 0xff) - 1); in s1d13xxxfb_bitblt_copyarea()
472 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (width >> 8)); in s1d13xxxfb_bitblt_copyarea()
474 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, (height & 0xff) - 1); in s1d13xxxfb_bitblt_copyarea()
475 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (height >> 8)); in s1d13xxxfb_bitblt_copyarea()
480 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x03); in s1d13xxxfb_bitblt_copyarea()
482 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x02); in s1d13xxxfb_bitblt_copyarea()
487 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); in s1d13xxxfb_bitblt_copyarea()
490 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (bpp >> 1)); in s1d13xxxfb_bitblt_copyarea()
493 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (stride >> 1) & 0xff); in s1d13xxxfb_bitblt_copyarea()
494 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (stride >> 9)); in s1d13xxxfb_bitblt_copyarea()
498 dbg_blit("(copyarea) width=%d, height=%d\n", width - 1, height - 1); in s1d13xxxfb_bitblt_copyarea()
503 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CC_EXP, 0x0c); in s1d13xxxfb_bitblt_copyarea()
505 /* initialize the engine */ in s1d13xxxfb_bitblt_copyarea()
506 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); in s1d13xxxfb_bitblt_copyarea()
515 * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function
527 u16 bpp = (info->var.bits_per_pixel >> 3); in s1d13xxxfb_bitblt_solidfill()
533 screen_stride = (bpp * info->var.xres); in s1d13xxxfb_bitblt_solidfill()
536 dest = ((rect->dy * screen_stride) + (bpp * rect->dx)); in s1d13xxxfb_bitblt_solidfill()
540 rect->dx, rect->dy, screen_stride, dest, in s1d13xxxfb_bitblt_solidfill()
541 rect->width - 1, rect->height - 1); in s1d13xxxfb_bitblt_solidfill()
544 info->var.xres, info->var.yres, in s1d13xxxfb_bitblt_solidfill()
545 info->var.bits_per_pixel); in s1d13xxxfb_bitblt_solidfill()
546 dbg_blit("(solidfill) : rop=%d\n", rect->rop); in s1d13xxxfb_bitblt_solidfill()
549 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dest & 0x00ff)); in s1d13xxxfb_bitblt_solidfill()
550 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, ((dest >> 8) & 0x00ff)); in s1d13xxxfb_bitblt_solidfill()
551 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, ((dest >> 16) & 0x00ff)); in s1d13xxxfb_bitblt_solidfill()
554 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, ((rect->width) & 0x00ff) - 1); in s1d13xxxfb_bitblt_solidfill()
555 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (rect->width >> 8)); in s1d13xxxfb_bitblt_solidfill()
558 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, ((rect->height) & 0x00ff) - 1); in s1d13xxxfb_bitblt_solidfill()
559 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (rect->height >> 8)); in s1d13xxxfb_bitblt_solidfill()
561 if (info->fix.visual == FB_VISUAL_TRUECOLOR || in s1d13xxxfb_bitblt_solidfill()
562 info->fix.visual == FB_VISUAL_DIRECTCOLOR) { in s1d13xxxfb_bitblt_solidfill()
563 fg = ((u32 *)info->pseudo_palette)[rect->color]; in s1d13xxxfb_bitblt_solidfill()
565 dbg_blit("(solidfill) pseudo_palette[%d] = %d\n", rect->color, fg); in s1d13xxxfb_bitblt_solidfill()
567 fg = rect->color; in s1d13xxxfb_bitblt_solidfill()
568 dbg_blit("(solidfill) color = %d\n", rect->color); in s1d13xxxfb_bitblt_solidfill()
572 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC0, (fg & 0xff)); in s1d13xxxfb_bitblt_solidfill()
573 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC1, (fg >> 8) & 0xff); in s1d13xxxfb_bitblt_solidfill()
576 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0); in s1d13xxxfb_bitblt_solidfill()
579 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, BBLT_SOLID_FILL); in s1d13xxxfb_bitblt_solidfill()
582 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (info->var.bits_per_pixel >> 4)); in s1d13xxxfb_bitblt_solidfill()
585 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (screen_stride >> 1) & 0x00ff); in s1d13xxxfb_bitblt_solidfill()
586 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (screen_stride >> 9)); in s1d13xxxfb_bitblt_solidfill()
589 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80); in s1d13xxxfb_bitblt_solidfill()
622 {4, 8, 16, -1},
623 {9, 12, 18, -1},
627 * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to
643 struct fb_var_screeninfo *var = &info->var; in s1d13xxxfb_fetch_hw_state()
644 struct fb_fix_screeninfo *fix = &info->fix; in s1d13xxxfb_fetch_hw_state()
645 struct s1d13xxxfb_par *par = info->par; in s1d13xxxfb_fetch_hw_state()
654 fix->type = FB_TYPE_PACKED_PIXELS; in s1d13xxxfb_fetch_hw_state()
657 par->display = s1d13xxxfb_readreg(par, S1DREG_COM_DISP_MODE); in s1d13xxxfb_fetch_hw_state()
658 crt_enabled = (par->display & 0x02) != 0; in s1d13xxxfb_fetch_hw_state()
659 lcd_enabled = (par->display & 0x01) != 0; in s1d13xxxfb_fetch_hw_state()
674 var->bits_per_pixel = 8; in s1d13xxxfb_fetch_hw_state()
675 var->red.offset = var->green.offset = var->blue.offset = 0; in s1d13xxxfb_fetch_hw_state()
676 var->red.length = var->green.length = var->blue.length = 8; in s1d13xxxfb_fetch_hw_state()
684 fb_alloc_cmap(&info->cmap, 256, 0); in s1d13xxxfb_fetch_hw_state()
708 xres_virtual = offset * 16 / var->bits_per_pixel; in s1d13xxxfb_fetch_hw_state()
709 yres_virtual = fix->smem_len / (offset * 2); in s1d13xxxfb_fetch_hw_state()
711 var->xres = xres; in s1d13xxxfb_fetch_hw_state()
712 var->yres = yres; in s1d13xxxfb_fetch_hw_state()
713 var->xres_virtual = xres_virtual; in s1d13xxxfb_fetch_hw_state()
714 var->yres_virtual = yres_virtual; in s1d13xxxfb_fetch_hw_state()
715 var->xoffset = var->yoffset = 0; in s1d13xxxfb_fetch_hw_state()
717 fix->line_length = offset * 2; in s1d13xxxfb_fetch_hw_state()
719 var->grayscale = !is_color; in s1d13xxxfb_fetch_hw_state()
721 var->activate = FB_ACTIVATE_NOW; in s1d13xxxfb_fetch_hw_state()
725 var->bits_per_pixel, lcd_bpp, crt_enabled, lcd_enabled); in s1d13xxxfb_fetch_hw_state()
737 par = info->par; in __s1d13xxxfb_remove()
738 if (par && par->regs) { in __s1d13xxxfb_remove()
742 iounmap(par->regs); in __s1d13xxxfb_remove()
745 fb_dealloc_cmap(&info->cmap); in __s1d13xxxfb_remove()
747 if (info->screen_base) in __s1d13xxxfb_remove()
748 iounmap(info->screen_base); in __s1d13xxxfb_remove()
753 release_mem_region(pdev->resource[0].start, in __s1d13xxxfb_remove()
754 resource_size(&pdev->resource[0])); in __s1d13xxxfb_remove()
755 release_mem_region(pdev->resource[1].start, in __s1d13xxxfb_remove()
756 resource_size(&pdev->resource[1])); in __s1d13xxxfb_remove()
780 /* enable platform-dependent hardware glue, if any */ in s1d13xxxfb_probe()
781 if (dev_get_platdata(&pdev->dev)) in s1d13xxxfb_probe()
782 pdata = dev_get_platdata(&pdev->dev); in s1d13xxxfb_probe()
784 if (pdata && pdata->platform_init_video) in s1d13xxxfb_probe()
785 pdata->platform_init_video(); in s1d13xxxfb_probe()
787 if (pdev->num_resources != 2) { in s1d13xxxfb_probe()
788 dev_err(&pdev->dev, "invalid num_resources: %i\n", in s1d13xxxfb_probe()
789 pdev->num_resources); in s1d13xxxfb_probe()
790 ret = -ENODEV; in s1d13xxxfb_probe()
795 if (pdev->resource[0].flags != IORESOURCE_MEM in s1d13xxxfb_probe()
796 || pdev->resource[1].flags != IORESOURCE_MEM) { in s1d13xxxfb_probe()
797 dev_err(&pdev->dev, "invalid resource type\n"); in s1d13xxxfb_probe()
798 ret = -ENODEV; in s1d13xxxfb_probe()
802 if (!request_mem_region(pdev->resource[0].start, in s1d13xxxfb_probe()
803 resource_size(&pdev->resource[0]), "s1d13xxxfb mem")) { in s1d13xxxfb_probe()
804 dev_dbg(&pdev->dev, "request_mem_region failed\n"); in s1d13xxxfb_probe()
805 ret = -EBUSY; in s1d13xxxfb_probe()
809 if (!request_mem_region(pdev->resource[1].start, in s1d13xxxfb_probe()
810 resource_size(&pdev->resource[1]), "s1d13xxxfb regs")) { in s1d13xxxfb_probe()
811 dev_dbg(&pdev->dev, "request_mem_region failed\n"); in s1d13xxxfb_probe()
812 ret = -EBUSY; in s1d13xxxfb_probe()
816 info = framebuffer_alloc(sizeof(struct s1d13xxxfb_par) + sizeof(u32) * 256, &pdev->dev); in s1d13xxxfb_probe()
818 ret = -ENOMEM; in s1d13xxxfb_probe()
823 default_par = info->par; in s1d13xxxfb_probe()
824 default_par->regs = ioremap(pdev->resource[1].start, in s1d13xxxfb_probe()
825 resource_size(&pdev->resource[1])); in s1d13xxxfb_probe()
826 if (!default_par->regs) { in s1d13xxxfb_probe()
828 ret = -ENOMEM; in s1d13xxxfb_probe()
831 info->pseudo_palette = default_par->pseudo_palette; in s1d13xxxfb_probe()
833 info->screen_base = ioremap(pdev->resource[0].start, in s1d13xxxfb_probe()
834 resource_size(&pdev->resource[0])); in s1d13xxxfb_probe()
836 if (!info->screen_base) { in s1d13xxxfb_probe()
838 ret = -ENOMEM; in s1d13xxxfb_probe()
846 ret = -ENODEV; in s1d13xxxfb_probe()
851 default_par->prod_id = prod_id; in s1d13xxxfb_probe()
852 default_par->revision = revision; in s1d13xxxfb_probe()
870 info->fix = s1d13xxxfb_fix; in s1d13xxxfb_probe()
871 info->fix.mmio_start = pdev->resource[1].start; in s1d13xxxfb_probe()
872 info->fix.mmio_len = resource_size(&pdev->resource[1]); in s1d13xxxfb_probe()
873 info->fix.smem_start = pdev->resource[0].start; in s1d13xxxfb_probe()
874 info->fix.smem_len = resource_size(&pdev->resource[0]); in s1d13xxxfb_probe()
877 default_par->regs, info->fix.smem_len / 1024, info->screen_base); in s1d13xxxfb_probe()
879 info->par = default_par; in s1d13xxxfb_probe()
883 info->flags = FBINFO_HWACCEL_YPAN | in s1d13xxxfb_probe()
885 info->fbops = &s1d13xxxfb_fbops_s1d13506; in s1d13xxxfb_probe()
888 info->flags = FBINFO_HWACCEL_YPAN; in s1d13xxxfb_probe()
889 info->fbops = &s1d13xxxfb_fbops; in s1d13xxxfb_probe()
894 if (pdata && pdata->initregs) in s1d13xxxfb_probe()
895 s1d13xxxfb_runinit(info->par, pdata->initregs, pdata->initregssize); in s1d13xxxfb_probe()
900 ret = -EINVAL; in s1d13xxxfb_probe()
904 fb_info(info, "%s frame buffer device\n", info->fix.id); in s1d13xxxfb_probe()
918 struct s1d13xxxfb_par *s1dfb = info->par; in s1d13xxxfb_suspend()
925 if (dev_get_platdata(&dev->dev)) in s1d13xxxfb_suspend()
926 pdata = dev_get_platdata(&dev->dev); in s1d13xxxfb_suspend()
929 if (!s1dfb->disp_save) in s1d13xxxfb_suspend()
930 s1dfb->disp_save = kmalloc(info->fix.smem_len, GFP_KERNEL); in s1d13xxxfb_suspend()
932 if (!s1dfb->disp_save) { in s1d13xxxfb_suspend()
934 return -ENOMEM; in s1d13xxxfb_suspend()
937 memcpy_fromio(s1dfb->disp_save, info->screen_base, info->fix.smem_len); in s1d13xxxfb_suspend()
939 s1dfb->disp_save = NULL; in s1d13xxxfb_suspend()
942 if (!s1dfb->regs_save) in s1d13xxxfb_suspend()
943 s1dfb->regs_save = kmalloc(info->fix.mmio_len, GFP_KERNEL); in s1d13xxxfb_suspend()
945 if (!s1dfb->regs_save) { in s1d13xxxfb_suspend()
947 return -ENOMEM; in s1d13xxxfb_suspend()
951 memcpy_fromio(s1dfb->regs_save, s1dfb->regs, info->fix.mmio_len); in s1d13xxxfb_suspend()
956 if (pdata && pdata->platform_suspend_video) in s1d13xxxfb_suspend()
957 return pdata->platform_suspend_video(); in s1d13xxxfb_suspend()
965 struct s1d13xxxfb_par *s1dfb = info->par; in s1d13xxxfb_resume()
975 if (dev_get_platdata(&dev->dev)) in s1d13xxxfb_resume()
976 pdata = dev_get_platdata(&dev->dev); in s1d13xxxfb_resume()
978 if (s1dfb->regs_save) { in s1d13xxxfb_resume()
980 memcpy_toio(s1dfb->regs, s1dfb->regs_save, info->fix.mmio_len); in s1d13xxxfb_resume()
981 kfree(s1dfb->regs_save); in s1d13xxxfb_resume()
984 if (s1dfb->disp_save) { in s1d13xxxfb_resume()
985 memcpy_toio(info->screen_base, s1dfb->disp_save, in s1d13xxxfb_resume()
986 info->fix.smem_len); in s1d13xxxfb_resume()
987 kfree(s1dfb->disp_save); /* XXX kmalloc()'d when? */ in s1d13xxxfb_resume()
990 if ((s1dfb->display & 0x01) != 0) in s1d13xxxfb_resume()
992 if ((s1dfb->display & 0x02) != 0) in s1d13xxxfb_resume()
995 if (pdata && pdata->platform_resume_video) in s1d13xxxfb_resume()
996 return pdata->platform_resume_video(); in s1d13xxxfb_resume()
1021 return -ENODEV; in s1d13xxxfb_init()
1040 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, Thibaut VARENE <varenet@parisc-linux.org>");