24 #include <linux/module.h>
27 #include <linux/types.h>
28 #include <linux/errno.h>
30 #include <linux/mman.h>
34 #include <linux/slab.h>
40 #define PFX "s1d13xxxfb: "
41 #define BLIT "s1d13xxxfb_bitblt: "
47 #define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0)
49 #define dbg(fmt, args...) do { } while (0)
56 #define dbg_blit(fmt, args...) do { printk(KERN_INFO BLIT fmt, ## args); } while (0)
58 #define dbg_blit(fmt, args...) do { } while (0)
69 static const int s1d13xxxfb_prod_ids[] = {
78 static const char *s1d13xxxfb_prod_names[] = {
100 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
101 regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
109 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
110 regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
118 const unsigned int size)
122 for (i = 0; i <
size; i++) {
125 mdelay((
int)initregs[i].value);
127 s1d13xxxfb_writereg(par, initregs[i].
addr, initregs[i].value);
166 s1d13xxxfb_setup_pseudocolour(
struct fb_info *
info)
170 info->
var.red.length = 4;
171 info->
var.green.length = 4;
172 info->
var.blue.length = 4;
179 info->
var.bits_per_pixel = 16;
181 info->
var.red.length = 5;
182 info->
var.red.offset = 11;
184 info->
var.green.length = 6;
185 info->
var.green.offset = 5;
187 info->
var.blue.length = 5;
188 info->
var.blue.offset = 0;
211 dbg(
"s1d13xxxfb_set_par: bpp=%d\n", info->
var.bits_per_pixel);
220 switch (info->
var.bits_per_pixel) {
222 dbg(
"pseudo colour 4\n");
223 s1d13xxxfb_setup_pseudocolour(info);
227 dbg(
"pseudo colour 8\n");
228 s1d13xxxfb_setup_pseudocolour(info);
232 dbg(
"true colour\n");
233 s1d13xxxfb_setup_truecolour(info);
238 dbg(
"bpp not supported!\n");
242 dbg(
"writing %02x to display mode register\n", val);
249 info->
fix.line_length = info->
var.xres * info->
var.bits_per_pixel;
250 info->
fix.line_length /= 8;
252 dbg(
"setting line_length to %d\n", info->
fix.line_length);
275 unsigned int pseudo_val;
280 dbg(
"s1d13xxxfb_setcolreg: %d: rgb=%d,%d,%d, tr=%d\n",
281 regno, red, green, blue, transp);
283 if (info->
var.grayscale)
284 red = green = blue = (19595*red + 38470*green + 7471*
blue) >> 16;
286 switch (info->
fix.visual) {
293 pseudo_val = (red >> 11) << info->
var.red.offset;
294 pseudo_val |= (green >> 10) << info->
var.green.offset;
295 pseudo_val |= (blue >> 11) << info->
var.blue.offset;
297 dbg(
"s1d13xxxfb_setcolreg: pseudo %d, val %08x\n",
300 #if defined(CONFIG_PLAT_MAPPI)
318 dbg(
"s1d13xxxfb_setcolreg: done\n");
339 s1d13xxxfb_blank(
int blank_mode,
struct fb_info *info)
343 dbg(
"s1d13xxxfb_blank: blank=%d, info=%p\n", blank_mode, info);
345 switch (blank_mode) {
348 if ((par->
display & 0x01) != 0)
350 if ((par->
display & 0x02) != 0)
391 start = (info->
fix.line_length >> 1) * var->
yoffset;
422 bltbit_wait_bitclear(
struct fb_info *info,
u8 bit,
int timeout)
427 dbg_blit(
"wait_bitclear timeout\n");
450 u16 dx = area->
dx, dy = area->
dy;
454 spin_lock(&s1d13xxxfb_bitblt_lock);
457 bpp = (info->
var.bits_per_pixel >> 3);
458 stride = bpp * info->
var.xres;
461 if ((dy > sy) || ((dy == sy) && (dx >= sx))) {
462 dst = (((dy +
height - 1) * stride) + (bpp * (dx + width - 1)));
463 src = (((sy +
height - 1) * stride) + (bpp * (sx + width - 1)));
467 dst = (dy * stride) + (bpp * dx);
468 src = (sy * stride) + (bpp * sx);
490 dbg_blit(
"(copyarea) negative rop\n");
494 dbg_blit(
"(copyarea) positive rop\n");
507 dbg_blit(
"(copyarea) dx=%d, dy=%d\n", dx, dy);
508 dbg_blit(
"(copyarea) sx=%d, sy=%d\n", sx, sy);
509 dbg_blit(
"(copyarea) width=%d, height=%d\n", width - 1,
height - 1);
510 dbg_blit(
"(copyarea) stride=%d\n", stride);
511 dbg_blit(
"(copyarea) bpp=%d=0x0%d, mem_offset1=%d, mem_offset2=%d\n", bpp, (bpp >> 1),
512 (stride >> 1) & 0xff, stride >> 9);
520 bltbit_wait_bitclear(info, 0x80, 8000);
522 spin_unlock(&s1d13xxxfb_bitblt_lock);
539 u16 bpp = (info->
var.bits_per_pixel >> 3);
542 spin_lock(&s1d13xxxfb_bitblt_lock);
545 screen_stride = (bpp * info->
var.xres);
548 dest = ((rect->
dy * screen_stride) + (bpp * rect->
dx));
550 dbg_blit(
"(solidfill) dx=%d, dy=%d, stride=%d, dest=%d\n"
551 "(solidfill) : rect_width=%d, rect_height=%d\n",
552 rect->
dx, rect->
dy, screen_stride, dest,
555 dbg_blit(
"(solidfill) : xres=%d, yres=%d, bpp=%d\n",
556 info->
var.xres, info->
var.yres,
557 info->
var.bits_per_pixel);
576 dbg_blit(
"(solidfill) truecolor/directcolor\n");
577 dbg_blit(
"(solidfill) pseudo_palette[%d] = %d\n", rect->
color, fg);
604 bltbit_wait_bitclear(info, 0x80, 8000);
607 spin_unlock(&s1d13xxxfb_bitblt_lock);
611 static struct fb_ops s1d13xxxfb_fbops = {
613 .fb_set_par = s1d13xxxfb_set_par,
614 .fb_setcolreg = s1d13xxxfb_setcolreg,
615 .fb_blank = s1d13xxxfb_blank,
617 .fb_pan_display = s1d13xxxfb_pan_display,
646 s1d13xxxfb_fetch_hw_state(
struct fb_info *info)
654 u32 xres_virtual, yres_virtual;
656 int is_color, is_dual, is_tft;
657 int lcd_enabled, crt_enabled;
663 crt_enabled = (par->
display & 0x02) != 0;
664 lcd_enabled = (par->
display & 0x01) != 0;
666 if (lcd_enabled && crt_enabled)
674 bpp = display & 0x07;
680 var->
red.offset = var->
green.offset = var->
blue.offset = 0;
681 var->
red.length = var->
green.length = var->
blue.length = 8;
684 s1d13xxxfb_setup_truecolour(info);
687 dbg(
"bpp: %i\n", bpp);
693 is_color = (panel & 0x04) != 0;
694 is_dual = (panel & 0x02) != 0;
695 is_tft = (panel & 0x01) != 0;
696 lcd_bpp = s1d13xxxfb_width_tab[is_tft][(panel >> 4) & 3];
714 yres_virtual = fix->
smem_len / (offset * 2);
728 dbg(
PFX "bpp=%d, lcd_bpp=%d, "
729 "crt_enabled=%d, lcd_enabled=%d\n",
731 dbg(
PFX "xres=%d, yres=%d, vxres=%d, vyres=%d "
732 "is_color=%d, is_dual=%d, is_tft=%d\n",
733 xres, yres, xres_virtual, yres_virtual, is_color, is_dual, is_tft);
740 struct fb_info *info = platform_get_drvdata(pdev);
745 if (par && par->
regs) {
777 dbg(
"probe called: device is %p\n", pdev);
782 if (pdev->
dev.platform_data)
783 pdata = pdev->
dev.platform_data;
789 dev_err(&pdev->
dev,
"invalid num_resources: %i\n",
798 dev_err(&pdev->
dev,
"invalid resource type\n");
805 dev_dbg(&pdev->
dev,
"request_mem_region failed\n");
812 dev_dbg(&pdev->
dev,
"request_mem_region failed\n");
823 platform_set_drvdata(pdev, info);
824 default_par = info->
par;
827 if (!default_par->
regs) {
849 for (i = 0; i <
ARRAY_SIZE(s1d13xxxfb_prod_ids); i++) {
850 if (prod_id == s1d13xxxfb_prod_ids[i]) {
852 default_par->
prod_id = prod_id;
861 prod_id, s1d13xxxfb_prod_names[i]);
865 "unknown chip production id %i, revision %i\n",
871 info->
fix = s1d13xxxfb_fix;
882 info->
fbops = &s1d13xxxfb_fbops;
886 s1d13xxxfb_fbops.
fb_fillrect = s1d13xxxfb_bitblt_solidfill;
887 s1d13xxxfb_fbops.
fb_copyarea = s1d13xxxfb_bitblt_copyarea;
899 s1d13xxxfb_fetch_hw_state(info);
912 s1d13xxxfb_remove(pdev);
920 struct fb_info *info = platform_get_drvdata(dev);
925 lcd_enable(s1dfb, 0);
926 crt_enable(s1dfb, 0);
928 if (dev->
dev.platform_data)
929 pdata = dev->
dev.platform_data;
932 if (!s1dfb->disp_save)
935 if (!s1dfb->disp_save) {
942 s1dfb->disp_save =
NULL;
945 if (!s1dfb->regs_save)
948 if (!s1dfb->regs_save) {
959 if (pdata && pdata->platform_suspend_video)
960 return pdata->platform_suspend_video();
967 struct fb_info *info = platform_get_drvdata(dev);
978 if (dev->
dev.platform_data)
979 pdata = dev->
dev.platform_data;
981 if (s1dfb->regs_save) {
984 kfree(s1dfb->regs_save);
987 if (s1dfb->disp_save) {
990 kfree(s1dfb->disp_save);
993 if ((s1dfb->
display & 0x01) != 0)
994 lcd_enable(s1dfb, 1);
995 if ((s1dfb->
display & 0x02) != 0)
996 crt_enable(s1dfb, 1);
998 if (pdata && pdata->platform_resume_video)
999 return pdata->platform_resume_video();
1006 .probe = s1d13xxxfb_probe,
1007 .remove = s1d13xxxfb_remove,
1009 .suspend = s1d13xxxfb_suspend,
1010 .resume = s1d13xxxfb_resume,
1019 s1d13xxxfb_init(
void)
1032 s1d13xxxfb_exit(
void)