aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/68328fb.c5
-rw-r--r--drivers/video/Kconfig61
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amba-clcd.c8
-rw-r--r--drivers/video/amifb.c7
-rw-r--r--drivers/video/arkfb.c4
-rw-r--r--drivers/video/asiliantfb.c26
-rw-r--r--drivers/video/aty/mach64_accel.c3
-rw-r--r--drivers/video/aty/mach64_cursor.c15
-rw-r--r--drivers/video/aty/radeon_pm.c3
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/lcd.c3
-rw-r--r--drivers/video/cirrusfb.c1529
-rw-r--r--drivers/video/console/fbcon.c73
-rw-r--r--drivers/video/cyblafb.c1683
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/fb_defio.c3
-rw-r--r--drivers/video/fbmem.c22
-rw-r--r--drivers/video/nvidia/nv_setup.c1
-rw-r--r--drivers/video/nvidia/nv_type.h2
-rw-r--r--drivers/video/nvidia/nvidia.c7
-rw-r--r--drivers/video/omap/hwa742.c4
-rw-r--r--drivers/video/omap/omapfb_main.c8
-rw-r--r--drivers/video/s1d13xxxfb.c48
-rw-r--r--drivers/video/s3c-fb.c1036
-rw-r--r--drivers/video/sgivwfb.c2
-rw-r--r--drivers/video/skeletonfb.c9
-rw-r--r--drivers/video/sm501fb.c5
-rw-r--r--drivers/video/sstfb.c10
-rw-r--r--drivers/video/stifb.c18
-rw-r--r--drivers/video/sunxvr500.c6
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/tgafb.c4
-rw-r--r--drivers/video/tridentfb.c19
-rw-r--r--drivers/video/uvesafb.c17
-rw-r--r--drivers/video/valkyriefb.c15
-rw-r--r--drivers/video/vesafb.c2
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/via/accel.c8
39 files changed, 1989 insertions, 2689 deletions
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 7f907fb23b8a..0b17824b0eb5 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -471,9 +471,11 @@ int __init mc68x328fb_init(void)
471 fb_info.pseudo_palette = &mc68x328fb_pseudo_palette; 471 fb_info.pseudo_palette = &mc68x328fb_pseudo_palette;
472 fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 472 fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
473 473
474 fb_alloc_cmap(&fb_info.cmap, 256, 0); 474 if (fb_alloc_cmap(&fb_info.cmap, 256, 0))
475 return -ENOMEM;
475 476
476 if (register_framebuffer(&fb_info) < 0) { 477 if (register_framebuffer(&fb_info) < 0) {
478 fb_dealloc_cmap(&fb_info.cmap);
477 return -EINVAL; 479 return -EINVAL;
478 } 480 }
479 481
@@ -494,6 +496,7 @@ module_init(mc68x328fb_init);
494static void __exit mc68x328fb_cleanup(void) 496static void __exit mc68x328fb_cleanup(void)
495{ 497{
496 unregister_framebuffer(&fb_info); 498 unregister_framebuffer(&fb_info);
499 fb_dealloc_cmap(&fb_info.cmap);
497} 500}
498 501
499module_exit(mc68x328fb_cleanup); 502module_exit(mc68x328fb_cleanup);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 41c27a44bd82..ffe2f2796e29 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1597,32 +1597,8 @@ config FB_VT8623
1597 Driver for CastleRock integrated graphics core in the 1597 Driver for CastleRock integrated graphics core in the
1598 VIA VT8623 [Apollo CLE266] chipset. 1598 VIA VT8623 [Apollo CLE266] chipset.
1599 1599
1600config FB_CYBLA
1601 tristate "Cyberblade/i1 support"
1602 depends on FB && PCI && X86_32 && !64BIT
1603 select FB_CFB_IMAGEBLIT
1604 ---help---
1605 This driver is supposed to support the Trident Cyberblade/i1
1606 graphics core integrated in the VIA VT8601A North Bridge,
1607 also known as VIA Apollo PLE133.
1608
1609 Status:
1610 - Developed, tested and working on EPIA 5000 and EPIA 800.
1611 - Does work reliable on all systems with CRT/LCD connected to
1612 normal VGA ports.
1613 - Should work on systems that do use the internal LCD port, but
1614 this is absolutely not tested.
1615
1616 Character imageblit, copyarea and rectangle fill are hw accelerated,
1617 ypan scrolling is used by default.
1618
1619 Please do read <file:Documentation/fb/cyblafb/*>.
1620
1621 To compile this driver as a module, choose M here: the
1622 module will be called cyblafb.
1623
1624config FB_TRIDENT 1600config FB_TRIDENT
1625 tristate "Trident support" 1601 tristate "Trident/CyberXXX/CyberBlade support"
1626 depends on FB && PCI 1602 depends on FB && PCI
1627 select FB_CFB_FILLRECT 1603 select FB_CFB_FILLRECT
1628 select FB_CFB_COPYAREA 1604 select FB_CFB_COPYAREA
@@ -1633,21 +1609,14 @@ config FB_TRIDENT
1633 and Blade XP. 1609 and Blade XP.
1634 There are also integrated versions of these chips called CyberXXXX, 1610 There are also integrated versions of these chips called CyberXXXX,
1635 CyberImage or CyberBlade. These chips are mostly found in laptops 1611 CyberImage or CyberBlade. These chips are mostly found in laptops
1636 but also on some motherboards. For more information, read 1612 but also on some motherboards including early VIA EPIA motherboards.
1637 <file:Documentation/fb/tridentfb.txt> 1613 For more information, read <file:Documentation/fb/tridentfb.txt>
1638 1614
1639 Say Y if you have such a graphics board. 1615 Say Y if you have such a graphics board.
1640 1616
1641 To compile this driver as a module, choose M here: the 1617 To compile this driver as a module, choose M here: the
1642 module will be called tridentfb. 1618 module will be called tridentfb.
1643 1619
1644config FB_TRIDENT_ACCEL
1645 bool "Trident Acceleration functions (EXPERIMENTAL)"
1646 depends on FB_TRIDENT && EXPERIMENTAL
1647 ---help---
1648 This will compile the Trident frame buffer device with
1649 acceleration functions.
1650
1651config FB_ARK 1620config FB_ARK
1652 tristate "ARK 2000PV support" 1621 tristate "ARK 2000PV support"
1653 depends on FB && PCI 1622 depends on FB && PCI
@@ -1920,6 +1889,30 @@ config FB_TMIO_ACCELL
1920 depends on FB_TMIO 1889 depends on FB_TMIO
1921 default y 1890 default y
1922 1891
1892config FB_S3C
1893 tristate "Samsung S3C framebuffer support"
1894 depends on FB && ARCH_S3C64XX
1895 select FB_CFB_FILLRECT
1896 select FB_CFB_COPYAREA
1897 select FB_CFB_IMAGEBLIT
1898 ---help---
1899 Frame buffer driver for the built-in FB controller in the Samsung
1900 SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
1901 and the S3C64XX series such as the S3C6400 and S3C6410.
1902
1903 These chips all have the same basic framebuffer design with the
1904 actual capabilities depending on the chip. For instance the S3C6400
1905 and S3C6410 support 4 hardware windows whereas the S3C24XX series
1906 currently only have two.
1907
1908 Currently the support is only for the S3C6400 and S3C6410 SoCs.
1909
1910config FB_S3C_DEBUG_REGWRITE
1911 bool "Debug register writes"
1912 depends on FB_S3C
1913 ---help---
1914 Show all register writes via printk(KERN_DEBUG)
1915
1923config FB_S3C2410 1916config FB_S3C2410
1924 tristate "S3C2410 LCD framebuffer support" 1917 tristate "S3C2410 LCD framebuffer support"
1925 depends on FB && ARCH_S3C2410 1918 depends on FB && ARCH_S3C2410
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index bb265eca7d57..0dbd6c68d76b 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
76 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o 76 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
77obj-$(CONFIG_FB_MAC) += macfb.o 77obj-$(CONFIG_FB_MAC) += macfb.o
78obj-$(CONFIG_FB_HECUBA) += hecubafb.o 78obj-$(CONFIG_FB_HECUBA) += hecubafb.o
79obj-$(CONFIG_FB_N411) += n411.o
79obj-$(CONFIG_FB_HGA) += hgafb.o 80obj-$(CONFIG_FB_HGA) += hgafb.o
80obj-$(CONFIG_FB_XVR500) += sunxvr500.o 81obj-$(CONFIG_FB_XVR500) += sunxvr500.o
81obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o 82obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
@@ -110,6 +111,7 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
110obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 111obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
111obj-$(CONFIG_FB_SH7760) += sh7760fb.o 112obj-$(CONFIG_FB_SH7760) += sh7760fb.o
112obj-$(CONFIG_FB_IMX) += imxfb.o 113obj-$(CONFIG_FB_IMX) += imxfb.o
114obj-$(CONFIG_FB_S3C) += s3c-fb.o
113obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o 115obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
114obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o 116obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
115obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o 117obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 4e046fed1380..61050ab14128 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -408,7 +408,9 @@ static int clcdfb_register(struct clcd_fb *fb)
408 /* 408 /*
409 * Allocate colourmap. 409 * Allocate colourmap.
410 */ 410 */
411 fb_alloc_cmap(&fb->fb.cmap, 256, 0); 411 ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0);
412 if (ret)
413 goto unmap;
412 414
413 /* 415 /*
414 * Ensure interrupts are disabled. 416 * Ensure interrupts are disabled.
@@ -426,6 +428,8 @@ static int clcdfb_register(struct clcd_fb *fb)
426 428
427 printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret); 429 printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
428 430
431 fb_dealloc_cmap(&fb->fb.cmap);
432 unmap:
429 iounmap(fb->regs); 433 iounmap(fb->regs);
430 free_clk: 434 free_clk:
431 clk_put(fb->clk); 435 clk_put(fb->clk);
@@ -485,6 +489,8 @@ static int clcdfb_remove(struct amba_device *dev)
485 489
486 clcdfb_disable(fb); 490 clcdfb_disable(fb);
487 unregister_framebuffer(&fb->fb); 491 unregister_framebuffer(&fb->fb);
492 if (fb->fb.cmap.len)
493 fb_dealloc_cmap(&fb->fb.cmap);
488 iounmap(fb->regs); 494 iounmap(fb->regs);
489 clk_put(fb->clk); 495 clk_put(fb->clk);
490 496
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 100f23661465..82bedd7f7789 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2437,7 +2437,9 @@ default_chipset:
2437 goto amifb_error; 2437 goto amifb_error;
2438 } 2438 }
2439 2439
2440 fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0); 2440 err = fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
2441 if (err)
2442 goto amifb_error;
2441 2443
2442 if (register_framebuffer(&fb_info) < 0) { 2444 if (register_framebuffer(&fb_info) < 0) {
2443 err = -EINVAL; 2445 err = -EINVAL;
@@ -2456,7 +2458,8 @@ amifb_error:
2456 2458
2457static void amifb_deinit(void) 2459static void amifb_deinit(void)
2458{ 2460{
2459 fb_dealloc_cmap(&fb_info.cmap); 2461 if (fb_info.cmap.len)
2462 fb_dealloc_cmap(&fb_info.cmap);
2460 chipfree(); 2463 chipfree();
2461 if (videomemory) 2464 if (videomemory)
2462 iounmap((void*)videomemory); 2465 iounmap((void*)videomemory);
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 314d18694b6a..d583bea608fd 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -470,7 +470,7 @@ static void ark_dac_read_regs(void *data, u8 *code, int count)
470 470
471 while (count != 0) 471 while (count != 0)
472 { 472 {
473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0); 473 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]); 474 code[1] = vga_r(NULL, dac_regs[code[0] & 3]);
475 count--; 475 count--;
476 code += 2; 476 code += 2;
@@ -485,7 +485,7 @@ static void ark_dac_write_regs(void *data, u8 *code, int count)
485 485
486 while (count != 0) 486 while (count != 0)
487 { 487 {
488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0); 488 vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
489 vga_w(NULL, dac_regs[code[0] & 3], code[1]); 489 vga_w(NULL, dac_regs[code[0] & 3], code[1]);
490 count--; 490 count--;
491 code += 2; 491 code += 2;
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 1fd22f460b0f..1a1f946d8fef 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -505,19 +505,27 @@ static struct fb_var_screeninfo asiliantfb_var __devinitdata = {
505 .vsync_len = 2, 505 .vsync_len = 2,
506}; 506};
507 507
508static void __devinit init_asiliant(struct fb_info *p, unsigned long addr) 508static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
509{ 509{
510 int err;
511
510 p->fix = asiliantfb_fix; 512 p->fix = asiliantfb_fix;
511 p->fix.smem_start = addr; 513 p->fix.smem_start = addr;
512 p->var = asiliantfb_var; 514 p->var = asiliantfb_var;
513 p->fbops = &asiliantfb_ops; 515 p->fbops = &asiliantfb_ops;
514 p->flags = FBINFO_DEFAULT; 516 p->flags = FBINFO_DEFAULT;
515 517
516 fb_alloc_cmap(&p->cmap, 256, 0); 518 err = fb_alloc_cmap(&p->cmap, 256, 0);
519 if (err) {
520 printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n");
521 return err;
522 }
517 523
518 if (register_framebuffer(p) < 0) { 524 err = register_framebuffer(p);
525 if (err < 0) {
519 printk(KERN_ERR "C&T 69000 framebuffer failed to register\n"); 526 printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
520 return; 527 fb_dealloc_cmap(&p->cmap);
528 return err;
521 } 529 }
522 530
523 printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n", 531 printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
@@ -532,6 +540,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
532{ 540{
533 unsigned long addr, size; 541 unsigned long addr, size;
534 struct fb_info *p; 542 struct fb_info *p;
543 int err;
535 544
536 if ((dp->resource[0].flags & IORESOURCE_MEM) == 0) 545 if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
537 return -ENODEV; 546 return -ENODEV;
@@ -560,7 +569,13 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
560 pci_write_config_dword(dp, 4, 0x02800083); 569 pci_write_config_dword(dp, 4, 0x02800083);
561 writeb(3, p->screen_base + 0x400784); 570 writeb(3, p->screen_base + 0x400784);
562 571
563 init_asiliant(p, addr); 572 err = init_asiliant(p, addr);
573 if (err) {
574 iounmap(p->screen_base);
575 release_mem_region(addr, size);
576 framebuffer_release(p);
577 return err;
578 }
564 579
565 pci_set_drvdata(dp, p); 580 pci_set_drvdata(dp, p);
566 return 0; 581 return 0;
@@ -571,6 +586,7 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp)
571 struct fb_info *p = pci_get_drvdata(dp); 586 struct fb_info *p = pci_get_drvdata(dp);
572 587
573 unregister_framebuffer(p); 588 unregister_framebuffer(p);
589 fb_dealloc_cmap(&p->cmap);
574 iounmap(p->screen_base); 590 iounmap(p->screen_base);
575 release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0)); 591 release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
576 pci_set_drvdata(dp, NULL); 592 pci_set_drvdata(dp, NULL);
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index a8f60c33863c..0cc9724e61a2 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -39,7 +39,8 @@ void aty_reset_engine(const struct atyfb_par *par)
39{ 39{
40 /* reset engine */ 40 /* reset engine */
41 aty_st_le32(GEN_TEST_CNTL, 41 aty_st_le32(GEN_TEST_CNTL,
42 aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par); 42 aty_ld_le32(GEN_TEST_CNTL, par) &
43 ~(GUI_ENGINE_ENABLE | HWCURSOR_ENABLE), par);
43 /* enable engine */ 44 /* enable engine */
44 aty_st_le32(GEN_TEST_CNTL, 45 aty_st_le32(GEN_TEST_CNTL,
45 aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par); 46 aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par);
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index faf95da8fcbc..04c710804bb0 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -77,9 +77,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
77 if (par->asleep) 77 if (par->asleep)
78 return -EPERM; 78 return -EPERM;
79 79
80 /* Hide cursor */
81 wait_for_fifo(1, par); 80 wait_for_fifo(1, par);
82 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par); 81 if (cursor->enable)
82 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
83 | HWCURSOR_ENABLE, par);
84 else
85 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
86 & ~HWCURSOR_ENABLE, par);
83 87
84 /* set position */ 88 /* set position */
85 if (cursor->set & FB_CUR_SETPOS) { 89 if (cursor->set & FB_CUR_SETPOS) {
@@ -109,7 +113,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
109 y<<=1; 113 y<<=1;
110 h<<=1; 114 h<<=1;
111 } 115 }
112 wait_for_fifo(4, par); 116 wait_for_fifo(3, par);
113 aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par); 117 aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
114 aty_st_le32(CUR_HORZ_VERT_OFF, 118 aty_st_le32(CUR_HORZ_VERT_OFF,
115 ((u32) (64 - h + yoff) << 16) | xoff, par); 119 ((u32) (64 - h + yoff) << 16) | xoff, par);
@@ -177,11 +181,6 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
177 } 181 }
178 } 182 }
179 183
180 if (cursor->enable) {
181 wait_for_fifo(1, par);
182 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
183 | HWCURSOR_ENABLE, par);
184 }
185 return 0; 184 return 0;
186} 185}
187 186
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 1de0c0032468..97a1f095f327 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -89,6 +89,9 @@ static struct radeon_device_id radeon_workaround_list[] = {
89 BUGFIX("Acer Aspire 2010", 89 BUGFIX("Acer Aspire 2010",
90 PCI_VENDOR_ID_AI, 0x0061, 90 PCI_VENDOR_ID_AI, 0x0061,
91 radeon_pm_off, radeon_reinitialize_M10), 91 radeon_pm_off, radeon_reinitialize_M10),
92 BUGFIX("Acer Travelmate 290D/292LMi",
93 PCI_VENDOR_ID_AI, 0x005a,
94 radeon_pm_off, radeon_reinitialize_M10),
92 { .ident = NULL } 95 { .ident = NULL }
93}; 96};
94 97
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c79ca3..dd37cbcaf8ce 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,6 +35,8 @@ static int fb_notifier_callback(struct notifier_block *self,
35 return 0; 35 return 0;
36 36
37 bd = container_of(self, struct backlight_device, fb_notif); 37 bd = container_of(self, struct backlight_device, fb_notif);
38 if (!lock_fb_info(evdata->info))
39 return -ENODEV;
38 mutex_lock(&bd->ops_lock); 40 mutex_lock(&bd->ops_lock);
39 if (bd->ops) 41 if (bd->ops)
40 if (!bd->ops->check_fb || 42 if (!bd->ops->check_fb ||
@@ -47,6 +49,7 @@ static int fb_notifier_callback(struct notifier_block *self,
47 backlight_update_status(bd); 49 backlight_update_status(bd);
48 } 50 }
49 mutex_unlock(&bd->ops_lock); 51 mutex_unlock(&bd->ops_lock);
52 unlock_fb_info(evdata->info);
50 return 0; 53 return 0;
51} 54}
52 55
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106c..0bb13df0fa89 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,6 +40,8 @@ static int fb_notifier_callback(struct notifier_block *self,
40 if (!ld->ops) 40 if (!ld->ops)
41 return 0; 41 return 0;
42 42
43 if (!lock_fb_info(evdata->info))
44 return -ENODEV;
43 mutex_lock(&ld->ops_lock); 45 mutex_lock(&ld->ops_lock);
44 if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { 46 if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
45 if (event == FB_EVENT_BLANK) { 47 if (event == FB_EVENT_BLANK) {
@@ -51,6 +53,7 @@ static int fb_notifier_callback(struct notifier_block *self,
51 } 53 }
52 } 54 }
53 mutex_unlock(&ld->ops_lock); 55 mutex_unlock(&ld->ops_lock);
56 unlock_fb_info(evdata->info);
54 return 0; 57 return 0;
55} 58}
56 59
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index a2aa6ddffbe2..d42e385f091c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -34,8 +34,6 @@
34 * 34 *
35 */ 35 */
36 36
37#define CIRRUSFB_VERSION "2.0-pre2"
38
39#include <linux/module.h> 37#include <linux/module.h>
40#include <linux/kernel.h> 38#include <linux/kernel.h>
41#include <linux/errno.h> 39#include <linux/errno.h>
@@ -72,20 +70,9 @@
72 * 70 *
73 */ 71 */
74 72
75/* enable debug output? */
76/* #define CIRRUSFB_DEBUG 1 */
77
78/* disable runtime assertions? */ 73/* disable runtime assertions? */
79/* #define CIRRUSFB_NDEBUG */ 74/* #define CIRRUSFB_NDEBUG */
80 75
81/* debug output */
82#ifdef CIRRUSFB_DEBUG
83#define DPRINTK(fmt, args...) \
84 printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
85#else
86#define DPRINTK(fmt, args...)
87#endif
88
89/* debugging assertions */ 76/* debugging assertions */
90#ifndef CIRRUSFB_NDEBUG 77#ifndef CIRRUSFB_NDEBUG
91#define assert(expr) \ 78#define assert(expr) \
@@ -108,14 +95,15 @@
108/* board types */ 95/* board types */
109enum cirrus_board { 96enum cirrus_board {
110 BT_NONE = 0, 97 BT_NONE = 0,
111 BT_SD64, 98 BT_SD64, /* GD5434 */
112 BT_PICCOLO, 99 BT_PICCOLO, /* GD5426 */
113 BT_PICASSO, 100 BT_PICASSO, /* GD5426 or GD5428 */
114 BT_SPECTRUM, 101 BT_SPECTRUM, /* GD5426 or GD5428 */
115 BT_PICASSO4, /* GD5446 */ 102 BT_PICASSO4, /* GD5446 */
116 BT_ALPINE, /* GD543x/4x */ 103 BT_ALPINE, /* GD543x/4x */
117 BT_GD5480, 104 BT_GD5480,
118 BT_LAGUNA, /* GD546x */ 105 BT_LAGUNA, /* GD5462/64 */
106 BT_LAGUNAB, /* GD5465 */
119}; 107};
120 108
121/* 109/*
@@ -150,15 +138,17 @@ static const struct cirrusfb_board_info_rec {
150 .maxclock = { 138 .maxclock = {
151 /* guess */ 139 /* guess */
152 /* the SD64/P4 have a higher max. videoclock */ 140 /* the SD64/P4 have a higher max. videoclock */
153 140000, 140000, 140000, 140000, 140000, 141 135100, 135100, 85500, 85500, 0
154 }, 142 },
155 .init_sr07 = true, 143 .init_sr07 = true,
156 .init_sr1f = true, 144 .init_sr1f = true,
157 .scrn_start_bit19 = true, 145 .scrn_start_bit19 = true,
158 .sr07 = 0xF0, 146 .sr07 = 0xF0,
159 .sr07_1bpp = 0xF0, 147 .sr07_1bpp = 0xF0,
148 .sr07_1bpp_mux = 0xF6,
160 .sr07_8bpp = 0xF1, 149 .sr07_8bpp = 0xF1,
161 .sr1f = 0x20 150 .sr07_8bpp_mux = 0xF7,
151 .sr1f = 0x1E
162 }, 152 },
163 [BT_PICCOLO] = { 153 [BT_PICCOLO] = {
164 .name = "CL Piccolo", 154 .name = "CL Piccolo",
@@ -210,9 +200,11 @@ static const struct cirrusfb_board_info_rec {
210 .init_sr07 = true, 200 .init_sr07 = true,
211 .init_sr1f = false, 201 .init_sr1f = false,
212 .scrn_start_bit19 = true, 202 .scrn_start_bit19 = true,
213 .sr07 = 0x20, 203 .sr07 = 0xA0,
214 .sr07_1bpp = 0x20, 204 .sr07_1bpp = 0xA0,
215 .sr07_8bpp = 0x21, 205 .sr07_1bpp_mux = 0xA6,
206 .sr07_8bpp = 0xA1,
207 .sr07_8bpp_mux = 0xA7,
216 .sr1f = 0 208 .sr1f = 0
217 }, 209 },
218 [BT_ALPINE] = { 210 [BT_ALPINE] = {
@@ -225,8 +217,8 @@ static const struct cirrusfb_board_info_rec {
225 .init_sr1f = true, 217 .init_sr1f = true,
226 .scrn_start_bit19 = true, 218 .scrn_start_bit19 = true,
227 .sr07 = 0xA0, 219 .sr07 = 0xA0,
228 .sr07_1bpp = 0xA1, 220 .sr07_1bpp = 0xA0,
229 .sr07_1bpp_mux = 0xA7, 221 .sr07_1bpp_mux = 0xA6,
230 .sr07_8bpp = 0xA1, 222 .sr07_8bpp = 0xA1,
231 .sr07_8bpp_mux = 0xA7, 223 .sr07_8bpp_mux = 0xA7,
232 .sr1f = 0x1C 224 .sr1f = 0x1C
@@ -247,8 +239,18 @@ static const struct cirrusfb_board_info_rec {
247 [BT_LAGUNA] = { 239 [BT_LAGUNA] = {
248 .name = "CL Laguna", 240 .name = "CL Laguna",
249 .maxclock = { 241 .maxclock = {
250 /* guess */ 242 /* taken from X11 code */
251 135100, 135100, 135100, 135100, 135100, 243 170000, 170000, 170000, 170000, 135100,
244 },
245 .init_sr07 = false,
246 .init_sr1f = false,
247 .scrn_start_bit19 = true,
248 },
249 [BT_LAGUNAB] = {
250 .name = "CL Laguna AGP",
251 .maxclock = {
252 /* taken from X11 code */
253 170000, 250000, 170000, 170000, 135100,
252 }, 254 },
253 .init_sr07 = false, 255 .init_sr07 = false,
254 .init_sr1f = false, 256 .init_sr1f = false,
@@ -262,8 +264,8 @@ static const struct cirrusfb_board_info_rec {
262 264
263static struct pci_device_id cirrusfb_pci_table[] = { 265static struct pci_device_id cirrusfb_pci_table[] = {
264 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE), 266 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
265 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE), 267 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE), 268 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
267 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */ 269 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
268 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE), 270 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
269 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE), 271 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
@@ -271,7 +273,7 @@ static struct pci_device_id cirrusfb_pci_table[] = {
271 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */ 273 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
272 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */ 274 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
273 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */ 275 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
274 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/ 276 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
275 { 0, } 277 { 0, }
276}; 278};
277MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); 279MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -326,10 +328,6 @@ static const struct {
326}; 328};
327#endif /* CONFIG_ZORRO */ 329#endif /* CONFIG_ZORRO */
328 330
329struct cirrusfb_regs {
330 int multiplexing;
331};
332
333#ifdef CIRRUSFB_DEBUG 331#ifdef CIRRUSFB_DEBUG
334enum cirrusfb_dbg_reg_class { 332enum cirrusfb_dbg_reg_class {
335 CRT, 333 CRT,
@@ -340,10 +338,12 @@ enum cirrusfb_dbg_reg_class {
340/* info about board */ 338/* info about board */
341struct cirrusfb_info { 339struct cirrusfb_info {
342 u8 __iomem *regbase; 340 u8 __iomem *regbase;
341 u8 __iomem *laguna_mmio;
343 enum cirrus_board btype; 342 enum cirrus_board btype;
344 unsigned char SFR; /* Shadow of special function register */ 343 unsigned char SFR; /* Shadow of special function register */
345 344
346 struct cirrusfb_regs currentmode; 345 int multiplexing;
346 int doubleVCLK;
347 int blank_mode; 347 int blank_mode;
348 u32 pseudo_palette[16]; 348 u32 pseudo_palette[16];
349 349
@@ -357,43 +357,8 @@ static char *mode_option __devinitdata = "640x480@60";
357/**** BEGIN PROTOTYPES ******************************************************/ 357/**** BEGIN PROTOTYPES ******************************************************/
358 358
359/*--- Interface used by the world ------------------------------------------*/ 359/*--- Interface used by the world ------------------------------------------*/
360static int cirrusfb_init(void);
361#ifndef MODULE
362static int cirrusfb_setup(char *options);
363#endif
364
365static int cirrusfb_open(struct fb_info *info, int user);
366static int cirrusfb_release(struct fb_info *info, int user);
367static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
368 unsigned blue, unsigned transp,
369 struct fb_info *info);
370static int cirrusfb_check_var(struct fb_var_screeninfo *var,
371 struct fb_info *info);
372static int cirrusfb_set_par(struct fb_info *info);
373static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 360static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
374 struct fb_info *info); 361 struct fb_info *info);
375static int cirrusfb_blank(int blank_mode, struct fb_info *info);
376static void cirrusfb_fillrect(struct fb_info *info,
377 const struct fb_fillrect *region);
378static void cirrusfb_copyarea(struct fb_info *info,
379 const struct fb_copyarea *area);
380static void cirrusfb_imageblit(struct fb_info *info,
381 const struct fb_image *image);
382
383/* function table of the above functions */
384static struct fb_ops cirrusfb_ops = {
385 .owner = THIS_MODULE,
386 .fb_open = cirrusfb_open,
387 .fb_release = cirrusfb_release,
388 .fb_setcolreg = cirrusfb_setcolreg,
389 .fb_check_var = cirrusfb_check_var,
390 .fb_set_par = cirrusfb_set_par,
391 .fb_pan_display = cirrusfb_pan_display,
392 .fb_blank = cirrusfb_blank,
393 .fb_fillrect = cirrusfb_fillrect,
394 .fb_copyarea = cirrusfb_copyarea,
395 .fb_imageblit = cirrusfb_imageblit,
396};
397 362
398/*--- Internal routines ----------------------------------------------------*/ 363/*--- Internal routines ----------------------------------------------------*/
399static void init_vgachip(struct fb_info *info); 364static void init_vgachip(struct fb_info *info);
@@ -421,22 +386,27 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
421static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 386static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
422 u_short x, u_short y, 387 u_short x, u_short y,
423 u_short width, u_short height, 388 u_short width, u_short height,
424 u_char color, u_short line_length); 389 u32 fg_color, u32 bg_color,
390 u_short line_length, u_char blitmode);
425 391
426static void bestclock(long freq, int *nom, int *den, int *div); 392static void bestclock(long freq, int *nom, int *den, int *div);
427 393
428#ifdef CIRRUSFB_DEBUG 394#ifdef CIRRUSFB_DEBUG
429static void cirrusfb_dump(void); 395static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
430static void cirrusfb_dbg_reg_dump(caddr_t regbase); 396static void cirrusfb_dbg_print_regs(struct fb_info *info,
431static void cirrusfb_dbg_print_regs(caddr_t regbase, 397 caddr_t regbase,
432 enum cirrusfb_dbg_reg_class reg_class, ...); 398 enum cirrusfb_dbg_reg_class reg_class, ...);
433static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
434#endif /* CIRRUSFB_DEBUG */ 399#endif /* CIRRUSFB_DEBUG */
435 400
436/*** END PROTOTYPES ********************************************************/ 401/*** END PROTOTYPES ********************************************************/
437/*****************************************************************************/ 402/*****************************************************************************/
438/*** BEGIN Interface Used by the World ***************************************/ 403/*** BEGIN Interface Used by the World ***************************************/
439 404
405static inline int is_laguna(const struct cirrusfb_info *cinfo)
406{
407 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
408}
409
440static int opencount; 410static int opencount;
441 411
442/*--- Open /dev/fbx ---------------------------------------------------------*/ 412/*--- Open /dev/fbx ---------------------------------------------------------*/
@@ -460,85 +430,94 @@ static int cirrusfb_release(struct fb_info *info, int user)
460/**** BEGIN Hardware specific Routines **************************************/ 430/**** BEGIN Hardware specific Routines **************************************/
461 431
462/* Check if the MCLK is not a better clock source */ 432/* Check if the MCLK is not a better clock source */
463static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq) 433static int cirrusfb_check_mclk(struct fb_info *info, long freq)
464{ 434{
435 struct cirrusfb_info *cinfo = info->par;
465 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f; 436 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
466 437
467 /* Read MCLK value */ 438 /* Read MCLK value */
468 mclk = (14318 * mclk) >> 3; 439 mclk = (14318 * mclk) >> 3;
469 DPRINTK("Read MCLK of %ld kHz\n", mclk); 440 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
470 441
471 /* Determine if we should use MCLK instead of VCLK, and if so, what we 442 /* Determine if we should use MCLK instead of VCLK, and if so, what we
472 * should divide it by to get VCLK 443 * should divide it by to get VCLK
473 */ 444 */
474 445
475 if (abs(freq - mclk) < 250) { 446 if (abs(freq - mclk) < 250) {
476 DPRINTK("Using VCLK = MCLK\n"); 447 dev_dbg(info->device, "Using VCLK = MCLK\n");
477 return 1; 448 return 1;
478 } else if (abs(freq - (mclk / 2)) < 250) { 449 } else if (abs(freq - (mclk / 2)) < 250) {
479 DPRINTK("Using VCLK = MCLK/2\n"); 450 dev_dbg(info->device, "Using VCLK = MCLK/2\n");
480 return 2; 451 return 2;
481 } 452 }
482 453
483 return 0; 454 return 0;
484} 455}
485 456
486static int cirrusfb_check_var(struct fb_var_screeninfo *var, 457static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
487 struct fb_info *info) 458 struct fb_info *info)
488{ 459{
489 int yres; 460 long freq;
490 /* memory size in pixels */ 461 long maxclock;
491 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel; 462 struct cirrusfb_info *cinfo = info->par;
463 unsigned maxclockidx = var->bits_per_pixel >> 3;
492 464
493 switch (var->bits_per_pixel) { 465 /* convert from ps to kHz */
494 case 1: 466 freq = PICOS2KHZ(var->pixclock);
495 pixels /= 4;
496 break; /* 8 pixel per byte, only 1/4th of mem usable */
497 case 8:
498 case 16:
499 case 32:
500 break; /* 1 pixel == 1 byte */
501 default:
502 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
503 "color depth not supported.\n",
504 var->xres, var->yres, var->bits_per_pixel);
505 DPRINTK("EXIT - EINVAL error\n");
506 return -EINVAL;
507 }
508 467
509 if (var->xres_virtual < var->xres) 468 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
510 var->xres_virtual = var->xres;
511 /* use highest possible virtual resolution */
512 if (var->yres_virtual == -1) {
513 var->yres_virtual = pixels / var->xres_virtual;
514 469
515 printk(KERN_INFO "cirrusfb: virtual resolution set to " 470 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
516 "maximum of %dx%d\n", var->xres_virtual, 471 cinfo->multiplexing = 0;
517 var->yres_virtual);
518 }
519 if (var->yres_virtual < var->yres)
520 var->yres_virtual = var->yres;
521 472
522 if (var->xres_virtual * var->yres_virtual > pixels) { 473 /* If the frequency is greater than we can support, we might be able
523 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... " 474 * to use multiplexing for the video mode */
524 "virtual resolution too high to fit into video memory!\n", 475 if (freq > maxclock) {
525 var->xres_virtual, var->yres_virtual, 476 dev_err(info->device,
526 var->bits_per_pixel); 477 "Frequency greater than maxclock (%ld kHz)\n",
527 DPRINTK("EXIT - EINVAL error\n"); 478 maxclock);
528 return -EINVAL; 479 return -EINVAL;
529 } 480 }
481 /*
482 * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
483 * pixel clock
484 */
485 if (var->bits_per_pixel == 8) {
486 switch (cinfo->btype) {
487 case BT_ALPINE:
488 case BT_SD64:
489 case BT_PICASSO4:
490 if (freq > 85500)
491 cinfo->multiplexing = 1;
492 break;
493 case BT_GD5480:
494 if (freq > 135100)
495 cinfo->multiplexing = 1;
496 break;
530 497
498 default:
499 break;
500 }
501 }
531 502
532 if (var->xoffset < 0) 503 /* If we have a 1MB 5434, we need to put ourselves in a mode where
533 var->xoffset = 0; 504 * the VCLK is double the pixel clock. */
534 if (var->yoffset < 0) 505 cinfo->doubleVCLK = 0;
535 var->yoffset = 0; 506 if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
507 var->bits_per_pixel == 16) {
508 cinfo->doubleVCLK = 1;
509 }
536 510
537 /* truncate xoffset and yoffset to maximum if too high */ 511 return 0;
538 if (var->xoffset > var->xres_virtual - var->xres) 512}
539 var->xoffset = var->xres_virtual - var->xres - 1; 513
540 if (var->yoffset > var->yres_virtual - var->yres) 514static int cirrusfb_check_var(struct fb_var_screeninfo *var,
541 var->yoffset = var->yres_virtual - var->yres - 1; 515 struct fb_info *info)
516{
517 int yres;
518 /* memory size in pixels */
519 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
520 struct cirrusfb_info *cinfo = info->par;
542 521
543 switch (var->bits_per_pixel) { 522 switch (var->bits_per_pixel) {
544 case 1: 523 case 1:
@@ -550,7 +529,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
550 529
551 case 8: 530 case 8:
552 var->red.offset = 0; 531 var->red.offset = 0;
553 var->red.length = 6; 532 var->red.length = 8;
554 var->green = var->red; 533 var->green = var->red;
555 var->blue = var->red; 534 var->blue = var->red;
556 break; 535 break;
@@ -561,20 +540,20 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
561 var->green.offset = -3; 540 var->green.offset = -3;
562 var->blue.offset = 8; 541 var->blue.offset = 8;
563 } else { 542 } else {
564 var->red.offset = 10; 543 var->red.offset = 11;
565 var->green.offset = 5; 544 var->green.offset = 5;
566 var->blue.offset = 0; 545 var->blue.offset = 0;
567 } 546 }
568 var->red.length = 5; 547 var->red.length = 5;
569 var->green.length = 5; 548 var->green.length = 6;
570 var->blue.length = 5; 549 var->blue.length = 5;
571 break; 550 break;
572 551
573 case 32: 552 case 24:
574 if (isPReP) { 553 if (isPReP) {
575 var->red.offset = 8; 554 var->red.offset = 0;
576 var->green.offset = 16; 555 var->green.offset = 8;
577 var->blue.offset = 24; 556 var->blue.offset = 16;
578 } else { 557 } else {
579 var->red.offset = 16; 558 var->red.offset = 16;
580 var->green.offset = 8; 559 var->green.offset = 8;
@@ -586,12 +565,45 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
586 break; 565 break;
587 566
588 default: 567 default:
589 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); 568 dev_dbg(info->device,
569 "Unsupported bpp size: %d\n", var->bits_per_pixel);
590 assert(false); 570 assert(false);
591 /* should never occur */ 571 /* should never occur */
592 break; 572 break;
593 } 573 }
594 574
575 if (var->xres_virtual < var->xres)
576 var->xres_virtual = var->xres;
577 /* use highest possible virtual resolution */
578 if (var->yres_virtual == -1) {
579 var->yres_virtual = pixels / var->xres_virtual;
580
581 dev_info(info->device,
582 "virtual resolution set to maximum of %dx%d\n",
583 var->xres_virtual, var->yres_virtual);
584 }
585 if (var->yres_virtual < var->yres)
586 var->yres_virtual = var->yres;
587
588 if (var->xres_virtual * var->yres_virtual > pixels) {
589 dev_err(info->device, "mode %dx%dx%d rejected... "
590 "virtual resolution too high to fit into video memory!\n",
591 var->xres_virtual, var->yres_virtual,
592 var->bits_per_pixel);
593 return -EINVAL;
594 }
595
596 if (var->xoffset < 0)
597 var->xoffset = 0;
598 if (var->yoffset < 0)
599 var->yoffset = 0;
600
601 /* truncate xoffset and yoffset to maximum if too high */
602 if (var->xoffset > var->xres_virtual - var->xres)
603 var->xoffset = var->xres_virtual - var->xres - 1;
604 if (var->yoffset > var->yres_virtual - var->yres)
605 var->yoffset = var->yres_virtual - var->yres - 1;
606
595 var->red.msb_right = 607 var->red.msb_right =
596 var->green.msb_right = 608 var->green.msb_right =
597 var->blue.msb_right = 609 var->blue.msb_right =
@@ -606,99 +618,31 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
606 yres = (yres + 1) / 2; 618 yres = (yres + 1) / 2;
607 619
608 if (yres >= 1280) { 620 if (yres >= 1280) {
609 printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; " 621 dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
610 "special treatment required! (TODO)\n"); 622 "special treatment required! (TODO)\n");
611 DPRINTK("EXIT - EINVAL error\n");
612 return -EINVAL; 623 return -EINVAL;
613 } 624 }
614 625
615 return 0; 626 if (cirrusfb_check_pixclock(var, info))
616} 627 return -EINVAL;
617
618static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
619 struct cirrusfb_regs *regs,
620 struct fb_info *info)
621{
622 long freq;
623 long maxclock;
624 int maxclockidx = var->bits_per_pixel >> 3;
625 struct cirrusfb_info *cinfo = info->par;
626
627 switch (var->bits_per_pixel) {
628 case 1:
629 info->fix.line_length = var->xres_virtual / 8;
630 info->fix.visual = FB_VISUAL_MONO10;
631 break;
632
633 case 8:
634 info->fix.line_length = var->xres_virtual;
635 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
636 break;
637
638 case 16:
639 case 32:
640 info->fix.line_length = var->xres_virtual * maxclockidx;
641 info->fix.visual = FB_VISUAL_TRUECOLOR;
642 break;
643
644 default:
645 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
646 assert(false);
647 /* should never occur */
648 break;
649 }
650
651 info->fix.type = FB_TYPE_PACKED_PIXELS;
652
653 /* convert from ps to kHz */
654 freq = PICOS2KHZ(var->pixclock);
655
656 DPRINTK("desired pixclock: %ld kHz\n", freq);
657
658 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
659 regs->multiplexing = 0;
660 628
661 /* If the frequency is greater than we can support, we might be able 629 if (!is_laguna(cinfo))
662 * to use multiplexing for the video mode */ 630 var->accel_flags = FB_ACCELF_TEXT;
663 if (freq > maxclock) {
664 switch (cinfo->btype) {
665 case BT_ALPINE:
666 case BT_GD5480:
667 regs->multiplexing = 1;
668 break;
669 631
670 default:
671 printk(KERN_ERR "cirrusfb: Frequency greater "
672 "than maxclock (%ld kHz)\n", maxclock);
673 DPRINTK("EXIT - return -EINVAL\n");
674 return -EINVAL;
675 }
676 }
677#if 0
678 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
679 * the VCLK is double the pixel clock. */
680 switch (var->bits_per_pixel) {
681 case 16:
682 case 32:
683 if (var->xres <= 800)
684 /* Xbh has this type of clock for 32-bit */
685 freq /= 2;
686 break;
687 }
688#endif
689 return 0; 632 return 0;
690} 633}
691 634
692static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo, 635static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
693 int div)
694{ 636{
637 struct cirrusfb_info *cinfo = info->par;
695 unsigned char old1f, old1e; 638 unsigned char old1f, old1e;
639
696 assert(cinfo != NULL); 640 assert(cinfo != NULL);
697 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40; 641 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
698 642
699 if (div) { 643 if (div) {
700 DPRINTK("Set %s as pixclock source.\n", 644 dev_dbg(info->device, "Set %s as pixclock source.\n",
701 (div == 2) ? "MCLK/2" : "MCLK"); 645 (div == 2) ? "MCLK/2" : "MCLK");
702 old1f |= 0x40; 646 old1f |= 0x40;
703 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1; 647 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
704 if (div == 2) 648 if (div == 2)
@@ -718,101 +662,119 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
718{ 662{
719 struct cirrusfb_info *cinfo = info->par; 663 struct cirrusfb_info *cinfo = info->par;
720 struct fb_var_screeninfo *var = &info->var; 664 struct fb_var_screeninfo *var = &info->var;
721 struct cirrusfb_regs regs;
722 u8 __iomem *regbase = cinfo->regbase; 665 u8 __iomem *regbase = cinfo->regbase;
723 unsigned char tmp; 666 unsigned char tmp;
724 int offset = 0, err; 667 int pitch;
725 const struct cirrusfb_board_info_rec *bi; 668 const struct cirrusfb_board_info_rec *bi;
726 int hdispend, hsyncstart, hsyncend, htotal; 669 int hdispend, hsyncstart, hsyncend, htotal;
727 int yres, vdispend, vsyncstart, vsyncend, vtotal; 670 int yres, vdispend, vsyncstart, vsyncend, vtotal;
728 long freq; 671 long freq;
729 int nom, den, div; 672 int nom, den, div;
673 unsigned int control = 0, format = 0, threshold = 0;
730 674
731 DPRINTK("ENTER\n"); 675 dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
732 DPRINTK("Requested mode: %dx%dx%d\n",
733 var->xres, var->yres, var->bits_per_pixel); 676 var->xres, var->yres, var->bits_per_pixel);
734 DPRINTK("pixclock: %d\n", var->pixclock);
735 677
736 init_vgachip(info); 678 switch (var->bits_per_pixel) {
679 case 1:
680 info->fix.line_length = var->xres_virtual / 8;
681 info->fix.visual = FB_VISUAL_MONO10;
682 break;
737 683
738 err = cirrusfb_decode_var(var, &regs, info); 684 case 8:
739 if (err) { 685 info->fix.line_length = var->xres_virtual;
740 /* should never happen */ 686 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
741 DPRINTK("mode change aborted. invalid var.\n"); 687 break;
742 return -EINVAL; 688
689 case 16:
690 case 24:
691 info->fix.line_length = var->xres_virtual *
692 var->bits_per_pixel >> 3;
693 info->fix.visual = FB_VISUAL_TRUECOLOR;
694 break;
743 } 695 }
696 info->fix.type = FB_TYPE_PACKED_PIXELS;
697
698 init_vgachip(info);
744 699
745 bi = &cirrusfb_board_info[cinfo->btype]; 700 bi = &cirrusfb_board_info[cinfo->btype];
746 701
747 hsyncstart = var->xres + var->right_margin; 702 hsyncstart = var->xres + var->right_margin;
748 hsyncend = hsyncstart + var->hsync_len; 703 hsyncend = hsyncstart + var->hsync_len;
749 htotal = (hsyncend + var->left_margin) / 8 - 5; 704 htotal = (hsyncend + var->left_margin) / 8;
750 hdispend = var->xres / 8 - 1; 705 hdispend = var->xres / 8;
751 hsyncstart = hsyncstart / 8 + 1; 706 hsyncstart = hsyncstart / 8;
752 hsyncend = hsyncend / 8 + 1; 707 hsyncend = hsyncend / 8;
753 708
754 yres = var->yres; 709 vdispend = var->yres;
755 vsyncstart = yres + var->lower_margin; 710 vsyncstart = vdispend + var->lower_margin;
756 vsyncend = vsyncstart + var->vsync_len; 711 vsyncend = vsyncstart + var->vsync_len;
757 vtotal = vsyncend + var->upper_margin; 712 vtotal = vsyncend + var->upper_margin;
758 vdispend = yres - 1;
759 713
760 if (var->vmode & FB_VMODE_DOUBLE) { 714 if (var->vmode & FB_VMODE_DOUBLE) {
761 yres *= 2; 715 vdispend *= 2;
762 vsyncstart *= 2; 716 vsyncstart *= 2;
763 vsyncend *= 2; 717 vsyncend *= 2;
764 vtotal *= 2; 718 vtotal *= 2;
765 } else if (var->vmode & FB_VMODE_INTERLACED) { 719 } else if (var->vmode & FB_VMODE_INTERLACED) {
766 yres = (yres + 1) / 2; 720 vdispend = (vdispend + 1) / 2;
767 vsyncstart = (vsyncstart + 1) / 2; 721 vsyncstart = (vsyncstart + 1) / 2;
768 vsyncend = (vsyncend + 1) / 2; 722 vsyncend = (vsyncend + 1) / 2;
769 vtotal = (vtotal + 1) / 2; 723 vtotal = (vtotal + 1) / 2;
770 } 724 }
771 725 yres = vdispend;
772 vtotal -= 2;
773 vsyncstart -= 1;
774 vsyncend -= 1;
775
776 if (yres >= 1024) { 726 if (yres >= 1024) {
777 vtotal /= 2; 727 vtotal /= 2;
778 vsyncstart /= 2; 728 vsyncstart /= 2;
779 vsyncend /= 2; 729 vsyncend /= 2;
780 vdispend /= 2; 730 vdispend /= 2;
781 } 731 }
782 if (regs.multiplexing) { 732
733 vdispend -= 1;
734 vsyncstart -= 1;
735 vsyncend -= 1;
736 vtotal -= 2;
737
738 if (cinfo->multiplexing) {
783 htotal /= 2; 739 htotal /= 2;
784 hsyncstart /= 2; 740 hsyncstart /= 2;
785 hsyncend /= 2; 741 hsyncend /= 2;
786 hdispend /= 2; 742 hdispend /= 2;
787 } 743 }
744
745 htotal -= 5;
746 hdispend -= 1;
747 hsyncstart += 1;
748 hsyncend += 1;
749
788 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ 750 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
789 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ 751 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
790 752
791 /* if debugging is enabled, all parameters get output before writing */ 753 /* if debugging is enabled, all parameters get output before writing */
792 DPRINTK("CRT0: %d\n", htotal); 754 dev_dbg(info->device, "CRT0: %d\n", htotal);
793 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal); 755 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
794 756
795 DPRINTK("CRT1: %d\n", hdispend); 757 dev_dbg(info->device, "CRT1: %d\n", hdispend);
796 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend); 758 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
797 759
798 DPRINTK("CRT2: %d\n", var->xres / 8); 760 dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
799 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8); 761 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
800 762
801 /* + 128: Compatible read */ 763 /* + 128: Compatible read */
802 DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32); 764 dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
803 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END, 765 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
804 128 + ((htotal + 5) % 32)); 766 128 + ((htotal + 5) % 32));
805 767
806 DPRINTK("CRT4: %d\n", hsyncstart); 768 dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
807 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart); 769 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
808 770
809 tmp = hsyncend % 32; 771 tmp = hsyncend % 32;
810 if ((htotal + 5) & 32) 772 if ((htotal + 5) & 32)
811 tmp += 128; 773 tmp += 128;
812 DPRINTK("CRT5: %d\n", tmp); 774 dev_dbg(info->device, "CRT5: %d\n", tmp);
813 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp); 775 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
814 776
815 DPRINTK("CRT6: %d\n", vtotal & 0xff); 777 dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
816 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff); 778 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
817 779
818 tmp = 16; /* LineCompare bit #9 */ 780 tmp = 16; /* LineCompare bit #9 */
@@ -830,7 +792,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
830 tmp |= 64; 792 tmp |= 64;
831 if (vsyncstart & 512) 793 if (vsyncstart & 512)
832 tmp |= 128; 794 tmp |= 128;
833 DPRINTK("CRT7: %d\n", tmp); 795 dev_dbg(info->device, "CRT7: %d\n", tmp);
834 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp); 796 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
835 797
836 tmp = 0x40; /* LineCompare bit #8 */ 798 tmp = 0x40; /* LineCompare bit #8 */
@@ -838,25 +800,25 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
838 tmp |= 0x20; 800 tmp |= 0x20;
839 if (var->vmode & FB_VMODE_DOUBLE) 801 if (var->vmode & FB_VMODE_DOUBLE)
840 tmp |= 0x80; 802 tmp |= 0x80;
841 DPRINTK("CRT9: %d\n", tmp); 803 dev_dbg(info->device, "CRT9: %d\n", tmp);
842 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp); 804 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
843 805
844 DPRINTK("CRT10: %d\n", vsyncstart & 0xff); 806 dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
845 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff); 807 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
846 808
847 DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16); 809 dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
848 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32); 810 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
849 811
850 DPRINTK("CRT12: %d\n", vdispend & 0xff); 812 dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
851 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff); 813 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
852 814
853 DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff); 815 dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
854 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff); 816 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
855 817
856 DPRINTK("CRT16: %d\n", vtotal & 0xff); 818 dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
857 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff); 819 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
858 820
859 DPRINTK("CRT18: 0xff\n"); 821 dev_dbg(info->device, "CRT18: 0xff\n");
860 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff); 822 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
861 823
862 tmp = 0; 824 tmp = 0;
@@ -871,41 +833,75 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
871 if (vtotal & 512) 833 if (vtotal & 512)
872 tmp |= 128; 834 tmp |= 128;
873 835
874 DPRINTK("CRT1a: %d\n", tmp); 836 dev_dbg(info->device, "CRT1a: %d\n", tmp);
875 vga_wcrt(regbase, CL_CRT1A, tmp); 837 vga_wcrt(regbase, CL_CRT1A, tmp);
876 838
877 freq = PICOS2KHZ(var->pixclock); 839 freq = PICOS2KHZ(var->pixclock);
840 if (var->bits_per_pixel == 24)
841 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
842 freq *= 3;
843 if (cinfo->multiplexing)
844 freq /= 2;
845 if (cinfo->doubleVCLK)
846 freq *= 2;
847
878 bestclock(freq, &nom, &den, &div); 848 bestclock(freq, &nom, &den, &div);
879 849
850 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
851 freq, nom, den, div);
852
880 /* set VCLK0 */ 853 /* set VCLK0 */
881 /* hardware RefClock: 14.31818 MHz */ 854 /* hardware RefClock: 14.31818 MHz */
882 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 855 /* formula: VClk = (OSC * N) / (D * (1+P)) */
883 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 856 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
884 857
885 if (cinfo->btype == BT_ALPINE) { 858 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
859 cinfo->btype == BT_SD64) {
886 /* if freq is close to mclk or mclk/2 select mclk 860 /* if freq is close to mclk or mclk/2 select mclk
887 * as clock source 861 * as clock source
888 */ 862 */
889 int divMCLK = cirrusfb_check_mclk(cinfo, freq); 863 int divMCLK = cirrusfb_check_mclk(info, freq);
890 if (divMCLK) { 864 if (divMCLK)
891 nom = 0; 865 nom = 0;
892 cirrusfb_set_mclk_as_source(cinfo, divMCLK); 866 cirrusfb_set_mclk_as_source(info, divMCLK);
867 }
868 if (is_laguna(cinfo)) {
869 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
870 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
871 unsigned short tile_control;
872
873 if (cinfo->btype == BT_LAGUNAB) {
874 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
875 tile_control &= ~0x80;
876 fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
893 } 877 }
878
879 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
880 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
881 control = fb_readw(cinfo->laguna_mmio + 0x402);
882 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
883 control &= ~0x6800;
884 format = 0;
885 threshold &= 0xffc0 & 0x3fbf;
894 } 886 }
895 if (nom) { 887 if (nom) {
896 vga_wseq(regbase, CL_SEQRB, nom);
897 tmp = den << 1; 888 tmp = den << 1;
898 if (div != 0) 889 if (div != 0)
899 tmp |= 1; 890 tmp |= 1;
900
901 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 891 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
902 if ((cinfo->btype == BT_SD64) || 892 if ((cinfo->btype == BT_SD64) ||
903 (cinfo->btype == BT_ALPINE) || 893 (cinfo->btype == BT_ALPINE) ||
904 (cinfo->btype == BT_GD5480)) 894 (cinfo->btype == BT_GD5480))
905 tmp |= 0x80; 895 tmp |= 0x80;
906 896
907 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp); 897 /* Laguna chipset has reversed clock registers */
908 vga_wseq(regbase, CL_SEQR1B, tmp); 898 if (is_laguna(cinfo)) {
899 vga_wseq(regbase, CL_SEQRE, tmp);
900 vga_wseq(regbase, CL_SEQR1E, nom);
901 } else {
902 vga_wseq(regbase, CL_SEQRE, nom);
903 vga_wseq(regbase, CL_SEQR1E, tmp);
904 }
909 } 905 }
910 906
911 if (yres >= 1024) 907 if (yres >= 1024)
@@ -916,9 +912,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
916 * address wrap, no compat. */ 912 * address wrap, no compat. */
917 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3); 913 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
918 914
919/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
920 * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
921
922 /* don't know if it would hurt to also program this if no interlaced */ 915 /* don't know if it would hurt to also program this if no interlaced */
923 /* mode is used, but I feel better this way.. :-) */ 916 /* mode is used, but I feel better this way.. :-) */
924 if (var->vmode & FB_VMODE_INTERLACED) 917 if (var->vmode & FB_VMODE_INTERLACED)
@@ -926,19 +919,15 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
926 else 919 else
927 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 920 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
928 921
929 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0); 922 /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
930
931 /* adjust horizontal/vertical sync type (low/high) */
932 /* enable display memory & CRTC I/O address for color mode */ 923 /* enable display memory & CRTC I/O address for color mode */
933 tmp = 0x03; 924 tmp = 0x03 | 0xc;
934 if (var->sync & FB_SYNC_HOR_HIGH_ACT) 925 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
935 tmp |= 0x40; 926 tmp |= 0x40;
936 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 927 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
937 tmp |= 0x80; 928 tmp |= 0x80;
938 WGen(cinfo, VGA_MIS_W, tmp); 929 WGen(cinfo, VGA_MIS_W, tmp);
939 930
940 /* Screen A Preset Row-Scan register */
941 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
942 /* text cursor on and start line */ 931 /* text cursor on and start line */
943 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0); 932 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
944 /* text cursor end line */ 933 /* text cursor end line */
@@ -952,7 +941,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
952 941
953 /* programming for different color depths */ 942 /* programming for different color depths */
954 if (var->bits_per_pixel == 1) { 943 if (var->bits_per_pixel == 1) {
955 DPRINTK("cirrusfb: preparing for 1 bit deep display\n"); 944 dev_dbg(info->device, "preparing for 1 bit deep display\n");
956 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */ 945 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
957 946
958 /* SR07 */ 947 /* SR07 */
@@ -964,68 +953,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
964 case BT_PICASSO4: 953 case BT_PICASSO4:
965 case BT_ALPINE: 954 case BT_ALPINE:
966 case BT_GD5480: 955 case BT_GD5480:
967 DPRINTK(" (for GD54xx)\n");
968 vga_wseq(regbase, CL_SEQR7, 956 vga_wseq(regbase, CL_SEQR7,
969 regs.multiplexing ? 957 cinfo->multiplexing ?
970 bi->sr07_1bpp_mux : bi->sr07_1bpp); 958 bi->sr07_1bpp_mux : bi->sr07_1bpp);
971 break; 959 break;
972 960
973 case BT_LAGUNA: 961 case BT_LAGUNA:
974 DPRINTK(" (for GD546x)\n"); 962 case BT_LAGUNAB:
975 vga_wseq(regbase, CL_SEQR7, 963 vga_wseq(regbase, CL_SEQR7,
976 vga_rseq(regbase, CL_SEQR7) & ~0x01); 964 vga_rseq(regbase, CL_SEQR7) & ~0x01);
977 break; 965 break;
978 966
979 default: 967 default:
980 printk(KERN_WARNING "cirrusfb: unknown Board\n"); 968 dev_warn(info->device, "unknown Board\n");
981 break; 969 break;
982 } 970 }
983 971
984 /* Extended Sequencer Mode */ 972 /* Extended Sequencer Mode */
985 switch (cinfo->btype) { 973 switch (cinfo->btype) {
986 case BT_SD64:
987 /* setting the SEQRF on SD64 is not necessary
988 * (only during init)
989 */
990 DPRINTK("(for SD64)\n");
991 /* MCLK select */
992 vga_wseq(regbase, CL_SEQR1F, 0x1a);
993 break;
994 974
995 case BT_PICCOLO: 975 case BT_PICCOLO:
996 case BT_SPECTRUM: 976 case BT_SPECTRUM:
997 DPRINTK("(for Piccolo/Spectrum)\n");
998 /* ### ueberall 0x22? */
999 /* ##vorher 1c MCLK select */
1000 vga_wseq(regbase, CL_SEQR1F, 0x22);
1001 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ 977 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
1002 vga_wseq(regbase, CL_SEQRF, 0xb0); 978 vga_wseq(regbase, CL_SEQRF, 0xb0);
1003 break; 979 break;
1004 980
1005 case BT_PICASSO: 981 case BT_PICASSO:
1006 DPRINTK("(for Picasso)\n");
1007 /* ##vorher 22 MCLK select */
1008 vga_wseq(regbase, CL_SEQR1F, 0x22);
1009 /* ## vorher d0 avoid FIFO underruns..? */ 982 /* ## vorher d0 avoid FIFO underruns..? */
1010 vga_wseq(regbase, CL_SEQRF, 0xd0); 983 vga_wseq(regbase, CL_SEQRF, 0xd0);
1011 break; 984 break;
1012 985
986 case BT_SD64:
1013 case BT_PICASSO4: 987 case BT_PICASSO4:
1014 case BT_ALPINE: 988 case BT_ALPINE:
1015 case BT_GD5480: 989 case BT_GD5480:
1016 case BT_LAGUNA: 990 case BT_LAGUNA:
1017 DPRINTK(" (for GD54xx)\n"); 991 case BT_LAGUNAB:
1018 /* do nothing */ 992 /* do nothing */
1019 break; 993 break;
1020 994
1021 default: 995 default:
1022 printk(KERN_WARNING "cirrusfb: unknown Board\n"); 996 dev_warn(info->device, "unknown Board\n");
1023 break; 997 break;
1024 } 998 }
1025 999
1026 /* pixel mask: pass-through for first plane */ 1000 /* pixel mask: pass-through for first plane */
1027 WGen(cinfo, VGA_PEL_MSK, 0x01); 1001 WGen(cinfo, VGA_PEL_MSK, 0x01);
1028 if (regs.multiplexing) 1002 if (cinfo->multiplexing)
1029 /* hidden dac reg: 1280x1024 */ 1003 /* hidden dac reg: 1280x1024 */
1030 WHDR(cinfo, 0x4a); 1004 WHDR(cinfo, 0x4a);
1031 else 1005 else
@@ -1035,7 +1009,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1035 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06); 1009 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1036 /* plane mask: only write to first plane */ 1010 /* plane mask: only write to first plane */
1037 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01); 1011 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1038 offset = var->xres_virtual / 16;
1039 } 1012 }
1040 1013
1041 /****************************************************** 1014 /******************************************************
@@ -1045,7 +1018,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1045 */ 1018 */
1046 1019
1047 else if (var->bits_per_pixel == 8) { 1020 else if (var->bits_per_pixel == 8) {
1048 DPRINTK("cirrusfb: preparing for 8 bit deep display\n"); 1021 dev_dbg(info->device, "preparing for 8 bit deep display\n");
1049 switch (cinfo->btype) { 1022 switch (cinfo->btype) {
1050 case BT_SD64: 1023 case BT_SD64:
1051 case BT_PICCOLO: 1024 case BT_PICCOLO:
@@ -1054,34 +1027,27 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1054 case BT_PICASSO4: 1027 case BT_PICASSO4:
1055 case BT_ALPINE: 1028 case BT_ALPINE:
1056 case BT_GD5480: 1029 case BT_GD5480:
1057 DPRINTK(" (for GD54xx)\n");
1058 vga_wseq(regbase, CL_SEQR7, 1030 vga_wseq(regbase, CL_SEQR7,
1059 regs.multiplexing ? 1031 cinfo->multiplexing ?
1060 bi->sr07_8bpp_mux : bi->sr07_8bpp); 1032 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1061 break; 1033 break;
1062 1034
1063 case BT_LAGUNA: 1035 case BT_LAGUNA:
1064 DPRINTK(" (for GD546x)\n"); 1036 case BT_LAGUNAB:
1065 vga_wseq(regbase, CL_SEQR7, 1037 vga_wseq(regbase, CL_SEQR7,
1066 vga_rseq(regbase, CL_SEQR7) | 0x01); 1038 vga_rseq(regbase, CL_SEQR7) | 0x01);
1039 threshold |= 0x10;
1067 break; 1040 break;
1068 1041
1069 default: 1042 default:
1070 printk(KERN_WARNING "cirrusfb: unknown Board\n"); 1043 dev_warn(info->device, "unknown Board\n");
1071 break; 1044 break;
1072 } 1045 }
1073 1046
1074 switch (cinfo->btype) { 1047 switch (cinfo->btype) {
1075 case BT_SD64:
1076 /* MCLK select */
1077 vga_wseq(regbase, CL_SEQR1F, 0x1d);
1078 break;
1079
1080 case BT_PICCOLO: 1048 case BT_PICCOLO:
1081 case BT_PICASSO: 1049 case BT_PICASSO:
1082 case BT_SPECTRUM: 1050 case BT_SPECTRUM:
1083 /* ### vorher 1c MCLK select */
1084 vga_wseq(regbase, CL_SEQR1F, 0x22);
1085 /* Fast Page-Mode writes */ 1051 /* Fast Page-Mode writes */
1086 vga_wseq(regbase, CL_SEQRF, 0xb0); 1052 vga_wseq(regbase, CL_SEQRF, 0xb0);
1087 break; 1053 break;
@@ -1091,40 +1057,27 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1091 /* ### INCOMPLETE!! */ 1057 /* ### INCOMPLETE!! */
1092 vga_wseq(regbase, CL_SEQRF, 0xb8); 1058 vga_wseq(regbase, CL_SEQRF, 0xb8);
1093#endif 1059#endif
1094/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1095 break;
1096
1097 case BT_ALPINE: 1060 case BT_ALPINE:
1098 DPRINTK(" (for GD543x)\n"); 1061 case BT_SD64:
1099 /* We already set SRF and SR1F */
1100 break;
1101
1102 case BT_GD5480: 1062 case BT_GD5480:
1103 case BT_LAGUNA: 1063 case BT_LAGUNA:
1104 DPRINTK(" (for GD54xx)\n"); 1064 case BT_LAGUNAB:
1105 /* do nothing */ 1065 /* do nothing */
1106 break; 1066 break;
1107 1067
1108 default: 1068 default:
1109 printk(KERN_WARNING "cirrusfb: unknown Board\n"); 1069 dev_warn(info->device, "unknown board\n");
1110 break; 1070 break;
1111 } 1071 }
1112 1072
1113 /* mode register: 256 color mode */ 1073 /* mode register: 256 color mode */
1114 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1074 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1115 /* pixel mask: pass-through all planes */ 1075 if (cinfo->multiplexing)
1116 WGen(cinfo, VGA_PEL_MSK, 0xff);
1117 if (regs.multiplexing)
1118 /* hidden dac reg: 1280x1024 */ 1076 /* hidden dac reg: 1280x1024 */
1119 WHDR(cinfo, 0x4a); 1077 WHDR(cinfo, 0x4a);
1120 else 1078 else
1121 /* hidden dac: nothing */ 1079 /* hidden dac: nothing */
1122 WHDR(cinfo, 0); 1080 WHDR(cinfo, 0);
1123 /* memory mode: chain4, ext. memory */
1124 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1125 /* plane mask: enable writing to all 4 planes */
1126 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1127 offset = var->xres_virtual / 8;
1128 } 1081 }
1129 1082
1130 /****************************************************** 1083 /******************************************************
@@ -1134,147 +1087,110 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1134 */ 1087 */
1135 1088
1136 else if (var->bits_per_pixel == 16) { 1089 else if (var->bits_per_pixel == 16) {
1137 DPRINTK("cirrusfb: preparing for 16 bit deep display\n"); 1090 dev_dbg(info->device, "preparing for 16 bit deep display\n");
1138 switch (cinfo->btype) { 1091 switch (cinfo->btype) {
1139 case BT_SD64:
1140 /* Extended Sequencer Mode: 256c col. mode */
1141 vga_wseq(regbase, CL_SEQR7, 0xf7);
1142 /* MCLK select */
1143 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1144 break;
1145
1146 case BT_PICCOLO: 1092 case BT_PICCOLO:
1147 case BT_SPECTRUM: 1093 case BT_SPECTRUM:
1148 vga_wseq(regbase, CL_SEQR7, 0x87); 1094 vga_wseq(regbase, CL_SEQR7, 0x87);
1149 /* Fast Page-Mode writes */ 1095 /* Fast Page-Mode writes */
1150 vga_wseq(regbase, CL_SEQRF, 0xb0); 1096 vga_wseq(regbase, CL_SEQRF, 0xb0);
1151 /* MCLK select */
1152 vga_wseq(regbase, CL_SEQR1F, 0x22);
1153 break; 1097 break;
1154 1098
1155 case BT_PICASSO: 1099 case BT_PICASSO:
1156 vga_wseq(regbase, CL_SEQR7, 0x27); 1100 vga_wseq(regbase, CL_SEQR7, 0x27);
1157 /* Fast Page-Mode writes */ 1101 /* Fast Page-Mode writes */
1158 vga_wseq(regbase, CL_SEQRF, 0xb0); 1102 vga_wseq(regbase, CL_SEQRF, 0xb0);
1159 /* MCLK select */
1160 vga_wseq(regbase, CL_SEQR1F, 0x22);
1161 break; 1103 break;
1162 1104
1105 case BT_SD64:
1163 case BT_PICASSO4: 1106 case BT_PICASSO4:
1164 vga_wseq(regbase, CL_SEQR7, 0x27);
1165/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1166 break;
1167
1168 case BT_ALPINE: 1107 case BT_ALPINE:
1169 DPRINTK(" (for GD543x)\n"); 1108 /* Extended Sequencer Mode: 256c col. mode */
1170 vga_wseq(regbase, CL_SEQR7, 0xa7); 1109 vga_wseq(regbase, CL_SEQR7,
1110 cinfo->doubleVCLK ? 0xa3 : 0xa7);
1171 break; 1111 break;
1172 1112
1173 case BT_GD5480: 1113 case BT_GD5480:
1174 DPRINTK(" (for GD5480)\n");
1175 vga_wseq(regbase, CL_SEQR7, 0x17); 1114 vga_wseq(regbase, CL_SEQR7, 0x17);
1176 /* We already set SRF and SR1F */ 1115 /* We already set SRF and SR1F */
1177 break; 1116 break;
1178 1117
1179 case BT_LAGUNA: 1118 case BT_LAGUNA:
1180 DPRINTK(" (for GD546x)\n"); 1119 case BT_LAGUNAB:
1181 vga_wseq(regbase, CL_SEQR7, 1120 vga_wseq(regbase, CL_SEQR7,
1182 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1121 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1122 control |= 0x2000;
1123 format |= 0x1400;
1124 threshold |= 0x10;
1183 break; 1125 break;
1184 1126
1185 default: 1127 default:
1186 printk(KERN_WARNING "CIRRUSFB: unknown Board\n"); 1128 dev_warn(info->device, "unknown Board\n");
1187 break; 1129 break;
1188 } 1130 }
1189 1131
1190 /* mode register: 256 color mode */ 1132 /* mode register: 256 color mode */
1191 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1133 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1192 /* pixel mask: pass-through all planes */
1193 WGen(cinfo, VGA_PEL_MSK, 0xff);
1194#ifdef CONFIG_PCI 1134#ifdef CONFIG_PCI
1195 WHDR(cinfo, 0xc0); /* Copy Xbh */ 1135 WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
1196#elif defined(CONFIG_ZORRO) 1136#elif defined(CONFIG_ZORRO)
1197 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ 1137 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1198 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */ 1138 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1199#endif 1139#endif
1200 /* memory mode: chain4, ext. memory */
1201 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1202 /* plane mask: enable writing to all 4 planes */
1203 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1204 offset = var->xres_virtual / 4;
1205 } 1140 }
1206 1141
1207 /****************************************************** 1142 /******************************************************
1208 * 1143 *
1209 * 32 bpp 1144 * 24 bpp
1210 * 1145 *
1211 */ 1146 */
1212 1147
1213 else if (var->bits_per_pixel == 32) { 1148 else if (var->bits_per_pixel == 24) {
1214 DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); 1149 dev_dbg(info->device, "preparing for 24 bit deep display\n");
1215 switch (cinfo->btype) { 1150 switch (cinfo->btype) {
1216 case BT_SD64:
1217 /* Extended Sequencer Mode: 256c col. mode */
1218 vga_wseq(regbase, CL_SEQR7, 0xf9);
1219 /* MCLK select */
1220 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1221 break;
1222
1223 case BT_PICCOLO: 1151 case BT_PICCOLO:
1224 case BT_SPECTRUM: 1152 case BT_SPECTRUM:
1225 vga_wseq(regbase, CL_SEQR7, 0x85); 1153 vga_wseq(regbase, CL_SEQR7, 0x85);
1226 /* Fast Page-Mode writes */ 1154 /* Fast Page-Mode writes */
1227 vga_wseq(regbase, CL_SEQRF, 0xb0); 1155 vga_wseq(regbase, CL_SEQRF, 0xb0);
1228 /* MCLK select */
1229 vga_wseq(regbase, CL_SEQR1F, 0x22);
1230 break; 1156 break;
1231 1157
1232 case BT_PICASSO: 1158 case BT_PICASSO:
1233 vga_wseq(regbase, CL_SEQR7, 0x25); 1159 vga_wseq(regbase, CL_SEQR7, 0x25);
1234 /* Fast Page-Mode writes */ 1160 /* Fast Page-Mode writes */
1235 vga_wseq(regbase, CL_SEQRF, 0xb0); 1161 vga_wseq(regbase, CL_SEQRF, 0xb0);
1236 /* MCLK select */
1237 vga_wseq(regbase, CL_SEQR1F, 0x22);
1238 break; 1162 break;
1239 1163
1164 case BT_SD64:
1240 case BT_PICASSO4: 1165 case BT_PICASSO4:
1241 vga_wseq(regbase, CL_SEQR7, 0x25);
1242/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1243 break;
1244
1245 case BT_ALPINE: 1166 case BT_ALPINE:
1246 DPRINTK(" (for GD543x)\n"); 1167 /* Extended Sequencer Mode: 256c col. mode */
1247 vga_wseq(regbase, CL_SEQR7, 0xa9); 1168 vga_wseq(regbase, CL_SEQR7, 0xa5);
1248 break; 1169 break;
1249 1170
1250 case BT_GD5480: 1171 case BT_GD5480:
1251 DPRINTK(" (for GD5480)\n"); 1172 vga_wseq(regbase, CL_SEQR7, 0x15);
1252 vga_wseq(regbase, CL_SEQR7, 0x19);
1253 /* We already set SRF and SR1F */ 1173 /* We already set SRF and SR1F */
1254 break; 1174 break;
1255 1175
1256 case BT_LAGUNA: 1176 case BT_LAGUNA:
1257 DPRINTK(" (for GD546x)\n"); 1177 case BT_LAGUNAB:
1258 vga_wseq(regbase, CL_SEQR7, 1178 vga_wseq(regbase, CL_SEQR7,
1259 vga_rseq(regbase, CL_SEQR7) & ~0x01); 1179 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1180 control |= 0x4000;
1181 format |= 0x2400;
1182 threshold |= 0x20;
1260 break; 1183 break;
1261 1184
1262 default: 1185 default:
1263 printk(KERN_WARNING "cirrusfb: unknown Board\n"); 1186 dev_warn(info->device, "unknown Board\n");
1264 break; 1187 break;
1265 } 1188 }
1266 1189
1267 /* mode register: 256 color mode */ 1190 /* mode register: 256 color mode */
1268 vga_wgfx(regbase, VGA_GFX_MODE, 64); 1191 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1269 /* pixel mask: pass-through all planes */
1270 WGen(cinfo, VGA_PEL_MSK, 0xff);
1271 /* hidden dac reg: 8-8-8 mode (24 or 32) */ 1192 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1272 WHDR(cinfo, 0xc5); 1193 WHDR(cinfo, 0xc5);
1273 /* memory mode: chain4, ext. memory */
1274 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1275 /* plane mask: enable writing to all 4 planes */
1276 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1277 offset = var->xres_virtual / 4;
1278 } 1194 }
1279 1195
1280 /****************************************************** 1196 /******************************************************
@@ -1284,67 +1200,55 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1284 */ 1200 */
1285 1201
1286 else 1202 else
1287 printk(KERN_ERR "cirrusfb: What's this?? " 1203 dev_err(info->device,
1288 " requested color depth == %d.\n", 1204 "What's this? requested color depth == %d.\n",
1289 var->bits_per_pixel); 1205 var->bits_per_pixel);
1290 1206
1291 vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff); 1207 pitch = info->fix.line_length >> 3;
1208 vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1292 tmp = 0x22; 1209 tmp = 0x22;
1293 if (offset & 0x100) 1210 if (pitch & 0x100)
1294 tmp |= 0x10; /* offset overflow bit */ 1211 tmp |= 0x10; /* offset overflow bit */
1295 1212
1296 /* screen start addr #16-18, fastpagemode cycles */ 1213 /* screen start addr #16-18, fastpagemode cycles */
1297 vga_wcrt(regbase, CL_CRT1B, tmp); 1214 vga_wcrt(regbase, CL_CRT1B, tmp);
1298 1215
1299 if (cinfo->btype == BT_SD64 || 1216 /* screen start address bit 19 */
1300 cinfo->btype == BT_PICASSO4 || 1217 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1301 cinfo->btype == BT_ALPINE || 1218 vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1302 cinfo->btype == BT_GD5480) 1219
1303 /* screen start address bit 19 */ 1220 if (is_laguna(cinfo)) {
1304 vga_wcrt(regbase, CL_CRT1D, 0x00); 1221 tmp = 0;
1305 1222 if ((htotal + 5) & 256)
1306 /* text cursor location high */ 1223 tmp |= 128;
1307 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0); 1224 if (hdispend & 256)
1308 /* text cursor location low */ 1225 tmp |= 64;
1309 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0); 1226 if (hsyncstart & 256)
1310 /* underline row scanline = at very bottom */ 1227 tmp |= 48;
1311 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0); 1228 if (vtotal & 1024)
1312 1229 tmp |= 8;
1313 /* controller mode */ 1230 if (vdispend & 1024)
1314 vga_wattr(regbase, VGA_ATC_MODE, 1); 1231 tmp |= 4;
1315 /* overscan (border) color */ 1232 if (vsyncstart & 1024)
1316 vga_wattr(regbase, VGA_ATC_OVERSCAN, 0); 1233 tmp |= 3;
1317 /* color plane enable */ 1234
1318 vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15); 1235 vga_wcrt(regbase, CL_CRT1E, tmp);
1236 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1237 }
1238
1319 /* pixel panning */ 1239 /* pixel panning */
1320 vga_wattr(regbase, CL_AR33, 0); 1240 vga_wattr(regbase, CL_AR33, 0);
1321 /* color select */
1322 vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1323 1241
1324 /* [ EGS: SetOffset(); ] */ 1242 /* [ EGS: SetOffset(); ] */
1325 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ 1243 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1326 AttrOn(cinfo); 1244 AttrOn(cinfo);
1327 1245
1328 /* set/reset register */ 1246 if (is_laguna(cinfo)) {
1329 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0); 1247 /* no tiles */
1330 /* set/reset enable */ 1248 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1331 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0); 1249 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1332 /* color compare */ 1250 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1333 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0); 1251 }
1334 /* data rotate */
1335 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1336 /* read map select */
1337 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1338 /* miscellaneous register */
1339 vga_wgfx(regbase, VGA_GFX_MISC, 1);
1340 /* color don't care */
1341 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1342 /* bit mask */
1343 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1344
1345 /* graphics cursor attributes: nothing special */
1346 vga_wseq(regbase, CL_SEQR12, 0x0);
1347
1348 /* finally, turn on everything - turn off "FullBandwidth" bit */ 1252 /* finally, turn on everything - turn off "FullBandwidth" bit */
1349 /* also, set "DotClock%2" bit where requested */ 1253 /* also, set "DotClock%2" bit where requested */
1350 tmp = 0x01; 1254 tmp = 0x01;
@@ -1355,18 +1259,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
1355*/ 1259*/
1356 1260
1357 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp); 1261 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1358 DPRINTK("CL_SEQR1: %d\n", tmp); 1262 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1359
1360 cinfo->currentmode = regs;
1361
1362 /* pan to requested offset */
1363 cirrusfb_pan_display(var, info);
1364 1263
1365#ifdef CIRRUSFB_DEBUG 1264#ifdef CIRRUSFB_DEBUG
1366 cirrusfb_dump(); 1265 cirrusfb_dbg_reg_dump(info, NULL);
1367#endif 1266#endif
1368 1267
1369 DPRINTK("EXIT\n");
1370 return 0; 1268 return 0;
1371} 1269}
1372 1270
@@ -1418,27 +1316,19 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1418static int cirrusfb_pan_display(struct fb_var_screeninfo *var, 1316static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1419 struct fb_info *info) 1317 struct fb_info *info)
1420{ 1318{
1421 int xoffset = 0; 1319 int xoffset;
1422 int yoffset = 0;
1423 unsigned long base; 1320 unsigned long base;
1424 unsigned char tmp = 0, tmp2 = 0, xpix; 1321 unsigned char tmp, xpix;
1425 struct cirrusfb_info *cinfo = info->par; 1322 struct cirrusfb_info *cinfo = info->par;
1426 1323
1427 DPRINTK("ENTER\n");
1428 DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1429
1430 /* no range checks for xoffset and yoffset, */ 1324 /* no range checks for xoffset and yoffset, */
1431 /* as fb_pan_display has already done this */ 1325 /* as fb_pan_display has already done this */
1432 if (var->vmode & FB_VMODE_YWRAP) 1326 if (var->vmode & FB_VMODE_YWRAP)
1433 return -EINVAL; 1327 return -EINVAL;
1434 1328
1435 info->var.xoffset = var->xoffset;
1436 info->var.yoffset = var->yoffset;
1437
1438 xoffset = var->xoffset * info->var.bits_per_pixel / 8; 1329 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1439 yoffset = var->yoffset;
1440 1330
1441 base = yoffset * info->fix.line_length + xoffset; 1331 base = var->yoffset * info->fix.line_length + xoffset;
1442 1332
1443 if (info->var.bits_per_pixel == 1) { 1333 if (info->var.bits_per_pixel == 1) {
1444 /* base is already correct */ 1334 /* base is already correct */
@@ -1448,14 +1338,15 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1448 xpix = (unsigned char) ((xoffset % 4) * 2); 1338 xpix = (unsigned char) ((xoffset % 4) * 2);
1449 } 1339 }
1450 1340
1451 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ 1341 if (!is_laguna(cinfo))
1342 cirrusfb_WaitBLT(cinfo->regbase);
1452 1343
1453 /* lower 8 + 8 bits of screen start address */ 1344 /* lower 8 + 8 bits of screen start address */
1454 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 1345 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1455 (unsigned char) (base & 0xff)); 1346 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1456 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1457 (unsigned char) (base >> 8));
1458 1347
1348 /* 0xf2 is %11110010, exclude tmp bits */
1349 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1459 /* construct bits 16, 17 and 18 of screen start address */ 1350 /* construct bits 16, 17 and 18 of screen start address */
1460 if (base & 0x10000) 1351 if (base & 0x10000)
1461 tmp |= 0x01; 1352 tmp |= 0x01;
@@ -1464,13 +1355,17 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1464 if (base & 0x40000) 1355 if (base & 0x40000)
1465 tmp |= 0x08; 1356 tmp |= 0x08;
1466 1357
1467 /* 0xf2 is %11110010, exclude tmp bits */ 1358 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1468 tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
1469 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
1470 1359
1471 /* construct bit 19 of screen start address */ 1360 /* construct bit 19 of screen start address */
1472 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) 1361 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1473 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80); 1362 tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1363 if (is_laguna(cinfo))
1364 tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1365 else
1366 tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
1367 vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1368 }
1474 1369
1475 /* write pixel panning value to AR33; this does not quite work in 8bpp 1370 /* write pixel panning value to AR33; this does not quite work in 8bpp
1476 * 1371 *
@@ -1479,9 +1374,6 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1479 if (info->var.bits_per_pixel == 1) 1374 if (info->var.bits_per_pixel == 1)
1480 vga_wattr(cinfo->regbase, CL_AR33, xpix); 1375 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1481 1376
1482 cirrusfb_WaitBLT(cinfo->regbase);
1483
1484 DPRINTK("EXIT\n");
1485 return 0; 1377 return 0;
1486} 1378}
1487 1379
@@ -1502,57 +1394,54 @@ static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1502 struct cirrusfb_info *cinfo = info->par; 1394 struct cirrusfb_info *cinfo = info->par;
1503 int current_mode = cinfo->blank_mode; 1395 int current_mode = cinfo->blank_mode;
1504 1396
1505 DPRINTK("ENTER, blank mode = %d\n", blank_mode); 1397 dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1506 1398
1507 if (info->state != FBINFO_STATE_RUNNING || 1399 if (info->state != FBINFO_STATE_RUNNING ||
1508 current_mode == blank_mode) { 1400 current_mode == blank_mode) {
1509 DPRINTK("EXIT, returning 0\n"); 1401 dev_dbg(info->device, "EXIT, returning 0\n");
1510 return 0; 1402 return 0;
1511 } 1403 }
1512 1404
1513 /* Undo current */ 1405 /* Undo current */
1514 if (current_mode == FB_BLANK_NORMAL || 1406 if (current_mode == FB_BLANK_NORMAL ||
1515 current_mode == FB_BLANK_UNBLANK) { 1407 current_mode == FB_BLANK_UNBLANK)
1516 /* unblank the screen */
1517 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1518 /* clear "FullBandwidth" bit */ 1408 /* clear "FullBandwidth" bit */
1519 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); 1409 val = 0;
1520 /* and undo VESA suspend trickery */ 1410 else
1521 vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
1522 }
1523
1524 /* set new */
1525 if (blank_mode > FB_BLANK_NORMAL) {
1526 /* blank the screen */
1527 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1528 /* set "FullBandwidth" bit */ 1411 /* set "FullBandwidth" bit */
1529 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); 1412 val = 0x20;
1530 } 1413
1414 val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1415 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1531 1416
1532 switch (blank_mode) { 1417 switch (blank_mode) {
1533 case FB_BLANK_UNBLANK: 1418 case FB_BLANK_UNBLANK:
1534 case FB_BLANK_NORMAL: 1419 case FB_BLANK_NORMAL:
1420 val = 0x00;
1535 break; 1421 break;
1536 case FB_BLANK_VSYNC_SUSPEND: 1422 case FB_BLANK_VSYNC_SUSPEND:
1537 vga_wgfx(cinfo->regbase, CL_GRE, 0x04); 1423 val = 0x04;
1538 break; 1424 break;
1539 case FB_BLANK_HSYNC_SUSPEND: 1425 case FB_BLANK_HSYNC_SUSPEND:
1540 vga_wgfx(cinfo->regbase, CL_GRE, 0x02); 1426 val = 0x02;
1541 break; 1427 break;
1542 case FB_BLANK_POWERDOWN: 1428 case FB_BLANK_POWERDOWN:
1543 vga_wgfx(cinfo->regbase, CL_GRE, 0x06); 1429 val = 0x06;
1544 break; 1430 break;
1545 default: 1431 default:
1546 DPRINTK("EXIT, returning 1\n"); 1432 dev_dbg(info->device, "EXIT, returning 1\n");
1547 return 1; 1433 return 1;
1548 } 1434 }
1549 1435
1436 vga_wgfx(cinfo->regbase, CL_GRE, val);
1437
1550 cinfo->blank_mode = blank_mode; 1438 cinfo->blank_mode = blank_mode;
1551 DPRINTK("EXIT, returning 0\n"); 1439 dev_dbg(info->device, "EXIT, returning 0\n");
1552 1440
1553 /* Let fbcon do a soft blank for us */ 1441 /* Let fbcon do a soft blank for us */
1554 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1442 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1555} 1443}
1444
1556/**** END Hardware specific Routines **************************************/ 1445/**** END Hardware specific Routines **************************************/
1557/****************************************************************************/ 1446/****************************************************************************/
1558/**** BEGIN Internal Routines ***********************************************/ 1447/**** BEGIN Internal Routines ***********************************************/
@@ -1562,8 +1451,6 @@ static void init_vgachip(struct fb_info *info)
1562 struct cirrusfb_info *cinfo = info->par; 1451 struct cirrusfb_info *cinfo = info->par;
1563 const struct cirrusfb_board_info_rec *bi; 1452 const struct cirrusfb_board_info_rec *bi;
1564 1453
1565 DPRINTK("ENTER\n");
1566
1567 assert(cinfo != NULL); 1454 assert(cinfo != NULL);
1568 1455
1569 bi = &cirrusfb_board_info[cinfo->btype]; 1456 bi = &cirrusfb_board_info[cinfo->btype];
@@ -1591,25 +1478,23 @@ static void init_vgachip(struct fb_info *info)
1591 /* disable flickerfixer */ 1478 /* disable flickerfixer */
1592 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00); 1479 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1593 mdelay(100); 1480 mdelay(100);
1594 /* from Klaus' NetBSD driver: */
1595 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1596 /* put blitter into 542x compat */
1597 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1598 /* mode */ 1481 /* mode */
1599 vga_wgfx(cinfo->regbase, CL_GR31, 0x00); 1482 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1600 break; 1483 case BT_GD5480: /* fall through */
1601
1602 case BT_GD5480:
1603 /* from Klaus' NetBSD driver: */ 1484 /* from Klaus' NetBSD driver: */
1604 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00); 1485 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1486 case BT_ALPINE: /* fall through */
1487 /* put blitter into 542x compat */
1488 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1605 break; 1489 break;
1606 1490
1607 case BT_ALPINE: 1491 case BT_LAGUNA:
1492 case BT_LAGUNAB:
1608 /* Nothing to do to reset the board. */ 1493 /* Nothing to do to reset the board. */
1609 break; 1494 break;
1610 1495
1611 default: 1496 default:
1612 printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n"); 1497 dev_err(info->device, "Warning: Unknown board type\n");
1613 break; 1498 break;
1614 } 1499 }
1615 1500
@@ -1629,31 +1514,28 @@ static void init_vgachip(struct fb_info *info)
1629 WGen(cinfo, CL_VSSM2, 0x01); 1514 WGen(cinfo, CL_VSSM2, 0x01);
1630 1515
1631 /* reset sequencer logic */ 1516 /* reset sequencer logic */
1632 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03); 1517 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1633 1518
1634 /* FullBandwidth (video off) and 8/9 dot clock */ 1519 /* FullBandwidth (video off) and 8/9 dot clock */
1635 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); 1520 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1636 /* polarity (-/-), disable access to display memory,
1637 * VGA_CRTC_START_HI base address: color
1638 */
1639 WGen(cinfo, VGA_MIS_W, 0xc1);
1640 1521
1641 /* "magic cookie" - doesn't make any sense to me.. */ 1522 /* "magic cookie" - doesn't make any sense to me.. */
1642/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */ 1523/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1643 /* unlock all extension registers */ 1524 /* unlock all extension registers */
1644 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12); 1525 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1645 1526
1646 /* reset blitter */
1647 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1648
1649 switch (cinfo->btype) { 1527 switch (cinfo->btype) {
1650 case BT_GD5480: 1528 case BT_GD5480:
1651 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98); 1529 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1652 break; 1530 break;
1653 case BT_ALPINE: 1531 case BT_ALPINE:
1532 case BT_LAGUNA:
1533 case BT_LAGUNAB:
1654 break; 1534 break;
1655 case BT_SD64: 1535 case BT_SD64:
1536#ifdef CONFIG_ZORRO
1656 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8); 1537 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1538#endif
1657 break; 1539 break;
1658 default: 1540 default:
1659 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f); 1541 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
@@ -1665,8 +1547,8 @@ static void init_vgachip(struct fb_info *info)
1665 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); 1547 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1666 /* character map select: doesn't even matter in gx mode */ 1548 /* character map select: doesn't even matter in gx mode */
1667 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); 1549 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1668 /* memory mode: chain-4, no odd/even, ext. memory */ 1550 /* memory mode: chain4, ext. memory */
1669 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); 1551 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1670 1552
1671 /* controller-internal base address of video memory */ 1553 /* controller-internal base address of video memory */
1672 if (bi->init_sr07) 1554 if (bi->init_sr07)
@@ -1692,20 +1574,12 @@ static void init_vgachip(struct fb_info *info)
1692 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02); 1574 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1693 } 1575 }
1694 1576
1695 /* MCLK select etc. */
1696 if (bi->init_sr1f)
1697 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1698
1699 /* Screen A preset row scan: none */ 1577 /* Screen A preset row scan: none */
1700 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); 1578 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1701 /* Text cursor start: disable text cursor */ 1579 /* Text cursor start: disable text cursor */
1702 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); 1580 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1703 /* Text cursor end: - */ 1581 /* Text cursor end: - */
1704 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); 1582 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1705 /* Screen start address high: 0 */
1706 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1707 /* Screen start address low: 0 */
1708 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1709 /* text cursor location high: 0 */ 1583 /* text cursor location high: 0 */
1710 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); 1584 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1711 /* text cursor location low: 0 */ 1585 /* text cursor location low: 0 */
@@ -1713,10 +1587,6 @@ static void init_vgachip(struct fb_info *info)
1713 1587
1714 /* Underline Row scanline: - */ 1588 /* Underline Row scanline: - */
1715 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); 1589 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1716 /* mode control: timing enable, byte mode, no compat modes */
1717 vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1718 /* Line Compare: not needed */
1719 vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1720 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1590 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1721 /* ext. display controls: ext.adr. wrap */ 1591 /* ext. display controls: ext.adr. wrap */
1722 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02); 1592 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
@@ -1739,7 +1609,9 @@ static void init_vgachip(struct fb_info *info)
1739 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); 1609 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1740 /* Bit Mask: no mask at all */ 1610 /* Bit Mask: no mask at all */
1741 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); 1611 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1742 if (cinfo->btype == BT_ALPINE) 1612
1613 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1614 is_laguna(cinfo))
1743 /* (5434 can't have bit 3 set for bitblt) */ 1615 /* (5434 can't have bit 3 set for bitblt) */
1744 vga_wgfx(cinfo->regbase, CL_GRB, 0x20); 1616 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1745 else 1617 else
@@ -1779,18 +1651,11 @@ static void init_vgachip(struct fb_info *info)
1779 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); 1651 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1780 /* Color Plane enable: Enable all 4 planes */ 1652 /* Color Plane enable: Enable all 4 planes */
1781 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); 1653 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1782/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1783 /* Color Select: - */ 1654 /* Color Select: - */
1784 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); 1655 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1785 1656
1786 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1657 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1787 1658
1788 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1789 /* polarity (-/-), enable display mem,
1790 * VGA_CRTC_START_HI i/o base = color
1791 */
1792 WGen(cinfo, VGA_MIS_W, 0xc3);
1793
1794 /* BLT Start/status: Blitter reset */ 1659 /* BLT Start/status: Blitter reset */
1795 vga_wgfx(cinfo->regbase, CL_GR31, 0x04); 1660 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1796 /* - " - : "end-of-reset" */ 1661 /* - " - : "end-of-reset" */
@@ -1798,8 +1663,6 @@ static void init_vgachip(struct fb_info *info)
1798 1663
1799 /* misc... */ 1664 /* misc... */
1800 WHDR(cinfo, 0); /* Hidden DAC register: - */ 1665 WHDR(cinfo, 0); /* Hidden DAC register: - */
1801
1802 DPRINTK("EXIT\n");
1803 return; 1666 return;
1804} 1667}
1805 1668
@@ -1808,8 +1671,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1808#ifdef CONFIG_ZORRO /* only works on Zorro boards */ 1671#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1809 static int IsOn = 0; /* XXX not ok for multiple boards */ 1672 static int IsOn = 0; /* XXX not ok for multiple boards */
1810 1673
1811 DPRINTK("ENTER\n");
1812
1813 if (cinfo->btype == BT_PICASSO4) 1674 if (cinfo->btype == BT_PICASSO4)
1814 return; /* nothing to switch */ 1675 return; /* nothing to switch */
1815 if (cinfo->btype == BT_ALPINE) 1676 if (cinfo->btype == BT_ALPINE)
@@ -1819,8 +1680,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1819 if (cinfo->btype == BT_PICASSO) { 1680 if (cinfo->btype == BT_PICASSO) {
1820 if ((on && !IsOn) || (!on && IsOn)) 1681 if ((on && !IsOn) || (!on && IsOn))
1821 WSFR(cinfo, 0xff); 1682 WSFR(cinfo, 0xff);
1822
1823 DPRINTK("EXIT\n");
1824 return; 1683 return;
1825 } 1684 }
1826 if (on) { 1685 if (on) {
@@ -1847,11 +1706,10 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1847 case BT_SPECTRUM: 1706 case BT_SPECTRUM:
1848 WSFR(cinfo, 0x4f); 1707 WSFR(cinfo, 0x4f);
1849 break; 1708 break;
1850 default: /* do nothing */ break; 1709 default: /* do nothing */
1710 break;
1851 } 1711 }
1852 } 1712 }
1853
1854 DPRINTK("EXIT\n");
1855#endif /* CONFIG_ZORRO */ 1713#endif /* CONFIG_ZORRO */
1856} 1714}
1857 1715
@@ -1859,6 +1717,17 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1859/* Linux 2.6-style accelerated functions */ 1717/* Linux 2.6-style accelerated functions */
1860/******************************************/ 1718/******************************************/
1861 1719
1720static int cirrusfb_sync(struct fb_info *info)
1721{
1722 struct cirrusfb_info *cinfo = info->par;
1723
1724 if (!is_laguna(cinfo)) {
1725 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1726 cpu_relax();
1727 }
1728 return 0;
1729}
1730
1862static void cirrusfb_fillrect(struct fb_info *info, 1731static void cirrusfb_fillrect(struct fb_info *info,
1863 const struct fb_fillrect *region) 1732 const struct fb_fillrect *region)
1864{ 1733{
@@ -1894,8 +1763,8 @@ static void cirrusfb_fillrect(struct fb_info *info,
1894 info->var.bits_per_pixel, 1763 info->var.bits_per_pixel,
1895 (region->dx * m) / 8, region->dy, 1764 (region->dx * m) / 8, region->dy,
1896 (region->width * m) / 8, region->height, 1765 (region->width * m) / 8, region->height,
1897 color, 1766 color, color,
1898 info->fix.line_length); 1767 info->fix.line_length, 0x40);
1899} 1768}
1900 1769
1901static void cirrusfb_copyarea(struct fb_info *info, 1770static void cirrusfb_copyarea(struct fb_info *info,
@@ -1943,9 +1812,46 @@ static void cirrusfb_imageblit(struct fb_info *info,
1943 const struct fb_image *image) 1812 const struct fb_image *image)
1944{ 1813{
1945 struct cirrusfb_info *cinfo = info->par; 1814 struct cirrusfb_info *cinfo = info->par;
1815 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1946 1816
1947 cirrusfb_WaitBLT(cinfo->regbase); 1817 if (info->state != FBINFO_STATE_RUNNING)
1948 cfb_imageblit(info, image); 1818 return;
1819 /* Alpine/SD64 does not work at 24bpp ??? */
1820 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1821 cfb_imageblit(info, image);
1822 else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1823 op == 0xc)
1824 cfb_imageblit(info, image);
1825 else {
1826 unsigned size = ((image->width + 7) >> 3) * image->height;
1827 int m = info->var.bits_per_pixel;
1828 u32 fg, bg;
1829
1830 if (info->var.bits_per_pixel == 8) {
1831 fg = image->fg_color;
1832 bg = image->bg_color;
1833 } else {
1834 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1835 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1836 }
1837 if (info->var.bits_per_pixel == 24) {
1838 /* clear background first */
1839 cirrusfb_RectFill(cinfo->regbase,
1840 info->var.bits_per_pixel,
1841 (image->dx * m) / 8, image->dy,
1842 (image->width * m) / 8,
1843 image->height,
1844 bg, bg,
1845 info->fix.line_length, 0x40);
1846 }
1847 cirrusfb_RectFill(cinfo->regbase,
1848 info->var.bits_per_pixel,
1849 (image->dx * m) / 8, image->dy,
1850 (image->width * m) / 8, image->height,
1851 fg, bg,
1852 info->fix.line_length, op);
1853 memcpy(info->screen_base, image->data, size);
1854 }
1949} 1855}
1950 1856
1951#ifdef CONFIG_PPC_PREP 1857#ifdef CONFIG_PPC_PREP
@@ -1953,12 +1859,8 @@ static void cirrusfb_imageblit(struct fb_info *info,
1953#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) 1859#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
1954static void get_prep_addrs(unsigned long *display, unsigned long *registers) 1860static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1955{ 1861{
1956 DPRINTK("ENTER\n");
1957
1958 *display = PREP_VIDEO_BASE; 1862 *display = PREP_VIDEO_BASE;
1959 *registers = (unsigned long) PREP_IO_BASE; 1863 *registers = (unsigned long) PREP_IO_BASE;
1960
1961 DPRINTK("EXIT\n");
1962} 1864}
1963 1865
1964#endif /* CONFIG_PPC_PREP */ 1866#endif /* CONFIG_PPC_PREP */
@@ -1970,40 +1872,43 @@ static int release_io_ports;
1970 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 1872 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
1971 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 1873 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1972 * seem to have. */ 1874 * seem to have. */
1973static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase) 1875static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1876 u8 __iomem *regbase)
1974{ 1877{
1975 unsigned long mem; 1878 unsigned long mem;
1976 unsigned char SRF; 1879 struct cirrusfb_info *cinfo = info->par;
1977 1880
1978 DPRINTK("ENTER\n"); 1881 if (is_laguna(cinfo)) {
1882 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1979 1883
1980 SRF = vga_rseq(regbase, CL_SEQRF); 1884 mem = ((SR14 & 7) + 1) << 20;
1981 switch ((SRF & 0x18)) { 1885 } else {
1982 case 0x08: 1886 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1983 mem = 512 * 1024; 1887 switch ((SRF & 0x18)) {
1984 break; 1888 case 0x08:
1985 case 0x10: 1889 mem = 512 * 1024;
1986 mem = 1024 * 1024; 1890 break;
1987 break; 1891 case 0x10:
1988 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory 1892 mem = 1024 * 1024;
1989 * on the 5430. 1893 break;
1990 */ 1894 /* 64-bit DRAM data bus width; assume 2MB.
1991 case 0x18: 1895 * Also indicates 2MB memory on the 5430.
1992 mem = 2048 * 1024; 1896 */
1993 break; 1897 case 0x18:
1994 default: 1898 mem = 2048 * 1024;
1995 printk(KERN_WARNING "CLgenfb: Unknown memory size!\n"); 1899 break;
1996 mem = 1024 * 1024; 1900 default:
1901 dev_warn(info->device, "Unknown memory size!\n");
1902 mem = 1024 * 1024;
1903 }
1904 /* If DRAM bank switching is enabled, there must be
1905 * twice as much memory installed. (4MB on the 5434)
1906 */
1907 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1908 mem *= 2;
1997 } 1909 }
1998 if (SRF & 0x80)
1999 /* If DRAM bank switching is enabled, there must be twice as much
2000 * memory installed. (4MB on the 5434)
2001 */
2002 mem *= 2;
2003 1910
2004 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ 1911 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2005
2006 DPRINTK("EXIT\n");
2007 return mem; 1912 return mem;
2008} 1913}
2009 1914
@@ -2014,8 +1919,6 @@ static void get_pci_addrs(const struct pci_dev *pdev,
2014 assert(display != NULL); 1919 assert(display != NULL);
2015 assert(registers != NULL); 1920 assert(registers != NULL);
2016 1921
2017 DPRINTK("ENTER\n");
2018
2019 *display = 0; 1922 *display = 0;
2020 *registers = 0; 1923 *registers = 0;
2021 1924
@@ -2030,14 +1933,15 @@ static void get_pci_addrs(const struct pci_dev *pdev,
2030 } 1933 }
2031 1934
2032 assert(*display != 0); 1935 assert(*display != 0);
2033
2034 DPRINTK("EXIT\n");
2035} 1936}
2036 1937
2037static void cirrusfb_pci_unmap(struct fb_info *info) 1938static void cirrusfb_pci_unmap(struct fb_info *info)
2038{ 1939{
2039 struct pci_dev *pdev = to_pci_dev(info->device); 1940 struct pci_dev *pdev = to_pci_dev(info->device);
1941 struct cirrusfb_info *cinfo = info->par;
2040 1942
1943 if (cinfo->laguna_mmio == NULL)
1944 iounmap(cinfo->laguna_mmio);
2041 iounmap(info->screen_base); 1945 iounmap(info->screen_base);
2042#if 0 /* if system didn't claim this region, we would... */ 1946#if 0 /* if system didn't claim this region, we would... */
2043 release_mem_region(0xA0000, 65535); 1947 release_mem_region(0xA0000, 65535);
@@ -2067,6 +1971,22 @@ static void cirrusfb_zorro_unmap(struct fb_info *info)
2067} 1971}
2068#endif /* CONFIG_ZORRO */ 1972#endif /* CONFIG_ZORRO */
2069 1973
1974/* function table of the above functions */
1975static struct fb_ops cirrusfb_ops = {
1976 .owner = THIS_MODULE,
1977 .fb_open = cirrusfb_open,
1978 .fb_release = cirrusfb_release,
1979 .fb_setcolreg = cirrusfb_setcolreg,
1980 .fb_check_var = cirrusfb_check_var,
1981 .fb_set_par = cirrusfb_set_par,
1982 .fb_pan_display = cirrusfb_pan_display,
1983 .fb_blank = cirrusfb_blank,
1984 .fb_fillrect = cirrusfb_fillrect,
1985 .fb_copyarea = cirrusfb_copyarea,
1986 .fb_sync = cirrusfb_sync,
1987 .fb_imageblit = cirrusfb_imageblit,
1988};
1989
2070static int __devinit cirrusfb_set_fbinfo(struct fb_info *info) 1990static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2071{ 1991{
2072 struct cirrusfb_info *cinfo = info->par; 1992 struct cirrusfb_info *cinfo = info->par;
@@ -2077,10 +1997,16 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2077 | FBINFO_HWACCEL_XPAN 1997 | FBINFO_HWACCEL_XPAN
2078 | FBINFO_HWACCEL_YPAN 1998 | FBINFO_HWACCEL_YPAN
2079 | FBINFO_HWACCEL_FILLRECT 1999 | FBINFO_HWACCEL_FILLRECT
2000 | FBINFO_HWACCEL_IMAGEBLIT
2080 | FBINFO_HWACCEL_COPYAREA; 2001 | FBINFO_HWACCEL_COPYAREA;
2081 if (noaccel) 2002 if (noaccel || is_laguna(cinfo)) {
2082 info->flags |= FBINFO_HWACCEL_DISABLED; 2003 info->flags |= FBINFO_HWACCEL_DISABLED;
2004 info->fix.accel = FB_ACCEL_NONE;
2005 } else
2006 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
2007
2083 info->fbops = &cirrusfb_ops; 2008 info->fbops = &cirrusfb_ops;
2009
2084 if (cinfo->btype == BT_GD5480) { 2010 if (cinfo->btype == BT_GD5480) {
2085 if (var->bits_per_pixel == 16) 2011 if (var->bits_per_pixel == 16)
2086 info->screen_base += 1 * MB_; 2012 info->screen_base += 1 * MB_;
@@ -2104,7 +2030,6 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2104 2030
2105 /* FIXME: map region at 0xB8000 if available, fill in here */ 2031 /* FIXME: map region at 0xB8000 if available, fill in here */
2106 info->fix.mmio_len = 0; 2032 info->fix.mmio_len = 0;
2107 info->fix.accel = FB_ACCEL_NONE;
2108 2033
2109 fb_alloc_cmap(&info->cmap, 256, 0); 2034 fb_alloc_cmap(&info->cmap, 256, 0);
2110 2035
@@ -2115,70 +2040,56 @@ static int __devinit cirrusfb_register(struct fb_info *info)
2115{ 2040{
2116 struct cirrusfb_info *cinfo = info->par; 2041 struct cirrusfb_info *cinfo = info->par;
2117 int err; 2042 int err;
2118 enum cirrus_board btype;
2119
2120 DPRINTK("ENTER\n");
2121
2122 printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
2123 "graphic boards, v" CIRRUSFB_VERSION "\n");
2124
2125 btype = cinfo->btype;
2126 2043
2127 /* sanity checks */ 2044 /* sanity checks */
2128 assert(btype != BT_NONE); 2045 assert(cinfo->btype != BT_NONE);
2129 2046
2130 /* set all the vital stuff */ 2047 /* set all the vital stuff */
2131 cirrusfb_set_fbinfo(info); 2048 cirrusfb_set_fbinfo(info);
2132 2049
2133 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); 2050 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2134 2051
2135 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 2052 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2136 if (!err) { 2053 if (!err) {
2137 DPRINTK("wrong initial video mode\n"); 2054 dev_dbg(info->device, "wrong initial video mode\n");
2138 err = -EINVAL; 2055 err = -EINVAL;
2139 goto err_dealloc_cmap; 2056 goto err_dealloc_cmap;
2140 } 2057 }
2141 2058
2142 info->var.activate = FB_ACTIVATE_NOW; 2059 info->var.activate = FB_ACTIVATE_NOW;
2143 2060
2144 err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); 2061 err = cirrusfb_check_var(&info->var, info);
2145 if (err < 0) { 2062 if (err < 0) {
2146 /* should never happen */ 2063 /* should never happen */
2147 DPRINTK("choking on default var... umm, no good.\n"); 2064 dev_dbg(info->device,
2065 "choking on default var... umm, no good.\n");
2148 goto err_dealloc_cmap; 2066 goto err_dealloc_cmap;
2149 } 2067 }
2150 2068
2151 err = register_framebuffer(info); 2069 err = register_framebuffer(info);
2152 if (err < 0) { 2070 if (err < 0) {
2153 printk(KERN_ERR "cirrusfb: could not register " 2071 dev_err(info->device,
2154 "fb device; err = %d!\n", err); 2072 "could not register fb device; err = %d!\n", err);
2155 goto err_dealloc_cmap; 2073 goto err_dealloc_cmap;
2156 } 2074 }
2157 2075
2158 DPRINTK("EXIT, returning 0\n");
2159 return 0; 2076 return 0;
2160 2077
2161err_dealloc_cmap: 2078err_dealloc_cmap:
2162 fb_dealloc_cmap(&info->cmap); 2079 fb_dealloc_cmap(&info->cmap);
2163 cinfo->unmap(info);
2164 framebuffer_release(info);
2165 return err; 2080 return err;
2166} 2081}
2167 2082
2168static void __devexit cirrusfb_cleanup(struct fb_info *info) 2083static void __devexit cirrusfb_cleanup(struct fb_info *info)
2169{ 2084{
2170 struct cirrusfb_info *cinfo = info->par; 2085 struct cirrusfb_info *cinfo = info->par;
2171 DPRINTK("ENTER\n");
2172 2086
2173 switch_monitor(cinfo, 0); 2087 switch_monitor(cinfo, 0);
2174
2175 unregister_framebuffer(info); 2088 unregister_framebuffer(info);
2176 fb_dealloc_cmap(&info->cmap); 2089 fb_dealloc_cmap(&info->cmap);
2177 printk("Framebuffer unregistered\n"); 2090 dev_dbg(info->device, "Framebuffer unregistered\n");
2178 cinfo->unmap(info); 2091 cinfo->unmap(info);
2179 framebuffer_release(info); 2092 framebuffer_release(info);
2180
2181 DPRINTK("EXIT\n");
2182} 2093}
2183 2094
2184#ifdef CONFIG_PCI 2095#ifdef CONFIG_PCI
@@ -2187,7 +2098,6 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2187{ 2098{
2188 struct cirrusfb_info *cinfo; 2099 struct cirrusfb_info *cinfo;
2189 struct fb_info *info; 2100 struct fb_info *info;
2190 enum cirrus_board btype;
2191 unsigned long board_addr, board_size; 2101 unsigned long board_addr, board_size;
2192 int ret; 2102 int ret;
2193 2103
@@ -2201,15 +2111,17 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2201 if (!info) { 2111 if (!info) {
2202 printk(KERN_ERR "cirrusfb: could not allocate memory\n"); 2112 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2203 ret = -ENOMEM; 2113 ret = -ENOMEM;
2204 goto err_disable; 2114 goto err_out;
2205 } 2115 }
2206 2116
2207 cinfo = info->par; 2117 cinfo = info->par;
2208 cinfo->btype = btype = (enum cirrus_board) ent->driver_data; 2118 cinfo->btype = (enum cirrus_board) ent->driver_data;
2209 2119
2210 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", 2120 dev_dbg(info->device,
2211 pdev->resource[0].start, btype); 2121 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2212 DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start); 2122 (unsigned long long)pdev->resource[0].start, cinfo->btype);
2123 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2124 (unsigned long long)pdev->resource[1].start);
2213 2125
2214 if (isPReP) { 2126 if (isPReP) {
2215 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000); 2127 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
@@ -2219,30 +2131,30 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2219 /* PReP dies if we ioremap the IO registers, but it works w/out... */ 2131 /* PReP dies if we ioremap the IO registers, but it works w/out... */
2220 cinfo->regbase = (char __iomem *) info->fix.mmio_start; 2132 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2221 } else { 2133 } else {
2222 DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n"); 2134 dev_dbg(info->device,
2135 "Attempt to get PCI info for Cirrus Graphics Card\n");
2223 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start); 2136 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2224 /* FIXME: this forces VGA. alternatives? */ 2137 /* FIXME: this forces VGA. alternatives? */
2225 cinfo->regbase = NULL; 2138 cinfo->regbase = NULL;
2139 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2226 } 2140 }
2227 2141
2228 DPRINTK("Board address: 0x%lx, register address: 0x%lx\n", 2142 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2229 board_addr, info->fix.mmio_start); 2143 board_addr, info->fix.mmio_start);
2230 2144
2231 board_size = (btype == BT_GD5480) ? 2145 board_size = (cinfo->btype == BT_GD5480) ?
2232 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase); 2146 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2233 2147
2234 ret = pci_request_regions(pdev, "cirrusfb"); 2148 ret = pci_request_regions(pdev, "cirrusfb");
2235 if (ret < 0) { 2149 if (ret < 0) {
2236 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " 2150 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2237 "abort\n", 2151 board_addr);
2238 board_addr);
2239 goto err_release_fb; 2152 goto err_release_fb;
2240 } 2153 }
2241#if 0 /* if the system didn't claim this region, we would... */ 2154#if 0 /* if the system didn't claim this region, we would... */
2242 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) { 2155 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2243 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n" 2156 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2244, 2157 0xA0000L);
2245 0xA0000L);
2246 ret = -EBUSY; 2158 ret = -EBUSY;
2247 goto err_release_regions; 2159 goto err_release_regions;
2248 } 2160 }
@@ -2260,16 +2172,17 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2260 info->screen_size = board_size; 2172 info->screen_size = board_size;
2261 cinfo->unmap = cirrusfb_pci_unmap; 2173 cinfo->unmap = cirrusfb_pci_unmap;
2262 2174
2263 printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " 2175 dev_info(info->device,
2264 "Logic chipset on PCI bus\n", 2176 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2265 info->screen_size >> 10, board_addr); 2177 info->screen_size >> 10, board_addr);
2266 pci_set_drvdata(pdev, info); 2178 pci_set_drvdata(pdev, info);
2267 2179
2268 ret = cirrusfb_register(info); 2180 ret = cirrusfb_register(info);
2269 if (ret) 2181 if (!ret)
2270 iounmap(info->screen_base); 2182 return 0;
2271 return ret;
2272 2183
2184 pci_set_drvdata(pdev, NULL);
2185 iounmap(info->screen_base);
2273err_release_legacy: 2186err_release_legacy:
2274 if (release_io_ports) 2187 if (release_io_ports)
2275 release_region(0x3C0, 32); 2188 release_region(0x3C0, 32);
@@ -2279,8 +2192,9 @@ err_release_regions:
2279#endif 2192#endif
2280 pci_release_regions(pdev); 2193 pci_release_regions(pdev);
2281err_release_fb: 2194err_release_fb:
2195 if (cinfo->laguna_mmio != NULL)
2196 iounmap(cinfo->laguna_mmio);
2282 framebuffer_release(info); 2197 framebuffer_release(info);
2283err_disable:
2284err_out: 2198err_out:
2285 return ret; 2199 return ret;
2286} 2200}
@@ -2288,11 +2202,8 @@ err_out:
2288static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev) 2202static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2289{ 2203{
2290 struct fb_info *info = pci_get_drvdata(pdev); 2204 struct fb_info *info = pci_get_drvdata(pdev);
2291 DPRINTK("ENTER\n");
2292 2205
2293 cirrusfb_cleanup(info); 2206 cirrusfb_cleanup(info);
2294
2295 DPRINTK("EXIT\n");
2296} 2207}
2297 2208
2298static struct pci_driver cirrusfb_pci_driver = { 2209static struct pci_driver cirrusfb_pci_driver = {
@@ -2324,8 +2235,6 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2324 if (cirrusfb_zorro_table2[btype].id2) 2235 if (cirrusfb_zorro_table2[btype].id2)
2325 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL); 2236 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2326 size = cirrusfb_zorro_table2[btype].size; 2237 size = cirrusfb_zorro_table2[btype].size;
2327 printk(KERN_INFO "cirrusfb: %s board detected; ",
2328 cirrusfb_board_info[btype].name);
2329 2238
2330 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2239 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2331 if (!info) { 2240 if (!info) {
@@ -2334,6 +2243,9 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2334 goto err_out; 2243 goto err_out;
2335 } 2244 }
2336 2245
2246 dev_info(info->device, "%s board detected\n",
2247 cirrusfb_board_info[btype].name);
2248
2337 cinfo = info->par; 2249 cinfo = info->par;
2338 cinfo->btype = btype; 2250 cinfo->btype = btype;
2339 2251
@@ -2345,19 +2257,16 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2345 info->screen_size = size; 2257 info->screen_size = size;
2346 2258
2347 if (!zorro_request_device(z, "cirrusfb")) { 2259 if (!zorro_request_device(z, "cirrusfb")) {
2348 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, " 2260 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2349 "abort\n", 2261 board_addr);
2350 board_addr);
2351 ret = -EBUSY; 2262 ret = -EBUSY;
2352 goto err_release_fb; 2263 goto err_release_fb;
2353 } 2264 }
2354 2265
2355 printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
2356
2357 ret = -EIO; 2266 ret = -EIO;
2358 2267
2359 if (btype == BT_PICASSO4) { 2268 if (btype == BT_PICASSO4) {
2360 printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000); 2269 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2361 2270
2362 /* To be precise, for the P4 this is not the */ 2271 /* To be precise, for the P4 this is not the */
2363 /* begin of the board, but the begin of RAM. */ 2272 /* begin of the board, but the begin of RAM. */
@@ -2367,7 +2276,7 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2367 if (!cinfo->regbase) 2276 if (!cinfo->regbase)
2368 goto err_release_region; 2277 goto err_release_region;
2369 2278
2370 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", 2279 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2371 cinfo->regbase); 2280 cinfo->regbase);
2372 cinfo->regbase += 0x600000; 2281 cinfo->regbase += 0x600000;
2373 info->fix.mmio_start = board_addr + 0x600000; 2282 info->fix.mmio_start = board_addr + 0x600000;
@@ -2377,8 +2286,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2377 if (!info->screen_base) 2286 if (!info->screen_base)
2378 goto err_unmap_regbase; 2287 goto err_unmap_regbase;
2379 } else { 2288 } else {
2380 printk(KERN_INFO " REG at $%lx\n", 2289 dev_info(info->device, " REG at $%lx\n",
2381 (unsigned long) z2->resource.start); 2290 (unsigned long) z2->resource.start);
2382 2291
2383 info->fix.smem_start = board_addr; 2292 info->fix.smem_start = board_addr;
2384 if (board_addr > 0x01000000) 2293 if (board_addr > 0x01000000)
@@ -2392,27 +2301,32 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2392 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start); 2301 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2393 info->fix.mmio_start = z2->resource.start; 2302 info->fix.mmio_start = z2->resource.start;
2394 2303
2395 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n", 2304 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2396 cinfo->regbase); 2305 cinfo->regbase);
2397 } 2306 }
2398 cinfo->unmap = cirrusfb_zorro_unmap; 2307 cinfo->unmap = cirrusfb_zorro_unmap;
2399 2308
2400 printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); 2309 dev_info(info->device,
2310 "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2311 board_size / MB_, board_addr);
2312
2401 zorro_set_drvdata(z, info); 2313 zorro_set_drvdata(z, info);
2402 2314
2315 /* MCLK select etc. */
2316 if (cirrusfb_board_info[btype].init_sr1f)
2317 vga_wseq(cinfo->regbase, CL_SEQR1F,
2318 cirrusfb_board_info[btype].sr1f);
2319
2403 ret = cirrusfb_register(info); 2320 ret = cirrusfb_register(info);
2404 if (ret) { 2321 if (!ret)
2405 if (btype == BT_PICASSO4) { 2322 return 0;
2406 iounmap(info->screen_base); 2323
2407 iounmap(cinfo->regbase - 0x600000); 2324 if (btype == BT_PICASSO4 || board_addr > 0x01000000)
2408 } else if (board_addr > 0x01000000) 2325 iounmap(info->screen_base);
2409 iounmap(info->screen_base);
2410 }
2411 return ret;
2412 2326
2413err_unmap_regbase: 2327err_unmap_regbase:
2414 /* Parental advisory: explicit hack */ 2328 if (btype == BT_PICASSO4)
2415 iounmap(cinfo->regbase - 0x600000); 2329 iounmap(cinfo->regbase - 0x600000);
2416err_release_region: 2330err_release_region:
2417 release_region(board_addr, board_size); 2331 release_region(board_addr, board_size);
2418err_release_fb: 2332err_release_fb:
@@ -2424,11 +2338,8 @@ err_out:
2424void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) 2338void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2425{ 2339{
2426 struct fb_info *info = zorro_get_drvdata(z); 2340 struct fb_info *info = zorro_get_drvdata(z);
2427 DPRINTK("ENTER\n");
2428 2341
2429 cirrusfb_cleanup(info); 2342 cirrusfb_cleanup(info);
2430
2431 DPRINTK("EXIT\n");
2432} 2343}
2433 2344
2434static struct zorro_driver cirrusfb_zorro_driver = { 2345static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2439,33 +2350,11 @@ static struct zorro_driver cirrusfb_zorro_driver = {
2439}; 2350};
2440#endif /* CONFIG_ZORRO */ 2351#endif /* CONFIG_ZORRO */
2441 2352
2442static int __init cirrusfb_init(void)
2443{
2444 int error = 0;
2445
2446#ifndef MODULE 2353#ifndef MODULE
2447 char *option = NULL; 2354static int __init cirrusfb_setup(char *options)
2448 2355{
2449 if (fb_get_options("cirrusfb", &option))
2450 return -ENODEV;
2451 cirrusfb_setup(option);
2452#endif
2453
2454#ifdef CONFIG_ZORRO
2455 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2456#endif
2457#ifdef CONFIG_PCI
2458 error |= pci_register_driver(&cirrusfb_pci_driver);
2459#endif
2460 return error;
2461}
2462
2463#ifndef MODULE
2464static int __init cirrusfb_setup(char *options) {
2465 char *this_opt; 2356 char *this_opt;
2466 2357
2467 DPRINTK("ENTER\n");
2468
2469 if (!options || !*options) 2358 if (!options || !*options)
2470 return 0; 2359 return 0;
2471 2360
@@ -2473,8 +2362,6 @@ static int __init cirrusfb_setup(char *options) {
2473 if (!*this_opt) 2362 if (!*this_opt)
2474 continue; 2363 continue;
2475 2364
2476 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2477
2478 if (!strcmp(this_opt, "noaccel")) 2365 if (!strcmp(this_opt, "noaccel"))
2479 noaccel = 1; 2366 noaccel = 1;
2480 else if (!strncmp(this_opt, "mode:", 5)) 2367 else if (!strncmp(this_opt, "mode:", 5))
@@ -2494,6 +2381,27 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2494MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2381MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2495MODULE_LICENSE("GPL"); 2382MODULE_LICENSE("GPL");
2496 2383
2384static int __init cirrusfb_init(void)
2385{
2386 int error = 0;
2387
2388#ifndef MODULE
2389 char *option = NULL;
2390
2391 if (fb_get_options("cirrusfb", &option))
2392 return -ENODEV;
2393 cirrusfb_setup(option);
2394#endif
2395
2396#ifdef CONFIG_ZORRO
2397 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2398#endif
2399#ifdef CONFIG_PCI
2400 error |= pci_register_driver(&cirrusfb_pci_driver);
2401#endif
2402 return error;
2403}
2404
2497static void __exit cirrusfb_exit(void) 2405static void __exit cirrusfb_exit(void)
2498{ 2406{
2499#ifdef CONFIG_PCI 2407#ifdef CONFIG_PCI
@@ -2560,8 +2468,6 @@ static void AttrOn(const struct cirrusfb_info *cinfo)
2560{ 2468{
2561 assert(cinfo != NULL); 2469 assert(cinfo != NULL);
2562 2470
2563 DPRINTK("ENTER\n");
2564
2565 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) { 2471 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2566 /* if we're just in "write value" mode, write back the */ 2472 /* if we're just in "write value" mode, write back the */
2567 /* same value as before to not modify anything */ 2473 /* same value as before to not modify anything */
@@ -2574,8 +2480,6 @@ static void AttrOn(const struct cirrusfb_info *cinfo)
2574 2480
2575 /* dummy write on Reg0 to be on "write index" mode next time */ 2481 /* dummy write on Reg0 to be on "write index" mode next time */
2576 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00); 2482 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2577
2578 DPRINTK("EXIT\n");
2579} 2483}
2580 2484
2581/*** WHDR() - write into the Hidden DAC register ***/ 2485/*** WHDR() - write into the Hidden DAC register ***/
@@ -2588,6 +2492,8 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2588{ 2492{
2589 unsigned char dummy; 2493 unsigned char dummy;
2590 2494
2495 if (is_laguna(cinfo))
2496 return;
2591 if (cinfo->btype == BT_PICASSO) { 2497 if (cinfo->btype == BT_PICASSO) {
2592 /* Klaus' hint for correct access to HDR on some boards */ 2498 /* Klaus' hint for correct access to HDR on some boards */
2593 /* first write 0 to pixel mask (3c6) */ 2499 /* first write 0 to pixel mask (3c6) */
@@ -2655,7 +2561,8 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch
2655 vga_w(cinfo->regbase, VGA_PEL_IW, regnum); 2561 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2656 2562
2657 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2563 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2658 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2564 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2565 cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2659 /* but DAC data register IS, at least for Picasso II */ 2566 /* but DAC data register IS, at least for Picasso II */
2660 if (cinfo->btype == BT_PICASSO) 2567 if (cinfo->btype == BT_PICASSO)
2661 data += 0xfff; 2568 data += 0xfff;
@@ -2702,9 +2609,8 @@ static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch
2702/* FIXME: use interrupts instead */ 2609/* FIXME: use interrupts instead */
2703static void cirrusfb_WaitBLT(u8 __iomem *regbase) 2610static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2704{ 2611{
2705 /* now busy-wait until we're done */
2706 while (vga_rgfx(regbase, CL_GR31) & 0x08) 2612 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2707 /* do nothing */ ; 2613 cpu_relax();
2708} 2614}
2709 2615
2710/******************************************************************* 2616/*******************************************************************
@@ -2713,60 +2619,12 @@ static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2713 perform accelerated "scrolling" 2619 perform accelerated "scrolling"
2714********************************************************************/ 2620********************************************************************/
2715 2621
2716static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel, 2622static void cirrusfb_set_blitter(u8 __iomem *regbase,
2717 u_short curx, u_short cury, 2623 u_short nwidth, u_short nheight,
2718 u_short destx, u_short desty, 2624 u_long nsrc, u_long ndest,
2719 u_short width, u_short height, 2625 u_short bltmode, u_short line_length)
2720 u_short line_length)
2721{
2722 u_short nwidth, nheight;
2723 u_long nsrc, ndest;
2724 u_char bltmode;
2725
2726 DPRINTK("ENTER\n");
2727
2728 nwidth = width - 1;
2729 nheight = height - 1;
2730
2731 bltmode = 0x00;
2732 /* if source adr < dest addr, do the Blt backwards */
2733 if (cury <= desty) {
2734 if (cury == desty) {
2735 /* if src and dest are on the same line, check x */
2736 if (curx < destx)
2737 bltmode |= 0x01;
2738 } else
2739 bltmode |= 0x01;
2740 }
2741 if (!bltmode) {
2742 /* standard case: forward blitting */
2743 nsrc = (cury * line_length) + curx;
2744 ndest = (desty * line_length) + destx;
2745 } else {
2746 /* this means start addresses are at the end,
2747 * counting backwards
2748 */
2749 nsrc = cury * line_length + curx +
2750 nheight * line_length + nwidth;
2751 ndest = desty * line_length + destx +
2752 nheight * line_length + nwidth;
2753 }
2754
2755 /*
2756 run-down of registers to be programmed:
2757 destination pitch
2758 source pitch
2759 BLT width/height
2760 source start
2761 destination start
2762 BLT mode
2763 BLT ROP
2764 VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
2765 start/stop
2766 */
2767
2768 cirrusfb_WaitBLT(regbase);
2769 2626
2627{
2770 /* pitch: set to line_length */ 2628 /* pitch: set to line_length */
2771 /* dest pitch low */ 2629 /* dest pitch low */
2772 vga_wgfx(regbase, CL_GR24, line_length & 0xff); 2630 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
@@ -2813,91 +2671,91 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2813 2671
2814 /* and finally: GO! */ 2672 /* and finally: GO! */
2815 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */ 2673 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2816
2817 DPRINTK("EXIT\n");
2818} 2674}
2819 2675
2820/******************************************************************* 2676/*******************************************************************
2821 cirrusfb_RectFill() 2677 cirrusfb_BitBLT()
2822 2678
2823 perform accelerated rectangle fill 2679 perform accelerated "scrolling"
2824********************************************************************/ 2680********************************************************************/
2825 2681
2826static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel, 2682static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2827 u_short x, u_short y, u_short width, u_short height, 2683 u_short curx, u_short cury,
2828 u_char color, u_short line_length) 2684 u_short destx, u_short desty,
2685 u_short width, u_short height,
2686 u_short line_length)
2829{ 2687{
2830 u_short nwidth, nheight; 2688 u_short nwidth = width - 1;
2831 u_long ndest; 2689 u_short nheight = height - 1;
2832 u_char op; 2690 u_long nsrc, ndest;
2833 2691 u_char bltmode;
2834 DPRINTK("ENTER\n");
2835
2836 nwidth = width - 1;
2837 nheight = height - 1;
2838 2692
2839 ndest = (y * line_length) + x; 2693 bltmode = 0x00;
2694 /* if source adr < dest addr, do the Blt backwards */
2695 if (cury <= desty) {
2696 if (cury == desty) {
2697 /* if src and dest are on the same line, check x */
2698 if (curx < destx)
2699 bltmode |= 0x01;
2700 } else
2701 bltmode |= 0x01;
2702 }
2703 /* standard case: forward blitting */
2704 nsrc = (cury * line_length) + curx;
2705 ndest = (desty * line_length) + destx;
2706 if (bltmode) {
2707 /* this means start addresses are at the end,
2708 * counting backwards
2709 */
2710 nsrc += nheight * line_length + nwidth;
2711 ndest += nheight * line_length + nwidth;
2712 }
2840 2713
2841 cirrusfb_WaitBLT(regbase); 2714 cirrusfb_WaitBLT(regbase);
2842 2715
2843 /* pitch: set to line_length */ 2716 cirrusfb_set_blitter(regbase, nwidth, nheight,
2844 vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ 2717 nsrc, ndest, bltmode, line_length);
2845 vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */ 2718}
2846 vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2847 vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
2848 2719
2849 /* BLT width: actual number of pixels - 1 */ 2720/*******************************************************************
2850 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ 2721 cirrusfb_RectFill()
2851 vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
2852 2722
2853 /* BLT height: actual number of lines -1 */ 2723 perform accelerated rectangle fill
2854 vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */ 2724********************************************************************/
2855 vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
2856 2725
2857 /* BLT destination */ 2726static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2858 /* BLT dest low */ 2727 u_short x, u_short y, u_short width, u_short height,
2859 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff)); 2728 u32 fg_color, u32 bg_color, u_short line_length,
2860 /* BLT dest mid */ 2729 u_char blitmode)
2861 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8)); 2730{
2862 /* BLT dest hi */ 2731 u_long ndest = (y * line_length) + x;
2863 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16)); 2732 u_char op;
2864 2733
2865 /* BLT source: set to 0 (is a dummy here anyway) */ 2734 cirrusfb_WaitBLT(regbase);
2866 vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
2867 vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
2868 vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
2869 2735
2870 /* This is a ColorExpand Blt, using the */ 2736 /* This is a ColorExpand Blt, using the */
2871 /* same color for foreground and background */ 2737 /* same color for foreground and background */
2872 vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ 2738 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2873 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */ 2739 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2874 2740
2875 op = 0xc0; 2741 op = 0x80;
2876 if (bits_per_pixel == 16) { 2742 if (bits_per_pixel >= 16) {
2877 vga_wgfx(regbase, CL_GR10, color); /* foreground color */ 2743 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2878 vga_wgfx(regbase, CL_GR11, color); /* background color */ 2744 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2879 op = 0x50; 2745 op = 0x90;
2880 op = 0xd0; 2746 }
2881 } else if (bits_per_pixel == 32) { 2747 if (bits_per_pixel >= 24) {
2882 vga_wgfx(regbase, CL_GR10, color); /* foreground color */ 2748 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2883 vga_wgfx(regbase, CL_GR11, color); /* background color */ 2749 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2884 vga_wgfx(regbase, CL_GR12, color); /* foreground color */ 2750 op = 0xa0;
2885 vga_wgfx(regbase, CL_GR13, color); /* background color */ 2751 }
2886 vga_wgfx(regbase, CL_GR14, 0); /* foreground color */ 2752 if (bits_per_pixel == 32) {
2887 vga_wgfx(regbase, CL_GR15, 0); /* background color */ 2753 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2888 op = 0x50; 2754 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2889 op = 0xf0; 2755 op = 0xb0;
2890 } 2756 }
2891 /* BLT mode: color expand, Enable 8x8 copy (faster?) */ 2757 cirrusfb_set_blitter(regbase, width - 1, height - 1,
2892 vga_wgfx(regbase, CL_GR30, op); /* BLT mode */ 2758 0, ndest, op | blitmode, line_length);
2893
2894 /* BLT ROP: SrcCopy */
2895 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2896
2897 /* and finally: GO! */
2898 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2899
2900 DPRINTK("EXIT\n");
2901} 2759}
2902 2760
2903/************************************************************************** 2761/**************************************************************************
@@ -2917,8 +2775,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
2917 *den = 0; 2775 *den = 0;
2918 *div = 0; 2776 *div = 0;
2919 2777
2920 DPRINTK("ENTER\n");
2921
2922 if (freq < 8000) 2778 if (freq < 8000)
2923 freq = 8000; 2779 freq = 8000;
2924 2780
@@ -2960,12 +2816,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
2960 } 2816 }
2961 } 2817 }
2962 } 2818 }
2963
2964 DPRINTK("Best possible values for given frequency:\n");
2965 DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
2966 freq, *nom, *den, *div);
2967
2968 DPRINTK("EXIT\n");
2969} 2819}
2970 2820
2971/* ------------------------------------------------------------------------- 2821/* -------------------------------------------------------------------------
@@ -2978,32 +2828,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
2978#ifdef CIRRUSFB_DEBUG 2828#ifdef CIRRUSFB_DEBUG
2979 2829
2980/** 2830/**
2981 * cirrusfb_dbg_print_byte
2982 * @name: name associated with byte value to be displayed
2983 * @val: byte value to be displayed
2984 *
2985 * DESCRIPTION:
2986 * Display an indented string, along with a hexidecimal byte value, and
2987 * its decoded bits. Bits 7 through 0 are listed in left-to-right
2988 * order.
2989 */
2990
2991static
2992void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
2993{
2994 DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
2995 name, val,
2996 val & 0x80 ? '1' : '0',
2997 val & 0x40 ? '1' : '0',
2998 val & 0x20 ? '1' : '0',
2999 val & 0x10 ? '1' : '0',
3000 val & 0x08 ? '1' : '0',
3001 val & 0x04 ? '1' : '0',
3002 val & 0x02 ? '1' : '0',
3003 val & 0x01 ? '1' : '0');
3004}
3005
3006/**
3007 * cirrusfb_dbg_print_regs 2831 * cirrusfb_dbg_print_regs
3008 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2832 * @base: If using newmmio, the newmmio base address, otherwise %NULL
3009 * @reg_class: type of registers to read: %CRT, or %SEQ 2833 * @reg_class: type of registers to read: %CRT, or %SEQ
@@ -3014,9 +2838,9 @@ void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
3014 * used at the given @base address to query the information. 2838 * used at the given @base address to query the information.
3015 */ 2839 */
3016 2840
3017static 2841static void cirrusfb_dbg_print_regs(struct fb_info *info,
3018void cirrusfb_dbg_print_regs(caddr_t regbase, 2842 caddr_t regbase,
3019 enum cirrusfb_dbg_reg_class reg_class, ...) 2843 enum cirrusfb_dbg_reg_class reg_class, ...)
3020{ 2844{
3021 va_list list; 2845 va_list list;
3022 unsigned char val = 0; 2846 unsigned char val = 0;
@@ -3042,7 +2866,7 @@ void cirrusfb_dbg_print_regs(caddr_t regbase,
3042 break; 2866 break;
3043 } 2867 }
3044 2868
3045 cirrusfb_dbg_print_byte(name, val); 2869 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
3046 2870
3047 name = va_arg(list, char *); 2871 name = va_arg(list, char *);
3048 } 2872 }
@@ -3051,18 +2875,6 @@ void cirrusfb_dbg_print_regs(caddr_t regbase,
3051} 2875}
3052 2876
3053/** 2877/**
3054 * cirrusfb_dump
3055 * @cirrusfbinfo:
3056 *
3057 * DESCRIPTION:
3058 */
3059
3060static void cirrusfb_dump(void)
3061{
3062 cirrusfb_dbg_reg_dump(NULL);
3063}
3064
3065/**
3066 * cirrusfb_dbg_reg_dump 2878 * cirrusfb_dbg_reg_dump
3067 * @base: If using newmmio, the newmmio base address, otherwise %NULL 2879 * @base: If using newmmio, the newmmio base address, otherwise %NULL
3068 * 2880 *
@@ -3072,12 +2884,11 @@ static void cirrusfb_dump(void)
3072 * used at the given @base address to query the information. 2884 * used at the given @base address to query the information.
3073 */ 2885 */
3074 2886
3075static 2887static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
3076void cirrusfb_dbg_reg_dump(caddr_t regbase)
3077{ 2888{
3078 DPRINTK("CIRRUSFB VGA CRTC register dump:\n"); 2889 dev_dbg(info->device, "VGA CRTC register dump:\n");
3079 2890
3080 cirrusfb_dbg_print_regs(regbase, CRT, 2891 cirrusfb_dbg_print_regs(info, regbase, CRT,
3081 "CR00", 0x00, 2892 "CR00", 0x00,
3082 "CR01", 0x01, 2893 "CR01", 0x01,
3083 "CR02", 0x02, 2894 "CR02", 0x02,
@@ -3127,11 +2938,11 @@ void cirrusfb_dbg_reg_dump(caddr_t regbase)
3127 "CR3F", 0x3F, 2938 "CR3F", 0x3F,
3128 NULL); 2939 NULL);
3129 2940
3130 DPRINTK("\n"); 2941 dev_dbg(info->device, "\n");
3131 2942
3132 DPRINTK("CIRRUSFB VGA SEQ register dump:\n"); 2943 dev_dbg(info->device, "VGA SEQ register dump:\n");
3133 2944
3134 cirrusfb_dbg_print_regs(regbase, SEQ, 2945 cirrusfb_dbg_print_regs(info, regbase, SEQ,
3135 "SR00", 0x00, 2946 "SR00", 0x00,
3136 "SR01", 0x01, 2947 "SR01", 0x01,
3137 "SR02", 0x02, 2948 "SR02", 0x02,
@@ -3160,7 +2971,7 @@ void cirrusfb_dbg_reg_dump(caddr_t regbase)
3160 "SR1F", 0x1F, 2971 "SR1F", 0x1F,
3161 NULL); 2972 NULL);
3162 2973
3163 DPRINTK("\n"); 2974 dev_dbg(info->device, "\n");
3164} 2975}
3165 2976
3166#endif /* CIRRUSFB_DEBUG */ 2977#endif /* CIRRUSFB_DEBUG */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1657b9608b04..2cd500a304f2 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2954,8 +2954,11 @@ static int fbcon_fb_unbind(int idx)
2954 2954
2955static int fbcon_fb_unregistered(struct fb_info *info) 2955static int fbcon_fb_unregistered(struct fb_info *info)
2956{ 2956{
2957 int i, idx = info->node; 2957 int i, idx;
2958 2958
2959 if (!lock_fb_info(info))
2960 return -ENODEV;
2961 idx = info->node;
2959 for (i = first_fb_vc; i <= last_fb_vc; i++) { 2962 for (i = first_fb_vc; i <= last_fb_vc; i++) {
2960 if (con2fb_map[i] == idx) 2963 if (con2fb_map[i] == idx)
2961 con2fb_map[i] = -1; 2964 con2fb_map[i] = -1;
@@ -2979,13 +2982,14 @@ static int fbcon_fb_unregistered(struct fb_info *info)
2979 } 2982 }
2980 } 2983 }
2981 2984
2982 if (!num_registered_fb)
2983 unregister_con_driver(&fb_con);
2984
2985
2986 if (primary_device == idx) 2985 if (primary_device == idx)
2987 primary_device = -1; 2986 primary_device = -1;
2988 2987
2988 unlock_fb_info(info);
2989
2990 if (!num_registered_fb)
2991 unregister_con_driver(&fb_con);
2992
2989 return 0; 2993 return 0;
2990} 2994}
2991 2995
@@ -3021,9 +3025,13 @@ static inline void fbcon_select_primary(struct fb_info *info)
3021 3025
3022static int fbcon_fb_registered(struct fb_info *info) 3026static int fbcon_fb_registered(struct fb_info *info)
3023{ 3027{
3024 int ret = 0, i, idx = info->node; 3028 int ret = 0, i, idx;
3025 3029
3030 if (!lock_fb_info(info))
3031 return -ENODEV;
3032 idx = info->node;
3026 fbcon_select_primary(info); 3033 fbcon_select_primary(info);
3034 unlock_fb_info(info);
3027 3035
3028 if (info_idx == -1) { 3036 if (info_idx == -1) {
3029 for (i = first_fb_vc; i <= last_fb_vc; i++) { 3037 for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3124,7 +3132,7 @@ static void fbcon_get_requirement(struct fb_info *info,
3124 } 3132 }
3125} 3133}
3126 3134
3127static int fbcon_event_notify(struct notifier_block *self, 3135static int fbcon_event_notify(struct notifier_block *self,
3128 unsigned long action, void *data) 3136 unsigned long action, void *data)
3129{ 3137{
3130 struct fb_event *event = data; 3138 struct fb_event *event = data;
@@ -3132,7 +3140,7 @@ static int fbcon_event_notify(struct notifier_block *self,
3132 struct fb_videomode *mode; 3140 struct fb_videomode *mode;
3133 struct fb_con2fbmap *con2fb; 3141 struct fb_con2fbmap *con2fb;
3134 struct fb_blit_caps *caps; 3142 struct fb_blit_caps *caps;
3135 int ret = 0; 3143 int idx, ret = 0;
3136 3144
3137 /* 3145 /*
3138 * ignore all events except driver registration and deregistration 3146 * ignore all events except driver registration and deregistration
@@ -3144,23 +3152,54 @@ static int fbcon_event_notify(struct notifier_block *self,
3144 3152
3145 switch(action) { 3153 switch(action) {
3146 case FB_EVENT_SUSPEND: 3154 case FB_EVENT_SUSPEND:
3155 if (!lock_fb_info(info)) {
3156 ret = -ENODEV;
3157 goto done;
3158 }
3147 fbcon_suspended(info); 3159 fbcon_suspended(info);
3160 unlock_fb_info(info);
3148 break; 3161 break;
3149 case FB_EVENT_RESUME: 3162 case FB_EVENT_RESUME:
3163 if (!lock_fb_info(info)) {
3164 ret = -ENODEV;
3165 goto done;
3166 }
3150 fbcon_resumed(info); 3167 fbcon_resumed(info);
3168 unlock_fb_info(info);
3151 break; 3169 break;
3152 case FB_EVENT_MODE_CHANGE: 3170 case FB_EVENT_MODE_CHANGE:
3171 if (!lock_fb_info(info)) {
3172 ret = -ENODEV;
3173 goto done;
3174 }
3153 fbcon_modechanged(info); 3175 fbcon_modechanged(info);
3176 unlock_fb_info(info);
3154 break; 3177 break;
3155 case FB_EVENT_MODE_CHANGE_ALL: 3178 case FB_EVENT_MODE_CHANGE_ALL:
3179 if (!lock_fb_info(info)) {
3180 ret = -ENODEV;
3181 goto done;
3182 }
3156 fbcon_set_all_vcs(info); 3183 fbcon_set_all_vcs(info);
3184 unlock_fb_info(info);
3157 break; 3185 break;
3158 case FB_EVENT_MODE_DELETE: 3186 case FB_EVENT_MODE_DELETE:
3159 mode = event->data; 3187 mode = event->data;
3188 if (!lock_fb_info(info)) {
3189 ret = -ENODEV;
3190 goto done;
3191 }
3160 ret = fbcon_mode_deleted(info, mode); 3192 ret = fbcon_mode_deleted(info, mode);
3193 unlock_fb_info(info);
3161 break; 3194 break;
3162 case FB_EVENT_FB_UNBIND: 3195 case FB_EVENT_FB_UNBIND:
3163 ret = fbcon_fb_unbind(info->node); 3196 if (!lock_fb_info(info)) {
3197 ret = -ENODEV;
3198 goto done;
3199 }
3200 idx = info->node;
3201 unlock_fb_info(info);
3202 ret = fbcon_fb_unbind(idx);
3164 break; 3203 break;
3165 case FB_EVENT_FB_REGISTERED: 3204 case FB_EVENT_FB_REGISTERED:
3166 ret = fbcon_fb_registered(info); 3205 ret = fbcon_fb_registered(info);
@@ -3178,17 +3217,31 @@ static int fbcon_event_notify(struct notifier_block *self,
3178 con2fb->framebuffer = con2fb_map[con2fb->console - 1]; 3217 con2fb->framebuffer = con2fb_map[con2fb->console - 1];
3179 break; 3218 break;
3180 case FB_EVENT_BLANK: 3219 case FB_EVENT_BLANK:
3220 if (!lock_fb_info(info)) {
3221 ret = -ENODEV;
3222 goto done;
3223 }
3181 fbcon_fb_blanked(info, *(int *)event->data); 3224 fbcon_fb_blanked(info, *(int *)event->data);
3225 unlock_fb_info(info);
3182 break; 3226 break;
3183 case FB_EVENT_NEW_MODELIST: 3227 case FB_EVENT_NEW_MODELIST:
3228 if (!lock_fb_info(info)) {
3229 ret = -ENODEV;
3230 goto done;
3231 }
3184 fbcon_new_modelist(info); 3232 fbcon_new_modelist(info);
3233 unlock_fb_info(info);
3185 break; 3234 break;
3186 case FB_EVENT_GET_REQ: 3235 case FB_EVENT_GET_REQ:
3187 caps = event->data; 3236 caps = event->data;
3237 if (!lock_fb_info(info)) {
3238 ret = -ENODEV;
3239 goto done;
3240 }
3188 fbcon_get_requirement(info, caps); 3241 fbcon_get_requirement(info, caps);
3242 unlock_fb_info(info);
3189 break; 3243 break;
3190 } 3244 }
3191
3192done: 3245done:
3193 return ret; 3246 return ret;
3194} 3247}
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
deleted file mode 100644
index 9704b73135f5..000000000000
--- a/drivers/video/cyblafb.c
+++ /dev/null
@@ -1,1683 +0,0 @@
1/*
2 * Frame buffer driver for Trident Cyberblade/i1 graphics core
3 *
4 * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de>
5 *
6 * CREDITS:
7 * tridentfb.c by Jani Monoses
8 * see files above for further credits
9 *
10 */
11
12#define CYBLAFB_DEBUG 0
13#define CYBLAFB_KD_GRAPHICS_QUIRK 1
14
15#define CYBLAFB_PIXMAPSIZE 8192
16
17#include <linux/module.h>
18#include <linux/string.h>
19#include <linux/fb.h>
20#include <linux/init.h>
21#include <linux/pci.h>
22#include <asm/types.h>
23#include <video/cyblafb.h>
24
25#define VERSION "0.62"
26
27struct cyblafb_par {
28 u32 pseudo_pal[16];
29 struct fb_ops ops;
30};
31
32static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
33 .id = "CyBla",
34 .type = FB_TYPE_PACKED_PIXELS,
35 .xpanstep = 1,
36 .ypanstep = 1,
37 .ywrapstep = 1,
38 .visual = FB_VISUAL_PSEUDOCOLOR,
39 .accel = FB_ACCEL_NONE,
40};
41
42static char *mode __devinitdata = NULL;
43static int bpp __devinitdata = 8;
44static int ref __devinitdata = 75;
45static int fp __devinitdata;
46static int crt __devinitdata;
47static int memsize __devinitdata;
48
49static int basestride;
50static int vesafb;
51static int nativex;
52static int center;
53static int stretch;
54static int pciwb = 1;
55static int pcirb = 1;
56static int pciwr = 1;
57static int pcirr = 1;
58static int disabled;
59static int verbosity;
60static int displaytype;
61
62static void __iomem *io_virt; // iospace virtual memory address
63
64module_param(mode, charp, 0);
65module_param(bpp, int, 0);
66module_param(ref, int, 0);
67module_param(fp, int, 0);
68module_param(crt, int, 0);
69module_param(nativex, int, 0);
70module_param(center, int, 0);
71module_param(stretch, int, 0);
72module_param(pciwb, int, 0);
73module_param(pcirb, int, 0);
74module_param(pciwr, int, 0);
75module_param(pcirr, int, 0);
76module_param(memsize, int, 0);
77module_param(verbosity, int, 0);
78
79//=========================================
80//
81// Well, we have to fix the upper layers.
82// Until this has been done, we work around
83// the bugs.
84//
85//=========================================
86
87#if (CYBLAFB_KD_GRAPHICS_QUIRK && CYBLAFB_DEBUG)
88 if (disabled) { \
89 printk("********\n");\
90 dump_stack();\
91 return val;\
92 }
93
94#elif CYBLAFB_KD_GRAPHICS_QUIRK
95#define KD_GRAPHICS_RETURN(val)\
96 if (disabled) {\
97 return val;\
98 }
99#else
100#define KD_GRAPHICS_RETURN(val)
101#endif
102
103//=========================================
104//
105// Port access macros for memory mapped io
106//
107//=========================================
108
109#define out8(r, v) writeb(v, io_virt + r)
110#define out32(r, v) writel(v, io_virt + r)
111#define in8(r) readb(io_virt + r)
112#define in32(r) readl(io_virt + r)
113
114//======================================
115//
116// Hardware access inline functions
117//
118//======================================
119
120static inline u8 read3X4(u32 reg)
121{
122 out8(0x3D4, reg);
123 return in8(0x3D5);
124}
125
126static inline u8 read3C4(u32 reg)
127{
128 out8(0x3C4, reg);
129 return in8(0x3C5);
130}
131
132static inline u8 read3CE(u32 reg)
133{
134 out8(0x3CE, reg);
135 return in8(0x3CF);
136}
137
138static inline void write3X4(u32 reg, u8 val)
139{
140 out8(0x3D4, reg);
141 out8(0x3D5, val);
142}
143
144static inline void write3C4(u32 reg, u8 val)
145{
146 out8(0x3C4, reg);
147 out8(0x3C5, val);
148}
149
150static inline void write3CE(u32 reg, u8 val)
151{
152 out8(0x3CE, reg);
153 out8(0x3CF, val);
154}
155
156static inline void write3C0(u32 reg, u8 val)
157{
158 in8(0x3DA); // read to reset index
159 out8(0x3C0, reg);
160 out8(0x3C0, val);
161}
162
163//=================================================
164//
165// Enable memory mapped io and unprotect registers
166//
167//=================================================
168
169static void enable_mmio(void)
170{
171 u8 tmp;
172
173 outb(0x0B, 0x3C4);
174 inb(0x3C5); // Set NEW mode
175 outb(SR0E, 0x3C4); // write enable a lot of extended ports
176 outb(0x80, 0x3C5);
177
178 outb(SR11, 0x3C4); // write enable those extended ports that
179 outb(0x87, 0x3C5); // are not affected by SR0E_New
180
181 outb(CR1E, 0x3d4); // clear write protect bit for port 0x3c2
182 tmp = inb(0x3d5) & 0xBF;
183 outb(CR1E, 0x3d4);
184 outb(tmp, 0x3d5);
185
186 outb(CR39, 0x3D4);
187 outb(inb(0x3D5) | 0x01, 0x3D5); // Enable mmio
188}
189
190//=================================================
191//
192// Set pixel clock VCLK1
193// - multipliers set elswhere
194// - freq in units of 0.01 MHz
195//
196// Hardware bug: SR18 >= 250 is broken for the
197// cyberblade/i1
198//
199//=================================================
200
201static void set_vclk(struct cyblafb_par *par, int freq)
202{
203 u32 m, n, k;
204 int f, fi, d, di;
205 u8 lo = 0, hi = 0;
206
207 d = 2000;
208 k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
209 for (m = 0; m < 64; m++)
210 for (n = 0; n < 250; n++) {
211 fi = (int)(((5864727 * (n + 8)) /
212 ((m + 2) * (1 << k))) >> 12);
213 if ((di = abs(fi - freq)) < d) {
214 d = di;
215 f = fi;
216 lo = (u8) n;
217 hi = (u8) ((k << 6) | m);
218 }
219 }
220 write3C4(SR19, hi);
221 write3C4(SR18, lo);
222 if (verbosity > 0)
223 output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
224 freq / 100, freq % 100, (hi & 0xc0) >> 6, hi & 0x3f, lo);
225}
226
227//================================================
228//
229// Cyberblade specific Graphics Engine (GE) setup
230//
231//================================================
232
233static void cyblafb_setup_GE(int pitch, int bpp)
234{
235 KD_GRAPHICS_RETURN();
236
237 switch (bpp) {
238 case 8:
239 basestride = ((pitch >> 3) << 20) | (0 << 29);
240 break;
241 case 15:
242 basestride = ((pitch >> 3) << 20) | (5 << 29);
243 break;
244 case 16:
245 basestride = ((pitch >> 3) << 20) | (1 << 29);
246 break;
247 case 24:
248 case 32:
249 basestride = ((pitch >> 3) << 20) | (2 << 29);
250 break;
251 }
252
253 write3X4(CR36, 0x90); // reset GE
254 write3X4(CR36, 0x80); // enable GE
255 out32(GE24, 1 << 7); // reset all GE pointers by toggling
256 out32(GE24, 0); // d7 of GE24
257 write3X4(CR2D, 0x00); // GE Timinigs, no delays
258 out32(GE6C, 0); // Pattern and Style, p 129, ok
259}
260
261//=====================================================================
262//
263// Cyberblade specific syncing
264//
265// A timeout might be caused by disabled mmio.
266// Cause:
267// - bit CR39 & 1 == 0 upon return, X trident driver bug
268// - kdm bug (KD_GRAPHICS not set on first switch)
269// - kernel design flaw (it believes in the correctness
270// of kdm/X
271// First we try to sync ignoring that problem, as most of the
272// time that will succeed immediately and the enable_mmio()
273// would only degrade performance.
274//
275//=====================================================================
276
277static int cyblafb_sync(struct fb_info *info)
278{
279 u32 status, i = 100000;
280
281 KD_GRAPHICS_RETURN(0);
282
283 while (((status = in32(GE20)) & 0xFe800000) && i != 0)
284 i--;
285
286 if (i == 0) {
287 enable_mmio();
288 i = 1000000;
289 while (((status = in32(GE20)) & 0xFA800000) && i != 0)
290 i--;
291 if (i == 0) {
292 output("GE Timeout, status: %x\n", status);
293 if (status & 0x80000000)
294 output("Bresenham Engine : Busy\n");
295 if (status & 0x40000000)
296 output("Setup Engine : Busy\n");
297 if (status & 0x20000000)
298 output("SP / DPE : Busy\n");
299 if (status & 0x10000000)
300 output("Memory Interface : Busy\n");
301 if (status & 0x08000000)
302 output("Com Lst Proc : Busy\n");
303 if (status & 0x04000000)
304 output("Block Write : Busy\n");
305 if (status & 0x02000000)
306 output("Command Buffer : Full\n");
307 if (status & 0x01000000)
308 output("RESERVED : Busy\n");
309 if (status & 0x00800000)
310 output("PCI Write Buffer : Busy\n");
311 cyblafb_setup_GE(info->var.xres,
312 info->var.bits_per_pixel);
313 }
314 }
315
316 return 0;
317}
318
319//==============================
320//
321// Cyberblade specific fillrect
322//
323//==============================
324
325static void cyblafb_fillrect(struct fb_info *info, const struct fb_fillrect *fr)
326{
327 u32 bpp = info->var.bits_per_pixel, col, desty, height;
328
329 KD_GRAPHICS_RETURN();
330
331 switch (bpp) {
332 default:
333 case 8:
334 col = fr->color;
335 col |= col << 8;
336 col |= col << 16;
337 break;
338 case 16:
339 col = ((u32 *) (info->pseudo_palette))[fr->color];
340 col |= col << 16;
341 break;
342 case 32:
343 col = ((u32 *) (info->pseudo_palette))[fr->color];
344 break;
345 }
346
347 desty = fr->dy;
348 height = fr->height;
349 while (height) {
350 out32(GEB8, basestride | ((desty * info->var.xres_virtual *
351 bpp) >> 6));
352 out32(GE60, col);
353 out32(GE48, fr->rop ? 0x66 : ROP_S);
354 out32(GE44, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
355 out32(GE08, point(fr->dx, 0));
356 out32(GE0C, point(fr->dx + fr->width - 1,
357 height > 4096 ? 4095 : height - 1));
358 if (likely(height <= 4096))
359 return;
360 desty += 4096;
361 height -= 4096;
362 }
363}
364
365//================================================
366//
367// Cyberblade specific copyarea
368//
369// This function silently assumes that it never
370// will be called with width or height exceeding
371// 4096.
372//
373//================================================
374
375static void cyblafb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
376{
377 u32 s1, s2, d1, d2, direction;
378
379 KD_GRAPHICS_RETURN();
380
381 s1 = point(ca->sx, 0);
382 s2 = point(ca->sx + ca->width - 1, ca->height - 1);
383 d1 = point(ca->dx, 0);
384 d2 = point(ca->dx + ca->width - 1, ca->height - 1);
385
386 if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
387 direction = 0;
388 else
389 direction = 2;
390
391 out32(GEB8, basestride | ((ca->dy * info->var.xres_virtual *
392 info->var.bits_per_pixel) >> 6));
393 out32(GEC8, basestride | ((ca->sy * info->var.xres_virtual *
394 info->var.bits_per_pixel) >> 6));
395 out32(GE44, 0xa0000000 | 1 << 19 | 1 << 2 | direction);
396 out32(GE00, direction ? s2 : s1);
397 out32(GE04, direction ? s1 : s2);
398 out32(GE08, direction ? d2 : d1);
399 out32(GE0C, direction ? d1 : d2);
400}
401
402//=======================================================================
403//
404// Cyberblade specific imageblit
405//
406// Accelerated for the most usual case, blitting 1 - bit deep
407// character images. Everything else is passed to the generic imageblit
408// unless it is so insane that it is better to printk an alert.
409//
410// Hardware bug: _Never_ blit across pixel column 2048, that will lock
411// the system. We split those blit requests into three blitting
412// operations.
413//
414//=======================================================================
415
416static void cyblafb_imageblit(struct fb_info *info,
417 const struct fb_image *image)
418{
419 u32 fgcol, bgcol;
420 u32 *pd = (u32 *) image->data;
421 u32 bpp = info->var.bits_per_pixel;
422
423 KD_GRAPHICS_RETURN();
424
425 // Used only for drawing the penguine (image->depth > 1)
426 if (image->depth != 1) {
427 cfb_imageblit(info, image);
428 return;
429 }
430 // That should never happen, but it would be fatal
431 if (image->width == 0 || image->height == 0) {
432 output("imageblit: width/height 0 detected\n");
433 return;
434 }
435
436 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
437 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
438 fgcol = ((u32 *) (info->pseudo_palette))[image->fg_color];
439 bgcol = ((u32 *) (info->pseudo_palette))[image->bg_color];
440 } else {
441 fgcol = image->fg_color;
442 bgcol = image->bg_color;
443 }
444
445 switch (bpp) {
446 case 8:
447 fgcol |= fgcol << 8;
448 bgcol |= bgcol << 8;
449 case 16:
450 fgcol |= fgcol << 16;
451 bgcol |= bgcol << 16;
452 default:
453 break;
454 }
455
456 out32(GEB8, basestride | ((image->dy * info->var.xres_virtual *
457 bpp) >> 6));
458 out32(GE60, fgcol);
459 out32(GE64, bgcol);
460
461 if (!(image->dx < 2048 && (image->dx + image->width - 1) >= 2048)) {
462 u32 dds = ((image->width + 31) >> 5) * image->height;
463 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
464 out32(GE08, point(image->dx, 0));
465 out32(GE0C, point(image->dx + image->width - 1,
466 image->height - 1));
467 while (dds--)
468 out32(GE9C, *pd++);
469 } else {
470 int i, j;
471 u32 ddstotal = (image->width + 31) >> 5;
472 u32 ddsleft = (2048 - image->dx + 31) >> 5;
473 u32 skipleft = ddstotal - ddsleft;
474
475 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
476 out32(GE08, point(image->dx, 0));
477 out32(GE0C, point(2048 - 1, image->height - 1));
478 for (i = 0; i < image->height; i++) {
479 for (j = 0; j < ddsleft; j++)
480 out32(GE9C, *pd++);
481 pd += skipleft;
482 }
483
484 if (image->dx % 32) {
485 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
486 out32(GE08, point(2048, 0));
487 if (image->width > ddsleft << 5)
488 out32(GE0C, point(image->dx + (ddsleft << 5) -
489 1, image->height - 1));
490 else
491 out32(GE0C, point(image->dx + image->width - 1,
492 image->height - 1));
493 pd = ((u32 *) image->data) + ddstotal - skipleft - 1;
494 for (i = 0; i < image->height; i++) {
495 out32(GE9C, swab32(swab32(*pd) << ((32 -
496 (image->dx & 31)) & 31)));
497 pd += ddstotal;
498 }
499 }
500
501 if (skipleft) {
502 out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
503 out32(GE08, point(image->dx + (ddsleft << 5), 0));
504 out32(GE0C, point(image->dx + image->width - 1,
505 image->height - 1));
506 pd = (u32 *) image->data;
507 for (i = 0; i < image->height; i++) {
508 pd += ddsleft;
509 for (j = 0; j < skipleft; j++)
510 out32(GE9C, *pd++);
511 }
512 }
513 }
514}
515
516//==========================================================
517//
518// Check if video mode is acceptable. We change var->??? if
519// video mode is slightly off or return error otherwise.
520// info->??? must not be changed!
521//
522//==========================================================
523
524static int cyblafb_check_var(struct fb_var_screeninfo *var,
525 struct fb_info *info)
526{
527 int bpp = var->bits_per_pixel;
528
529 //
530 // we try to support 8, 16, 24 and 32 bpp modes,
531 // default to 8
532 //
533 // there is a 24 bpp mode, but for now we change requests to 32 bpp
534 // (This is what tridentfb does ... will be changed in the future)
535 //
536 //
537 if (bpp % 8 != 0 || bpp < 8 || bpp > 32)
538 bpp = 8;
539 if (bpp == 24)
540 bpp = var->bits_per_pixel = 32;
541
542 //
543 // interlaced modes are broken, fail if one is requested
544 //
545 if (var->vmode & FB_VMODE_INTERLACED)
546 return -EINVAL;
547
548 //
549 // fail if requested resolution is higher than physical
550 // flatpanel resolution
551 //
552 if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex)
553 return -EINVAL;
554
555 //
556 // we do not allow vclk to exceed 230 MHz. If the requested
557 // vclk is too high, we default to 200 MHz
558 //
559 if ((bpp == 32 ? 200000000 : 100000000) / var->pixclock > 23000)
560 var->pixclock = (bpp == 32 ? 200000000 : 100000000) / 20000;
561
562 //
563 // enforce (h|v)sync_len limits
564 //
565 var->hsync_len &= ~7;
566 if(var->hsync_len > 248)
567 var->hsync_len = 248;
568
569 var->vsync_len &= 15;
570
571 //
572 // Enforce horizontal and vertical hardware limits.
573 // 1600x1200 is mentioned as a maximum, but higher resolutions could
574 // work with slow refresh, small margins and short sync.
575 //
576 var->xres &= ~7;
577
578 if (((var->xres + var->left_margin + var->right_margin +
579 var->hsync_len) > (bpp == 32 ? 2040 : 4088)) ||
580 ((var->yres + var->upper_margin + var->lower_margin +
581 var->vsync_len) > 2047))
582 return -EINVAL;
583
584 if ((var->xres > 1600) || (var->yres > 1200))
585 output("Mode %dx%d exceeds documented limits.\n",
586 var->xres, var->yres);
587 //
588 // try to be smart about (x|y)res_virtual problems.
589 //
590 if (var->xres > var->xres_virtual)
591 var->xres_virtual = var->xres;
592 if (var->yres > var->yres_virtual)
593 var->yres_virtual = var->yres;
594
595 if (bpp == 8 || bpp == 16) {
596 if (var->xres_virtual > 4088)
597 var->xres_virtual = 4088;
598 } else {
599 if (var->xres_virtual > 2040)
600 var->xres_virtual = 2040;
601 }
602 var->xres_virtual &= ~7;
603 while (var->xres_virtual * var->yres_virtual * bpp / 8 >
604 info->fix.smem_len) {
605 if (var->yres_virtual > var->yres)
606 var->yres_virtual--;
607 else if (var->xres_virtual > var->xres)
608 var->xres_virtual -= 8;
609 else
610 return -EINVAL;
611 }
612
613 switch (bpp) {
614 case 8:
615 var->red.offset = 0;
616 var->green.offset = 0;
617 var->blue.offset = 0;
618 var->red.length = 6;
619 var->green.length = 6;
620 var->blue.length = 6;
621 break;
622 case 16:
623 var->red.offset = 11;
624 var->green.offset = 5;
625 var->blue.offset = 0;
626 var->red.length = 5;
627 var->green.length = 6;
628 var->blue.length = 5;
629 break;
630 case 32:
631 var->red.offset = 16;
632 var->green.offset = 8;
633 var->blue.offset = 0;
634 var->red.length = 8;
635 var->green.length = 8;
636 var->blue.length = 8;
637 break;
638 default:
639 return -EINVAL;
640 }
641
642 return 0;
643}
644
645//=====================================================================
646//
647// Pan the display
648//
649// The datasheets defines crt start address to be 20 bits wide and
650// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is
651// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use
652// it, so it is also safe to be used here. BTW: datasheet CR0E on page
653// 90 really is CR1E, the real CRE is documented on page 72.
654//
655// BUT:
656//
657// As of internal version 0.60 we do not use vga panning any longer.
658// Vga panning did not allow us the use of all available video memory
659// and thus prevented ywrap scrolling. We do use the "right view"
660// register now.
661//
662//
663//=====================================================================
664
665static int cyblafb_pan_display(struct fb_var_screeninfo *var,
666 struct fb_info *info)
667{
668 KD_GRAPHICS_RETURN(0);
669
670 info->var.xoffset = var->xoffset;
671 info->var.yoffset = var->yoffset;
672 out32(GE10, 0x80000000 | ((var->xoffset + (var->yoffset *
673 var->xres_virtual)) * var->bits_per_pixel / 32));
674 return 0;
675}
676
677//============================================
678//
679// This will really help in case of a bug ...
680// dump most gaphics core registers.
681//
682//============================================
683
684static void regdump(struct cyblafb_par *par)
685{
686 int i;
687
688 if (verbosity < 2)
689 return;
690
691 printk("\n");
692 for (i = 0; i <= 0xff; i++) {
693 outb(i, 0x3d4);
694 printk("CR%02x=%02x ", i, inb(0x3d5));
695 if (i % 16 == 15)
696 printk("\n");
697 }
698
699 outb(0x30, 0x3ce);
700 outb(inb(0x3cf) | 0x40, 0x3cf);
701 for (i = 0; i <= 0x1f; i++) {
702 if (i == 0 || (i > 2 && i < 8) || i == 0x10 || i == 0x11
703 || i == 0x16) {
704 outb(i, 0x3d4);
705 printk("CR%02x=%02x ", i, inb(0x3d5));
706 } else
707 printk("------- ");
708 if (i % 16 == 15)
709 printk("\n");
710 }
711 outb(0x30, 0x3ce);
712 outb(inb(0x3cf) & 0xbf, 0x3cf);
713
714 printk("\n");
715 for (i = 0; i <= 0x7f; i++) {
716 outb(i, 0x3ce);
717 printk("GR%02x=%02x ", i, inb(0x3cf));
718 if (i % 16 == 15)
719 printk("\n");
720 }
721
722 printk("\n");
723 for (i = 0; i <= 0xff; i++) {
724 outb(i, 0x3c4);
725 printk("SR%02x=%02x ", i, inb(0x3c5));
726 if (i % 16 == 15)
727 printk("\n");
728 }
729
730 printk("\n");
731 for (i = 0; i <= 0x1F; i++) {
732 inb(0x3da); // next access is index!
733 outb(i, 0x3c0);
734 printk("AR%02x=%02x ", i, inb(0x3c1));
735 if (i % 16 == 15)
736 printk("\n");
737 }
738 printk("\n");
739
740 inb(0x3DA); // reset internal flag to 3c0 index
741 outb(0x20, 0x3C0); // enable attr
742
743 return;
744}
745
746//=======================================================================
747//
748// Save State
749//
750// This function is called while a switch to KD_TEXT is in progress,
751// before any of the other functions are called.
752//
753//=======================================================================
754
755static void cyblafb_save_state(struct fb_info *info)
756{
757 struct cyblafb_par *par = info->par;
758 if (verbosity > 0)
759 output("Switching to KD_TEXT\n");
760 disabled = 0;
761 regdump(par);
762 enable_mmio();
763 return;
764}
765
766//=======================================================================
767//
768// Restore State
769//
770// This function is called while a switch to KD_GRAPHICS is in progress,
771// We have to turn on vga style panning registers again because the
772// trident driver of X does not know about GE10.
773//
774//=======================================================================
775
776static void cyblafb_restore_state(struct fb_info *info)
777{
778 if (verbosity > 0)
779 output("Switching to KD_GRAPHICS\n");
780 out32(GE10, 0);
781 disabled = 1;
782 return;
783}
784
785//======================================
786//
787// Set hardware to requested video mode
788//
789//======================================
790
791static int cyblafb_set_par(struct fb_info *info)
792{
793 struct cyblafb_par *par = info->par;
794 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart,
795 hblankend, preendfetch, vtotal, vdispend, vsyncstart,
796 vsyncend, vblankstart, vblankend;
797 struct fb_var_screeninfo *var = &info->var;
798 int bpp = var->bits_per_pixel;
799 int i;
800
801 KD_GRAPHICS_RETURN(0);
802
803 if (verbosity > 0)
804 output("Switching to new mode: "
805 "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
806 var->xres, var->yres, var->xres_virtual,
807 var->yres_virtual, var->bits_per_pixel, var->pixclock,
808 var->left_margin, var->right_margin, var->upper_margin,
809 var->lower_margin, var->hsync_len, var->vsync_len);
810
811 htotal = (var->xres + var->left_margin + var->right_margin +
812 var->hsync_len) / 8 - 5;
813 hdispend = var->xres / 8 - 1;
814 hsyncstart = (var->xres + var->right_margin) / 8;
815 hsyncend = var->hsync_len / 8;
816 hblankstart = hdispend + 1;
817 hblankend = htotal + 3; // should be htotal + 5, bios does it this way
818 preendfetch = ((var->xres >> 3) + 1) * ((bpp + 1) >> 3);
819
820 vtotal = var->yres + var->upper_margin + var->lower_margin +
821 var->vsync_len - 2;
822 vdispend = var->yres - 1;
823 vsyncstart = var->yres + var->lower_margin;
824 vblankstart = var->yres;
825 vblankend = vtotal; // should be vtotal + 2, but bios does it this way
826 vsyncend = var->vsync_len;
827
828 enable_mmio(); // necessary! ... check X ...
829
830 write3X4(CR11, read3X4(CR11) & 0x7F); // unlock cr00 .. cr07
831
832 write3CE(GR30, 8);
833
834 if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
835
836 // stretch or center ?
837
838 out8(0x3C2, 0xEB);
839
840 write3CE(GR30, read3CE(GR30) | 0x81); // shadow mode on
841
842 if (center) {
843 write3CE(GR52, (read3CE(GR52) & 0x7C) | 0x80);
844 write3CE(GR53, (read3CE(GR53) & 0x7C) | 0x80);
845 } else if (stretch) {
846 write3CE(GR5D, 0);
847 write3CE(GR52, (read3CE(GR52) & 0x7C) | 1);
848 write3CE(GR53, (read3CE(GR53) & 0x7C) | 1);
849 }
850
851 } else {
852 out8(0x3C2, 0x2B);
853 write3CE(GR30, 8);
854 }
855
856 //
857 // Setup CRxx regs
858 //
859
860 write3X4(CR00, htotal & 0xFF);
861 write3X4(CR01, hdispend & 0xFF);
862 write3X4(CR02, hblankstart & 0xFF);
863 write3X4(CR03, hblankend & 0x1F);
864 write3X4(CR04, hsyncstart & 0xFF);
865 write3X4(CR05, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
866 write3X4(CR06, vtotal & 0xFF);
867 write3X4(CR07, (vtotal & 0x100) >> 8 |
868 (vdispend & 0x100) >> 7 |
869 (vsyncstart & 0x100) >> 6 |
870 (vblankstart & 0x100) >> 5 |
871 0x10 |
872 (vtotal & 0x200) >> 4 |
873 (vdispend & 0x200) >> 3 | (vsyncstart & 0x200) >> 2);
874 write3X4(CR08, 0);
875 write3X4(CR09, (vblankstart & 0x200) >> 4 | 0x40 | // FIX !!!
876 ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
877 write3X4(CR0A, 0); // Init to some reasonable default
878 write3X4(CR0B, 0); // Init to some reasonable default
879 write3X4(CR0C, 0); // Offset 0
880 write3X4(CR0D, 0); // Offset 0
881 write3X4(CR0E, 0); // Init to some reasonable default
882 write3X4(CR0F, 0); // Init to some reasonable default
883 write3X4(CR10, vsyncstart & 0xFF);
884 write3X4(CR11, (vsyncend & 0x0F));
885 write3X4(CR12, vdispend & 0xFF);
886 write3X4(CR13, ((info->var.xres_virtual * bpp) / (4 * 16)) & 0xFF);
887 write3X4(CR14, 0x40); // double word mode
888 write3X4(CR15, vblankstart & 0xFF);
889 write3X4(CR16, vblankend & 0xFF);
890 write3X4(CR17, 0xE3);
891 write3X4(CR18, 0xFF);
892 // CR19: needed for interlaced modes ... ignore it for now
893 write3X4(CR1A, 0x07); // Arbitration Control Counter 1
894 write3X4(CR1B, 0x07); // Arbitration Control Counter 2
895 write3X4(CR1C, 0x07); // Arbitration Control Counter 3
896 write3X4(CR1D, 0x00); // Don't know, doesn't hurt ; -)
897 write3X4(CR1E, (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
898 // CR1F: do not set, contains BIOS info about memsize
899 write3X4(CR20, 0x20); // enabe wr buf, disable 16bit planar mode
900 write3X4(CR21, 0x20); // enable linear memory access
901 // CR22: RO cpu latch readback
902 // CR23: ???
903 // CR24: RO AR flag state
904 // CR25: RAMDAC rw timing, pclk buffer tristate control ????
905 // CR26: ???
906 write3X4(CR27, (vdispend & 0x400) >> 6 |
907 (vsyncstart & 0x400) >> 5 |
908 (vblankstart & 0x400) >> 4 |
909 (vtotal & 0x400) >> 3 |
910 0x8);
911 // CR28: ???
912 write3X4(CR29, (read3X4(CR29) & 0xCF) | ((((info->var.xres_virtual *
913 bpp) / (4 * 16)) & 0x300) >> 4));
914 write3X4(CR2A, read3X4(CR2A) | 0x40);
915 write3X4(CR2B, (htotal & 0x100) >> 8 |
916 (hdispend & 0x100) >> 7 |
917 // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ???
918 (hsyncstart & 0x100) >> 5 |
919 (hblankstart & 0x100) >> 4);
920 // CR2C: ???
921 // CR2D: initialized in cyblafb_setup_GE()
922 write3X4(CR2F, 0x92); // conservative, better signal quality
923 // CR30: reserved
924 // CR31: reserved
925 // CR32: reserved
926 // CR33: reserved
927 // CR34: disabled in CR36
928 // CR35: disabled in CR36
929 // CR36: initialized in cyblafb_setup_GE
930 // CR37: i2c, ignore for now
931 write3X4(CR38, (bpp == 8) ? 0x00 : //
932 (bpp == 16) ? 0x05 : // highcolor
933 (bpp == 24) ? 0x29 : // packed 24bit truecolor
934 (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
935 write3X4(CR39, 0x01 | // MMIO enable
936 (pcirb ? 0x02 : 0) | // pci read burst enable
937 (pciwb ? 0x04 : 0)); // pci write burst enable
938 write3X4(CR55, 0x1F | // pci clocks * 2 for STOP# during 1st data phase
939 (pcirr ? 0x40 : 0) | // pci read retry enable
940 (pciwr ? 0x80 : 0)); // pci write retry enable
941 write3X4(CR56, preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01) | 2
942 : 0);
943 write3X4(CR57, preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
944 write3X4(CR58, 0x82); // Bios does this .... don't know more
945 //
946 // Setup SRxx regs
947 //
948 write3C4(SR00, 3);
949 write3C4(SR01, 1); //set char clock 8 dots wide
950 write3C4(SR02, 0x0F); //enable 4 maps needed in chain4 mode
951 write3C4(SR03, 0); //no character map select
952 write3C4(SR04, 0x0E); //memory mode: ext mem, even, chain4
953
954 out8(0x3C4, 0x0b);
955 in8(0x3C5); // Set NEW mode
956 write3C4(SR0D, 0x00); // test ... check
957
958 set_vclk(par, (bpp == 32 ? 200000000 : 100000000)
959 / info->var.pixclock); //SR18, SR19
960
961 //
962 // Setup GRxx regs
963 //
964 write3CE(GR00, 0x00); // test ... check
965 write3CE(GR01, 0x00); // test ... check
966 write3CE(GR02, 0x00); // test ... check
967 write3CE(GR03, 0x00); // test ... check
968 write3CE(GR04, 0x00); // test ... check
969 write3CE(GR05, 0x40); // no CGA compat, allow 256 col
970 write3CE(GR06, 0x05); // graphics mode
971 write3CE(GR07, 0x0F); // planes?
972 write3CE(GR08, 0xFF); // test ... check
973 write3CE(GR0F, (bpp == 32) ? 0x1A : 0x12); // vclk / 2 if 32bpp, chain4
974 write3CE(GR20, 0xC0); // test ... check
975 write3CE(GR2F, 0xA0); // PCLK = VCLK, no skew,
976
977 //
978 // Setup ARxx regs
979 //
980 for (i = 0; i < 0x10; i++) // set AR00 .. AR0f
981 write3C0(i, i);
982 write3C0(AR10, 0x41); // graphics mode and support 256 color modes
983 write3C0(AR12, 0x0F); // planes
984 write3C0(AR13, 0); // horizontal pel panning
985 in8(0x3DA); // reset internal flag to 3c0 index
986 out8(0x3C0, 0x20); // enable attr
987
988 //
989 // Setup hidden RAMDAC command register
990 //
991 in8(0x3C8); // these reads are
992 in8(0x3C6); // necessary to
993 in8(0x3C6); // unmask the RAMDAC
994 in8(0x3C6); // command reg, otherwise
995 in8(0x3C6); // we would write the pixelmask reg!
996 out8(0x3C6, (bpp == 8) ? 0x00 : // 256 colors
997 (bpp == 15) ? 0x10 : //
998 (bpp == 16) ? 0x30 : // hicolor
999 (bpp == 24) ? 0xD0 : // truecolor
1000 (bpp == 32) ? 0xD0 : 0); // truecolor
1001 in8(0x3C8);
1002
1003 //
1004 // GR31 is not mentioned in the datasheet
1005 //
1006 if (displaytype == DISPLAY_FP)
1007 write3CE(GR31, (read3CE(GR31) & 0x8F) |
1008 ((info->var.yres > 1024) ? 0x50 :
1009 (info->var.yres > 768) ? 0x30 :
1010 (info->var.yres > 600) ? 0x20 :
1011 (info->var.yres > 480) ? 0x10 : 0));
1012
1013 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
1014 : FB_VISUAL_TRUECOLOR;
1015 info->fix.line_length = info->var.xres_virtual * (bpp >> 3);
1016 info->cmap.len = (bpp == 8) ? 256 : 16;
1017
1018 //
1019 // init acceleration engine
1020 //
1021 cyblafb_setup_GE(info->var.xres_virtual, info->var.bits_per_pixel);
1022
1023 //
1024 // Set/clear flags to allow proper scroll mode selection.
1025 //
1026 if (var->xres == var->xres_virtual)
1027 info->flags &= ~FBINFO_HWACCEL_XPAN;
1028 else
1029 info->flags |= FBINFO_HWACCEL_XPAN;
1030
1031 if (var->yres == var->yres_virtual)
1032 info->flags &= ~FBINFO_HWACCEL_YPAN;
1033 else
1034 info->flags |= FBINFO_HWACCEL_YPAN;
1035
1036 if (info->fix.smem_len !=
1037 var->xres_virtual * var->yres_virtual * bpp / 8)
1038 info->flags &= ~FBINFO_HWACCEL_YWRAP;
1039 else
1040 info->flags |= FBINFO_HWACCEL_YWRAP;
1041
1042 regdump(par);
1043
1044 return 0;
1045}
1046
1047//========================
1048//
1049// Set one color register
1050//
1051//========================
1052
1053static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1054 unsigned blue, unsigned transp,
1055 struct fb_info *info)
1056{
1057 int bpp = info->var.bits_per_pixel;
1058
1059 KD_GRAPHICS_RETURN(0);
1060
1061 if (regno >= info->cmap.len)
1062 return 1;
1063
1064 if (bpp == 8) {
1065 out8(0x3C6, 0xFF);
1066 out8(0x3C8, regno);
1067 out8(0x3C9, red >> 10);
1068 out8(0x3C9, green >> 10);
1069 out8(0x3C9, blue >> 10);
1070
1071 } else if (regno < 16) {
1072 if (bpp == 16) // RGB 565
1073 ((u32 *) info->pseudo_palette)[regno] =
1074 (red & 0xF800) |
1075 ((green & 0xFC00) >> 5) |
1076 ((blue & 0xF800) >> 11);
1077 else if (bpp == 32) // ARGB 8888
1078 ((u32 *) info->pseudo_palette)[regno] =
1079 ((transp & 0xFF00) << 16) |
1080 ((red & 0xFF00) << 8) |
1081 ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
1082 }
1083
1084 return 0;
1085}
1086
1087//==========================================================
1088//
1089// Try blanking the screen. For flat panels it does nothing
1090//
1091//==========================================================
1092
1093static int cyblafb_blank(int blank_mode, struct fb_info *info)
1094{
1095 unsigned char PMCont, DPMSCont;
1096
1097 KD_GRAPHICS_RETURN(0);
1098
1099 if (displaytype == DISPLAY_FP)
1100 return 0;
1101
1102 out8(0x83C8, 0x04); // DPMS Control
1103 PMCont = in8(0x83C6) & 0xFC;
1104
1105 DPMSCont = read3CE(GR23) & 0xFC;
1106
1107 switch (blank_mode) {
1108 case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On
1109 case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
1110 PMCont |= 0x03;
1111 DPMSCont |= 0x00;
1112 break;
1113 case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On
1114 PMCont |= 0x02;
1115 DPMSCont |= 0x01;
1116 break;
1117 case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off
1118 PMCont |= 0x02;
1119 DPMSCont |= 0x02;
1120 break;
1121 case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off
1122 PMCont |= 0x00;
1123 DPMSCont |= 0x03;
1124 break;
1125 }
1126
1127 write3CE(GR23, DPMSCont);
1128 out8(0x83C8, 4);
1129 out8(0x83C6, PMCont);
1130 //
1131 // let fbcon do a softblank for us
1132 //
1133 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1134}
1135
1136static struct fb_ops cyblafb_ops __devinitdata = {
1137 .owner = THIS_MODULE,
1138 .fb_setcolreg = cyblafb_setcolreg,
1139 .fb_pan_display = cyblafb_pan_display,
1140 .fb_blank = cyblafb_blank,
1141 .fb_check_var = cyblafb_check_var,
1142 .fb_set_par = cyblafb_set_par,
1143 .fb_fillrect = cyblafb_fillrect,
1144 .fb_copyarea = cyblafb_copyarea,
1145 .fb_imageblit = cyblafb_imageblit,
1146 .fb_sync = cyblafb_sync,
1147 .fb_restore_state = cyblafb_restore_state,
1148 .fb_save_state = cyblafb_save_state,
1149};
1150
1151//==========================================================================
1152//
1153// getstartupmode() decides about the inital video mode
1154//
1155// There is no reason to use modedb, a lot of video modes there would
1156// need altered timings to display correctly. So I decided that it is much
1157// better to provide a limited optimized set of modes plus the option of
1158// using the mode in effect at startup time (might be selected using the
1159// vga=??? parameter). After that the user might use fbset to select any
1160// mode he likes, check_var will not try to alter geometry parameters as
1161// it would be necessary otherwise.
1162//
1163//==========================================================================
1164
1165static int __devinit getstartupmode(struct fb_info *info)
1166{
1167 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend,
1168 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend,
1169 cr00, cr01, cr02, cr03, cr04, cr05, cr2b,
1170 cr06, cr07, cr09, cr10, cr11, cr12, cr15, cr16, cr27,
1171 cr38, sr0d, sr18, sr19, gr0f, fi, pxclkdiv, vclkdiv, tmp, i;
1172
1173 struct modus {
1174 int xres; int vxres; int yres; int vyres;
1175 int bpp; int pxclk;
1176 int left_margin; int right_margin;
1177 int upper_margin; int lower_margin;
1178 int hsync_len; int vsync_len;
1179 } modedb[5] = {
1180 {
1181 0, 2048, 0, 4096, 0, 0, 0, 0, 0, 0, 0, 0}, {
1182 640, 2048, 480, 4096, 0, 0, -40, 24, 17, 0, 216, 3}, {
1183 800, 2048, 600, 4096, 0, 0, 96, 24, 14, 0, 136, 11}, {
1184 1024, 2048, 768, 4096, 0, 0, 144, 24, 29, 0, 120, 3}, {
1185 1280, 2048, 1024, 4096, 0, 0, 232, 16, 39, 0, 160, 3}
1186 };
1187
1188 outb(0x00, 0x3d4); cr00 = inb(0x3d5);
1189 outb(0x01, 0x3d4); cr01 = inb(0x3d5);
1190 outb(0x02, 0x3d4); cr02 = inb(0x3d5);
1191 outb(0x03, 0x3d4); cr03 = inb(0x3d5);
1192 outb(0x04, 0x3d4); cr04 = inb(0x3d5);
1193 outb(0x05, 0x3d4); cr05 = inb(0x3d5);
1194 outb(0x06, 0x3d4); cr06 = inb(0x3d5);
1195 outb(0x07, 0x3d4); cr07 = inb(0x3d5);
1196 outb(0x09, 0x3d4); cr09 = inb(0x3d5);
1197 outb(0x10, 0x3d4); cr10 = inb(0x3d5);
1198 outb(0x11, 0x3d4); cr11 = inb(0x3d5);
1199 outb(0x12, 0x3d4); cr12 = inb(0x3d5);
1200 outb(0x15, 0x3d4); cr15 = inb(0x3d5);
1201 outb(0x16, 0x3d4); cr16 = inb(0x3d5);
1202 outb(0x27, 0x3d4); cr27 = inb(0x3d5);
1203 outb(0x2b, 0x3d4); cr2b = inb(0x3d5);
1204 outb(0x38, 0x3d4); cr38 = inb(0x3d5);
1205
1206 outb(0x0b, 0x3c4);
1207 inb(0x3c5);
1208
1209 outb(0x0d, 0x3c4); sr0d = inb(0x3c5);
1210 outb(0x18, 0x3c4); sr18 = inb(0x3c5);
1211 outb(0x19, 0x3c4); sr19 = inb(0x3c5);
1212 outb(0x0f, 0x3ce); gr0f = inb(0x3cf);
1213
1214 htotal = cr00 | (cr2b & 0x01) << 8;
1215 hdispend = cr01 | (cr2b & 0x02) << 7;
1216 hblankstart = cr02 | (cr2b & 0x10) << 4;
1217 hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
1218 hsyncstart = cr04 | (cr2b & 0x08) << 5;
1219 hsyncend = cr05 & 0x1f;
1220
1221 modedb[0].xres = hblankstart * 8;
1222 modedb[0].hsync_len = hsyncend * 8;
1223 modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
1224 modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
1225 modedb[0].right_margin - modedb[0].hsync_len;
1226
1227 vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
1228 | (cr27 & 0x80) << 3;
1229 vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
1230 | (cr27 & 0x10) << 6;
1231 vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
1232 | (cr27 & 0x20) << 5;
1233 vsyncend = cr11 & 0x0f;
1234 vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
1235 | (cr27 & 0x40) << 4;
1236 vblankend = cr16;
1237
1238 modedb[0].yres = vdispend + 1;
1239 modedb[0].vsync_len = vsyncend;
1240 modedb[0].lower_margin = vsyncstart - modedb[0].yres;
1241 modedb[0].upper_margin = vtotal - modedb[0].yres -
1242 modedb[0].lower_margin - modedb[0].vsync_len + 2;
1243
1244 tmp = cr38 & 0x3c;
1245 modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
1246 tmp == 8 ? 32 : 8;
1247
1248 fi = ((5864727 * (sr18 + 8)) /
1249 (((sr19 & 0x3f) + 2) * (1 << ((sr19 & 0xc0) >> 6)))) >> 12;
1250 pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
1251 tmp = sr0d & 0x06;
1252 vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
1253 modedb[0].pxclk = ((100000000 * pxclkdiv * vclkdiv) >> 1) / fi;
1254
1255 if (verbosity > 0)
1256 output("detected startup mode: "
1257 "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
1258 modedb[0].xres, modedb[0].yres, modedb[0].xres,
1259 modedb[0].bpp, modedb[0].pxclk, modedb[0].left_margin,
1260 modedb[0].right_margin, modedb[0].upper_margin,
1261 modedb[0].lower_margin, modedb[0].hsync_len,
1262 modedb[0].vsync_len);
1263
1264 //
1265 // We use this goto target in case of a failed check_var. No, I really
1266 // do not want to do it in another way!
1267 //
1268
1269 tryagain:
1270
1271 i = (mode == NULL) ? 0 :
1272 !strncmp(mode, "640x480", 7) ? 1 :
1273 !strncmp(mode, "800x600", 7) ? 2 :
1274 !strncmp(mode, "1024x768", 8) ? 3 :
1275 !strncmp(mode, "1280x1024", 9) ? 4 : 0;
1276
1277 ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
1278
1279 if (i == 0) {
1280 info->var.pixclock = modedb[i].pxclk;
1281 info->var.bits_per_pixel = modedb[i].bpp;
1282 } else {
1283 info->var.pixclock = (100000000 /
1284 ((modedb[i].left_margin +
1285 modedb[i].xres +
1286 modedb[i].right_margin +
1287 modedb[i].hsync_len) *
1288 (modedb[i].upper_margin +
1289 modedb[i].yres +
1290 modedb[i].lower_margin +
1291 modedb[i].vsync_len) * ref / 10000));
1292 info->var.bits_per_pixel = bpp;
1293 }
1294
1295 info->var.left_margin = modedb[i].left_margin;
1296 info->var.right_margin = modedb[i].right_margin;
1297 info->var.xres = modedb[i].xres;
1298 if (!(modedb[i].yres == 1280 && modedb[i].bpp == 32))
1299 info->var.xres_virtual = modedb[i].vxres;
1300 else
1301 info->var.xres_virtual = modedb[i].xres;
1302 info->var.xoffset = 0;
1303 info->var.hsync_len = modedb[i].hsync_len;
1304 info->var.upper_margin = modedb[i].upper_margin;
1305 info->var.yres = modedb[i].yres;
1306 info->var.yres_virtual = modedb[i].vyres;
1307 info->var.yoffset = 0;
1308 info->var.lower_margin = modedb[i].lower_margin;
1309 info->var.vsync_len = modedb[i].vsync_len;
1310 info->var.sync = 0;
1311 info->var.vmode = FB_VMODE_NONINTERLACED;
1312
1313 if (cyblafb_check_var(&info->var, info)) {
1314 // 640x480 - 8@75 should really never fail. One case would
1315 // be fp == 1 and nativex < 640 ... give up then
1316 if (i == 1 && bpp == 8 && ref == 75) {
1317 output("Can't find a valid mode :-(\n");
1318 return -EINVAL;
1319 }
1320 // Our detected mode is unlikely to fail. If it does,
1321 // try 640x480 - 8@75 ...
1322 if (i == 0) {
1323 mode = "640x480";
1324 bpp = 8;
1325 ref = 75;
1326 output("Detected mode failed check_var! "
1327 "Trying 640x480 - 8@75\n");
1328 goto tryagain;
1329 }
1330 // A specified video mode failed for some reason.
1331 // Try the startup mode first
1332 output("Specified mode '%s' failed check! "
1333 "Falling back to startup mode.\n", mode);
1334 mode = NULL;
1335 goto tryagain;
1336 }
1337
1338 return 0;
1339}
1340
1341//========================================================
1342//
1343// Detect activated memory size. Undefined values require
1344// memsize parameter.
1345//
1346//========================================================
1347
1348static unsigned int __devinit get_memsize(void)
1349{
1350 unsigned char tmp;
1351 unsigned int k;
1352
1353 if (memsize)
1354 k = memsize * Kb;
1355 else {
1356 tmp = read3X4(CR1F) & 0x0F;
1357 switch (tmp) {
1358 case 0x03:
1359 k = 1 * 1024 * 1024;
1360 break;
1361 case 0x07:
1362 k = 2 * 1024 * 1024;
1363 break;
1364 case 0x0F:
1365 k = 4 * 1024 * 1024;
1366 break;
1367 case 0x04:
1368 k = 8 * 1024 * 1024;
1369 break;
1370 default:
1371 k = 1 * 1024 * 1024;
1372 output("Unknown memory size code %x in CR1F."
1373 " We default to 1 Mb for now, please"
1374 " do provide a memsize parameter!\n", tmp);
1375 }
1376 }
1377
1378 if (verbosity > 0)
1379 output("framebuffer size = %d Kb\n", k / Kb);
1380 return k;
1381}
1382
1383//=========================================================
1384//
1385// Detect if a flat panel monitor connected to the special
1386// interface is active. Override is possible by fp and crt
1387// parameters.
1388//
1389//=========================================================
1390
1391static unsigned int __devinit get_displaytype(void)
1392{
1393 if (fp)
1394 return DISPLAY_FP;
1395 if (crt)
1396 return DISPLAY_CRT;
1397 return (read3CE(GR33) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
1398}
1399
1400//=====================================
1401//
1402// Get native resolution of flat panel
1403//
1404//=====================================
1405
1406static int __devinit get_nativex(void)
1407{
1408 int x, y, tmp;
1409
1410 if (nativex)
1411 return nativex;
1412
1413 tmp = (read3CE(GR52) >> 4) & 3;
1414
1415 switch (tmp) {
1416 case 0: x = 1280; y = 1024;
1417 break;
1418 case 2: x = 1024; y = 768;
1419 break;
1420 case 3: x = 800; y = 600;
1421 break;
1422 case 4: x = 1400; y = 1050;
1423 break;
1424 case 1:
1425 default:
1426 x = 640; y = 480;
1427 break;
1428 }
1429
1430 if (verbosity > 0)
1431 output("%dx%d flat panel found\n", x, y);
1432 return x;
1433}
1434
1435static int __devinit cybla_pci_probe(struct pci_dev *dev,
1436 const struct pci_device_id *id)
1437{
1438 struct fb_info *info;
1439 struct cyblafb_par *par;
1440
1441 info = framebuffer_alloc(sizeof(struct cyblafb_par), &dev->dev);
1442 if (!info)
1443 goto errout_alloc_info;
1444
1445 info->pixmap.addr = kzalloc(CYBLAFB_PIXMAPSIZE, GFP_KERNEL);
1446 if (!info->pixmap.addr) {
1447 output("allocation of pixmap buffer failed!\n");
1448 goto errout_alloc_pixmap;
1449 }
1450 info->pixmap.size = CYBLAFB_PIXMAPSIZE - 4;
1451 info->pixmap.buf_align = 4;
1452 info->pixmap.access_align = 32;
1453 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1454 info->pixmap.scan_align = 4;
1455
1456 par = info->par;
1457 par->ops = cyblafb_ops;
1458
1459 info->fix = cyblafb_fix;
1460 info->fbops = &par->ops;
1461 info->fix = cyblafb_fix;
1462
1463 if (pci_enable_device(dev)) {
1464 output("could not enable device!\n");
1465 goto errout_enable;
1466 }
1467 // might already be requested by vga console or vesafb,
1468 // so we do care about success
1469 if (!request_region(0x3c0, 0x20, "cyblafb")) {
1470 output("region 0x3c0/0x20 already reserved\n");
1471 vesafb |= 1;
1472
1473 }
1474 //
1475 // Graphics Engine Registers
1476 //
1477 if (!request_region(GEBase, 0x100, "cyblafb")) {
1478 output("region %#x/0x100 already reserved\n", GEBase);
1479 vesafb |= 2;
1480 }
1481
1482 regdump(par);
1483
1484 enable_mmio();
1485
1486 // setup MMIO region
1487 info->fix.mmio_start = pci_resource_start(dev, 1);
1488 info->fix.mmio_len = 0x20000;
1489
1490 if (!request_mem_region(info->fix.mmio_start,
1491 info->fix.mmio_len, "cyblafb")) {
1492 output("request_mem_region failed for mmio region!\n");
1493 goto errout_mmio_reqmem;
1494 }
1495
1496 io_virt = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
1497
1498 if (!io_virt) {
1499 output("ioremap failed for mmio region\n");
1500 goto errout_mmio_remap;
1501 }
1502 // setup framebuffer memory ... might already be requested
1503 // by vesafb. Not to fail in case of an unsuccessful request
1504 // is useful if both are loaded.
1505 info->fix.smem_start = pci_resource_start(dev, 0);
1506 info->fix.smem_len = get_memsize();
1507
1508 if (!request_mem_region(info->fix.smem_start,
1509 info->fix.smem_len, "cyblafb")) {
1510 output("region %#lx/%#x already reserved\n",
1511 info->fix.smem_start, info->fix.smem_len);
1512 vesafb |= 4;
1513 }
1514
1515 info->screen_base = ioremap_nocache(info->fix.smem_start,
1516 info->fix.smem_len);
1517
1518 if (!info->screen_base) {
1519 output("ioremap failed for smem region\n");
1520 goto errout_smem_remap;
1521 }
1522
1523 displaytype = get_displaytype();
1524
1525 if (displaytype == DISPLAY_FP)
1526 nativex = get_nativex();
1527
1528 info->flags = FBINFO_DEFAULT
1529 | FBINFO_HWACCEL_COPYAREA
1530 | FBINFO_HWACCEL_FILLRECT
1531 | FBINFO_HWACCEL_IMAGEBLIT
1532 | FBINFO_READS_FAST
1533// | FBINFO_PARTIAL_PAN_OK
1534 | FBINFO_MISC_ALWAYS_SETPAR;
1535
1536 info->pseudo_palette = par->pseudo_pal;
1537
1538 if (getstartupmode(info))
1539 goto errout_findmode;
1540
1541 fb_alloc_cmap(&info->cmap, 256, 0);
1542
1543 if (register_framebuffer(info)) {
1544 output("Could not register CyBla framebuffer\n");
1545 goto errout_register;
1546 }
1547
1548 pci_set_drvdata(dev, info);
1549
1550 //
1551 // normal exit and error paths
1552 //
1553
1554 return 0;
1555
1556 errout_register:
1557 errout_findmode:
1558 iounmap(info->screen_base);
1559 errout_smem_remap:
1560 if (!(vesafb & 4))
1561 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1562 iounmap(io_virt);
1563 errout_mmio_remap:
1564 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1565 errout_mmio_reqmem:
1566 if (!(vesafb & 1))
1567 release_region(0x3c0, 32);
1568 errout_enable:
1569 kfree(info->pixmap.addr);
1570 errout_alloc_pixmap:
1571 framebuffer_release(info);
1572 errout_alloc_info:
1573 output("CyblaFB version %s aborting init.\n", VERSION);
1574 return -ENODEV;
1575}
1576
1577static void __devexit cybla_pci_remove(struct pci_dev *dev)
1578{
1579 struct fb_info *info = pci_get_drvdata(dev);
1580
1581 unregister_framebuffer(info);
1582 iounmap(io_virt);
1583 iounmap(info->screen_base);
1584 if (!(vesafb & 4))
1585 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1586 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1587 fb_dealloc_cmap(&info->cmap);
1588 if (!(vesafb & 2))
1589 release_region(GEBase, 0x100);
1590 if (!(vesafb & 1))
1591 release_region(0x3c0, 32);
1592 kfree(info->pixmap.addr);
1593 framebuffer_release(info);
1594 output("CyblaFB version %s normal exit.\n", VERSION);
1595}
1596
1597//
1598// List of boards that we are trying to support
1599//
1600static struct pci_device_id cybla_devices[] = {
1601 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1602 {0,}
1603};
1604
1605MODULE_DEVICE_TABLE(pci, cybla_devices);
1606
1607static struct pci_driver cyblafb_pci_driver = {
1608 .name = "cyblafb",
1609 .id_table = cybla_devices,
1610 .probe = cybla_pci_probe,
1611 .remove = __devexit_p(cybla_pci_remove)
1612};
1613
1614//=============================================================
1615//
1616// kernel command line example:
1617//
1618// video=cyblafb:1280x1024, bpp=16, ref=50 ...
1619//
1620// modprobe command line example:
1621//
1622// modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
1623//
1624//=============================================================
1625
1626static int __devinit cyblafb_init(void)
1627{
1628#ifndef MODULE
1629 char *options = NULL;
1630 char *opt;
1631
1632 if (fb_get_options("cyblafb", &options))
1633 return -ENODEV;
1634
1635 if (options && *options)
1636 while ((opt = strsep(&options, ",")) != NULL) {
1637 if (!*opt)
1638 continue;
1639 else if (!strncmp(opt, "bpp=", 4))
1640 bpp = simple_strtoul(opt + 4, NULL, 0);
1641 else if (!strncmp(opt, "ref=", 4))
1642 ref = simple_strtoul(opt + 4, NULL, 0);
1643 else if (!strncmp(opt, "fp", 2))
1644 displaytype = DISPLAY_FP;
1645 else if (!strncmp(opt, "crt", 3))
1646 displaytype = DISPLAY_CRT;
1647 else if (!strncmp(opt, "nativex=", 8))
1648 nativex = simple_strtoul(opt + 8, NULL, 0);
1649 else if (!strncmp(opt, "center", 6))
1650 center = 1;
1651 else if (!strncmp(opt, "stretch", 7))
1652 stretch = 1;
1653 else if (!strncmp(opt, "pciwb=", 6))
1654 pciwb = simple_strtoul(opt + 6, NULL, 0);
1655 else if (!strncmp(opt, "pcirb=", 6))
1656 pcirb = simple_strtoul(opt + 6, NULL, 0);
1657 else if (!strncmp(opt, "pciwr=", 6))
1658 pciwr = simple_strtoul(opt + 6, NULL, 0);
1659 else if (!strncmp(opt, "pcirr=", 6))
1660 pcirr = simple_strtoul(opt + 6, NULL, 0);
1661 else if (!strncmp(opt, "memsize=", 8))
1662 memsize = simple_strtoul(opt + 8, NULL, 0);
1663 else if (!strncmp(opt, "verbosity=", 10))
1664 verbosity = simple_strtoul(opt + 10, NULL, 0);
1665 else
1666 mode = opt;
1667 }
1668#endif
1669 output("CyblaFB version %s initializing\n", VERSION);
1670 return pci_register_driver(&cyblafb_pci_driver);
1671}
1672
1673static void __exit cyblafb_exit(void)
1674{
1675 pci_unregister_driver(&cyblafb_pci_driver);
1676}
1677
1678module_init(cyblafb_init);
1679module_exit(cyblafb_exit);
1680
1681MODULE_AUTHOR("Knut Petersen <knut_petersen@t-online.de>");
1682MODULE_DESCRIPTION("Framebuffer driver for Cyberblade/i1 graphics core");
1683MODULE_LICENSE("GPL");
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index daf9b81878a4..0c5b9a9fd56f 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -129,6 +129,8 @@ static int set_system(const struct dmi_system_id *id)
129 screen_info.lfb_width = info->width; 129 screen_info.lfb_width = info->width;
130 if (screen_info.lfb_height == 0) 130 if (screen_info.lfb_height == 0)
131 screen_info.lfb_height = info->height; 131 screen_info.lfb_height = info->height;
132 if (screen_info.orig_video_isVGA == 0)
133 screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
132 134
133 return 0; 135 return 0;
134} 136}
@@ -374,9 +376,10 @@ static int __init efifb_init(void)
374 int ret; 376 int ret;
375 char *option = NULL; 377 char *option = NULL;
376 378
379 dmi_check_system(dmi_system_table);
380
377 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 381 if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
378 return -ENODEV; 382 return -ENODEV;
379 dmi_check_system(dmi_system_table);
380 383
381 if (fb_get_options("efifb", &option)) 384 if (fb_get_options("efifb", &option))
382 return -ENODEV; 385 return -ENODEV;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 082026546aee..0a7a6679ee6e 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -85,8 +85,9 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
85 85
86/* vm_ops->page_mkwrite handler */ 86/* vm_ops->page_mkwrite handler */
87static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, 87static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
88 struct page *page) 88 struct vm_fault *vmf)
89{ 89{
90 struct page *page = vmf->page;
90 struct fb_info *info = vma->vm_private_data; 91 struct fb_info *info = vma->vm_private_data;
91 struct fb_deferred_io *fbdefio = info->fbdefio; 92 struct fb_deferred_io *fbdefio = info->fbdefio;
92 struct page *cur; 93 struct page *cur;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cfd9dce1ce0b..2ac32e6b5953 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -46,6 +46,17 @@
46struct fb_info *registered_fb[FB_MAX] __read_mostly; 46struct fb_info *registered_fb[FB_MAX] __read_mostly;
47int num_registered_fb __read_mostly; 47int num_registered_fb __read_mostly;
48 48
49int lock_fb_info(struct fb_info *info)
50{
51 mutex_lock(&info->lock);
52 if (!info->fbops) {
53 mutex_unlock(&info->lock);
54 return 0;
55 }
56 return 1;
57}
58EXPORT_SYMBOL(lock_fb_info);
59
49/* 60/*
50 * Helpers 61 * Helpers
51 */ 62 */
@@ -1086,13 +1097,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1086 return -EINVAL; 1097 return -EINVAL;
1087 con2fb.framebuffer = -1; 1098 con2fb.framebuffer = -1;
1088 event.data = &con2fb; 1099 event.data = &con2fb;
1089
1090 if (!lock_fb_info(info))
1091 return -ENODEV;
1092 event.info = info; 1100 event.info = info;
1093 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); 1101 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
1094 unlock_fb_info(info);
1095
1096 ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; 1102 ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
1097 break; 1103 break;
1098 case FBIOPUT_CON2FBMAP: 1104 case FBIOPUT_CON2FBMAP:
@@ -1109,12 +1115,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1109 break; 1115 break;
1110 } 1116 }
1111 event.data = &con2fb; 1117 event.data = &con2fb;
1112 if (!lock_fb_info(info))
1113 return -ENODEV;
1114 event.info = info; 1118 event.info = info;
1115 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, 1119 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
1116 &event);
1117 unlock_fb_info(info);
1118 break; 1120 break;
1119 case FBIOBLANK: 1121 case FBIOBLANK:
1120 if (!lock_fb_info(info)) 1122 if (!lock_fb_info(info))
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index d9627b57eb4d..135ae18bfce8 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -362,6 +362,7 @@ int NVCommonSetup(struct fb_info *info)
362 case 0x0186: 362 case 0x0186:
363 case 0x0187: 363 case 0x0187:
364 case 0x018D: 364 case 0x018D:
365 case 0x01D7:
365 case 0x0228: 366 case 0x0228:
366 case 0x0286: 367 case 0x0286:
367 case 0x028C: 368 case 0x028C:
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index f132aab8c5de..c03f7f55c76d 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -5,7 +5,6 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/i2c.h> 6#include <linux/i2c.h>
7#include <linux/i2c-algo-bit.h> 7#include <linux/i2c-algo-bit.h>
8#include <linux/mutex.h>
9#include <video/vga.h> 8#include <video/vga.h>
10 9
11#define NV_ARCH_04 0x04 10#define NV_ARCH_04 0x04
@@ -99,7 +98,6 @@ struct nvidia_par {
99 RIVA_HW_STATE initial_state; 98 RIVA_HW_STATE initial_state;
100 RIVA_HW_STATE *CurrentState; 99 RIVA_HW_STATE *CurrentState;
101 struct vgastate vgastate; 100 struct vgastate vgastate;
102 struct mutex open_lock;
103 u32 pseudo_palette[16]; 101 u32 pseudo_palette[16];
104 struct pci_dev *pci_dev; 102 struct pci_dev *pci_dev;
105 u32 Architecture; 103 u32 Architecture;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 9dbb5a5a267b..efe10ff86d63 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1004,15 +1004,12 @@ static int nvidiafb_open(struct fb_info *info, int user)
1004{ 1004{
1005 struct nvidia_par *par = info->par; 1005 struct nvidia_par *par = info->par;
1006 1006
1007 mutex_lock(&par->open_lock);
1008
1009 if (!par->open_count) { 1007 if (!par->open_count) {
1010 save_vga_x86(par); 1008 save_vga_x86(par);
1011 nvidia_save_vga(par, &par->initial_state); 1009 nvidia_save_vga(par, &par->initial_state);
1012 } 1010 }
1013 1011
1014 par->open_count++; 1012 par->open_count++;
1015 mutex_unlock(&par->open_lock);
1016 return 0; 1013 return 0;
1017} 1014}
1018 1015
@@ -1021,8 +1018,6 @@ static int nvidiafb_release(struct fb_info *info, int user)
1021 struct nvidia_par *par = info->par; 1018 struct nvidia_par *par = info->par;
1022 int err = 0; 1019 int err = 0;
1023 1020
1024 mutex_lock(&par->open_lock);
1025
1026 if (!par->open_count) { 1021 if (!par->open_count) {
1027 err = -EINVAL; 1022 err = -EINVAL;
1028 goto done; 1023 goto done;
@@ -1035,7 +1030,6 @@ static int nvidiafb_release(struct fb_info *info, int user)
1035 1030
1036 par->open_count--; 1031 par->open_count--;
1037done: 1032done:
1038 mutex_unlock(&par->open_lock);
1039 return err; 1033 return err;
1040} 1034}
1041 1035
@@ -1300,7 +1294,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1300 1294
1301 par = info->par; 1295 par = info->par;
1302 par->pci_dev = pd; 1296 par->pci_dev = pd;
1303 mutex_init(&par->open_lock);
1304 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL); 1297 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
1305 1298
1306 if (info->pixmap.addr == NULL) 1299 if (info->pixmap.addr == NULL)
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index f24df0b54e1c..8aa6e47202b9 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -742,7 +742,7 @@ static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
742 if (calc_reg_timing(sysclk, div) == 0) 742 if (calc_reg_timing(sysclk, div) == 0)
743 break; 743 break;
744 } 744 }
745 if (div > max_clk_div) 745 if (div >= max_clk_div)
746 goto err; 746 goto err;
747 747
748 *extif_mem_div = div; 748 *extif_mem_div = div;
@@ -752,7 +752,7 @@ static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
752 break; 752 break;
753 } 753 }
754 754
755 if (div > max_clk_div) 755 if (div >= max_clk_div)
756 goto err; 756 goto err;
757 757
758 return 0; 758 return 0;
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 1a49519dafa4..060d72fe57cb 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -338,7 +338,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
338 338
339 omapfb_rqueue_lock(fbdev); 339 omapfb_rqueue_lock(fbdev);
340 switch (blank) { 340 switch (blank) {
341 case VESA_NO_BLANKING: 341 case FB_BLANK_UNBLANK:
342 if (fbdev->state == OMAPFB_SUSPENDED) { 342 if (fbdev->state == OMAPFB_SUSPENDED) {
343 if (fbdev->ctrl->resume) 343 if (fbdev->ctrl->resume)
344 fbdev->ctrl->resume(); 344 fbdev->ctrl->resume();
@@ -349,7 +349,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
349 do_update = 1; 349 do_update = 1;
350 } 350 }
351 break; 351 break;
352 case VESA_POWERDOWN: 352 case FB_BLANK_POWERDOWN:
353 if (fbdev->state == OMAPFB_ACTIVE) { 353 if (fbdev->state == OMAPFB_ACTIVE) {
354 fbdev->panel->disable(fbdev->panel); 354 fbdev->panel->disable(fbdev->panel);
355 if (fbdev->ctrl->suspend) 355 if (fbdev->ctrl->suspend)
@@ -1818,7 +1818,7 @@ static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg)
1818{ 1818{
1819 struct omapfb_device *fbdev = platform_get_drvdata(pdev); 1819 struct omapfb_device *fbdev = platform_get_drvdata(pdev);
1820 1820
1821 omapfb_blank(VESA_POWERDOWN, fbdev->fb_info[0]); 1821 omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
1822 1822
1823 return 0; 1823 return 0;
1824} 1824}
@@ -1828,7 +1828,7 @@ static int omapfb_resume(struct platform_device *pdev)
1828{ 1828{
1829 struct omapfb_device *fbdev = platform_get_drvdata(pdev); 1829 struct omapfb_device *fbdev = platform_get_drvdata(pdev);
1830 1830
1831 omapfb_blank(VESA_NO_BLANKING, fbdev->fb_info[0]); 1831 omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
1832 return 0; 1832 return 0;
1833} 1833}
1834 1834
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index a7b01d2724b5..0726aecf3b7e 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -50,9 +50,22 @@
50#define dbg(fmt, args...) do { } while (0) 50#define dbg(fmt, args...) do { } while (0)
51#endif 51#endif
52 52
53static const int __devinitconst s1d13xxxfb_revisions[] = { 53/*
54 S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */ 54 * List of card production ids
55 S1D13806_CHIP_REV, /* Rev.7 on .. */ 55 */
56static const int s1d13xxxfb_prod_ids[] = {
57 S1D13505_PROD_ID,
58 S1D13506_PROD_ID,
59 S1D13806_PROD_ID,
60};
61
62/*
63 * List of card strings
64 */
65static const char *s1d13xxxfb_prod_names[] = {
66 "S1D13505",
67 "S1D13506",
68 "S1D13806",
56}; 69};
57 70
58/* 71/*
@@ -377,7 +390,6 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
377 return 0; 390 return 0;
378} 391}
379 392
380
381/* framebuffer information structures */ 393/* framebuffer information structures */
382 394
383static struct fb_ops s1d13xxxfb_fbops = { 395static struct fb_ops s1d13xxxfb_fbops = {
@@ -544,7 +556,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
544 struct s1d13xxxfb_pdata *pdata = NULL; 556 struct s1d13xxxfb_pdata *pdata = NULL;
545 int ret = 0; 557 int ret = 0;
546 int i; 558 int i;
547 u8 revision; 559 u8 revision, prod_id;
548 560
549 dbg("probe called: device is %p\n", pdev); 561 dbg("probe called: device is %p\n", pdev);
550 562
@@ -613,19 +625,31 @@ s1d13xxxfb_probe(struct platform_device *pdev)
613 goto bail; 625 goto bail;
614 } 626 }
615 627
616 revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2; 628 /* production id is top 6 bits */
617 629 prod_id = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
630 /* revision id is lower 2 bits */
631 revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) & 0x3;
618 ret = -ENODEV; 632 ret = -ENODEV;
619 633
620 for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) { 634 for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_prod_ids); i++) {
621 if (revision == s1d13xxxfb_revisions[i]) 635 if (prod_id == s1d13xxxfb_prod_ids[i]) {
636 /* looks like we got it in our list */
637 default_par->prod_id = prod_id;
638 default_par->revision = revision;
622 ret = 0; 639 ret = 0;
640 break;
641 }
623 } 642 }
624 643
625 if (!ret) 644 if (!ret) {
645 printk(KERN_INFO PFX "chip production id %i = %s\n",
646 prod_id, s1d13xxxfb_prod_names[i]);
626 printk(KERN_INFO PFX "chip revision %i\n", revision); 647 printk(KERN_INFO PFX "chip revision %i\n", revision);
627 else { 648 } else {
628 printk(KERN_INFO PFX "unknown chip revision %i\n", revision); 649 printk(KERN_INFO PFX
650 "unknown chip production id %i, revision %i\n",
651 prod_id, revision);
652 printk(KERN_INFO PFX "please contant maintainer\n");
629 goto bail; 653 goto bail;
630 } 654 }
631 655
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
new file mode 100644
index 000000000000..5e9c6302433b
--- /dev/null
+++ b/drivers/video/s3c-fb.c
@@ -0,0 +1,1036 @@
1/* linux/drivers/video/s3c-fb.c
2 *
3 * Copyright 2008 Openmoko Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * Samsung SoC Framebuffer driver
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <linux/init.h>
20#include <linux/gfp.h>
21#include <linux/clk.h>
22#include <linux/fb.h>
23#include <linux/io.h>
24
25#include <mach/map.h>
26#include <mach/regs-fb.h>
27#include <plat/fb.h>
28
29/* This driver will export a number of framebuffer interfaces depending
30 * on the configuration passed in via the platform data. Each fb instance
31 * maps to a hardware window. Currently there is no support for runtime
32 * setting of the alpha-blending functions that each window has, so only
33 * window 0 is actually useful.
34 *
35 * Window 0 is treated specially, it is used for the basis of the LCD
36 * output timings and as the control for the output power-down state.
37*/
38
39/* note, some of the functions that get called are derived from including
40 * <mach/regs-fb.h> as they are specific to the architecture that the code
41 * is being built for.
42*/
43
44#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE
45#undef writel
46#define writel(v, r) do { \
47 printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
48 __raw_writel(v, r); } while(0)
49#endif /* FB_S3C_DEBUG_REGWRITE */
50
51struct s3c_fb;
52
53/**
54 * struct s3c_fb_win - per window private data for each framebuffer.
55 * @windata: The platform data supplied for the window configuration.
56 * @parent: The hardware that this window is part of.
57 * @fbinfo: Pointer pack to the framebuffer info for this window.
58 * @palette_buffer: Buffer/cache to hold palette entries.
59 * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/
60 * @index: The window number of this window.
61 * @palette: The bitfields for changing r/g/b into a hardware palette entry.
62 */
63struct s3c_fb_win {
64 struct s3c_fb_pd_win *windata;
65 struct s3c_fb *parent;
66 struct fb_info *fbinfo;
67 struct s3c_fb_palette palette;
68
69 u32 *palette_buffer;
70 u32 pseudo_palette[16];
71 unsigned int index;
72};
73
74/**
75 * struct s3c_fb - overall hardware state of the hardware
76 * @dev: The device that we bound to, for printing, etc.
77 * @regs_res: The resource we claimed for the IO registers.
78 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
79 * @regs: The mapped hardware registers.
80 * @enabled: A bitmask of enabled hardware windows.
81 * @pdata: The platform configuration data passed with the device.
82 * @windows: The hardware windows that have been claimed.
83 */
84struct s3c_fb {
85 struct device *dev;
86 struct resource *regs_res;
87 struct clk *bus_clk;
88 void __iomem *regs;
89
90 unsigned char enabled;
91
92 struct s3c_fb_platdata *pdata;
93 struct s3c_fb_win *windows[S3C_FB_MAX_WIN];
94};
95
96/**
97 * s3c_fb_win_has_palette() - determine if a mode has a palette
98 * @win: The window number being queried.
99 * @bpp: The number of bits per pixel to test.
100 *
101 * Work out if the given window supports palletised data at the specified bpp.
102 */
103static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp)
104{
105 return s3c_fb_win_pal_size(win) <= (1 << bpp);
106}
107
108/**
109 * s3c_fb_check_var() - framebuffer layer request to verify a given mode.
110 * @var: The screen information to verify.
111 * @info: The framebuffer device.
112 *
113 * Framebuffer layer call to verify the given information and allow us to
114 * update various information depending on the hardware capabilities.
115 */
116static int s3c_fb_check_var(struct fb_var_screeninfo *var,
117 struct fb_info *info)
118{
119 struct s3c_fb_win *win = info->par;
120 struct s3c_fb_pd_win *windata = win->windata;
121 struct s3c_fb *sfb = win->parent;
122
123 dev_dbg(sfb->dev, "checking parameters\n");
124
125 var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres);
126 var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres);
127
128 if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) {
129 dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n",
130 win->index, var->bits_per_pixel);
131 return -EINVAL;
132 }
133
134 /* always ensure these are zero, for drop through cases below */
135 var->transp.offset = 0;
136 var->transp.length = 0;
137
138 switch (var->bits_per_pixel) {
139 case 1:
140 case 2:
141 case 4:
142 case 8:
143 if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) {
144 /* non palletised, A:1,R:2,G:3,B:2 mode */
145 var->red.offset = 4;
146 var->green.offset = 2;
147 var->blue.offset = 0;
148 var->red.length = 5;
149 var->green.length = 3;
150 var->blue.length = 2;
151 var->transp.offset = 7;
152 var->transp.length = 1;
153 } else {
154 var->red.offset = 0;
155 var->red.length = var->bits_per_pixel;
156 var->green = var->red;
157 var->blue = var->red;
158 }
159 break;
160
161 case 19:
162 /* 666 with one bit alpha/transparency */
163 var->transp.offset = 18;
164 var->transp.length = 1;
165 case 18:
166 var->bits_per_pixel = 32;
167
168 /* 666 format */
169 var->red.offset = 12;
170 var->green.offset = 6;
171 var->blue.offset = 0;
172 var->red.length = 6;
173 var->green.length = 6;
174 var->blue.length = 6;
175 break;
176
177 case 16:
178 /* 16 bpp, 565 format */
179 var->red.offset = 11;
180 var->green.offset = 5;
181 var->blue.offset = 0;
182 var->red.length = 5;
183 var->green.length = 6;
184 var->blue.length = 5;
185 break;
186
187 case 28:
188 case 25:
189 var->transp.length = var->bits_per_pixel - 24;
190 var->transp.offset = 24;
191 /* drop through */
192 case 24:
193 /* our 24bpp is unpacked, so 32bpp */
194 var->bits_per_pixel = 32;
195 case 32:
196 var->red.offset = 16;
197 var->red.length = 8;
198 var->green.offset = 8;
199 var->green.length = 8;
200 var->blue.offset = 0;
201 var->blue.length = 8;
202 break;
203
204 default:
205 dev_err(sfb->dev, "invalid bpp\n");
206 }
207
208 dev_dbg(sfb->dev, "%s: verified parameters\n", __func__);
209 return 0;
210}
211
212/**
213 * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
214 * @sfb: The hardware state.
215 * @pixclock: The pixel clock wanted, in picoseconds.
216 *
217 * Given the specified pixel clock, work out the necessary divider to get
218 * close to the output frequency.
219 */
220static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
221{
222 unsigned long clk = clk_get_rate(sfb->bus_clk);
223 unsigned long long tmp;
224 unsigned int result;
225
226 tmp = (unsigned long long)clk;
227 tmp *= pixclk;
228
229 do_div(tmp, 1000000000UL);
230 result = (unsigned int)tmp / 1000;
231
232 dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
233 pixclk, clk, result, clk / result);
234
235 return result;
236}
237
238/**
239 * s3c_fb_align_word() - align pixel count to word boundary
240 * @bpp: The number of bits per pixel
241 * @pix: The value to be aligned.
242 *
243 * Align the given pixel count so that it will start on an 32bit word
244 * boundary.
245 */
246static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
247{
248 int pix_per_word;
249
250 if (bpp > 16)
251 return pix;
252
253 pix_per_word = (8 * 32) / bpp;
254 return ALIGN(pix, pix_per_word);
255}
256
257/**
258 * s3c_fb_set_par() - framebuffer request to set new framebuffer state.
259 * @info: The framebuffer to change.
260 *
261 * Framebuffer layer request to set a new mode for the specified framebuffer
262 */
263static int s3c_fb_set_par(struct fb_info *info)
264{
265 struct fb_var_screeninfo *var = &info->var;
266 struct s3c_fb_win *win = info->par;
267 struct s3c_fb *sfb = win->parent;
268 void __iomem *regs = sfb->regs;
269 int win_no = win->index;
270 u32 data;
271 u32 pagewidth;
272 int clkdiv;
273
274 dev_dbg(sfb->dev, "setting framebuffer parameters\n");
275
276 switch (var->bits_per_pixel) {
277 case 32:
278 case 24:
279 case 16:
280 case 12:
281 info->fix.visual = FB_VISUAL_TRUECOLOR;
282 break;
283 case 8:
284 if (s3c_fb_win_has_palette(win_no, 8))
285 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
286 else
287 info->fix.visual = FB_VISUAL_TRUECOLOR;
288 break;
289 case 1:
290 info->fix.visual = FB_VISUAL_MONO01;
291 break;
292 default:
293 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
294 break;
295 }
296
297 info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
298
299 /* disable the window whilst we update it */
300 writel(0, regs + WINCON(win_no));
301
302 /* use window 0 as the basis for the lcd output timings */
303
304 if (win_no == 0) {
305 clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
306
307 data = sfb->pdata->vidcon0;
308 data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
309
310 if (clkdiv > 1)
311 data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR;
312 else
313 data &= ~VIDCON0_CLKDIR; /* 1:1 clock */
314
315 /* write the timing data to the panel */
316
317 data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
318 writel(data, regs + VIDCON0);
319
320 data = VIDTCON0_VBPD(var->upper_margin - 1) |
321 VIDTCON0_VFPD(var->lower_margin - 1) |
322 VIDTCON0_VSPW(var->vsync_len - 1);
323
324 writel(data, regs + VIDTCON0);
325
326 data = VIDTCON1_HBPD(var->left_margin - 1) |
327 VIDTCON1_HFPD(var->right_margin - 1) |
328 VIDTCON1_HSPW(var->hsync_len - 1);
329
330 writel(data, regs + VIDTCON1);
331
332 data = VIDTCON2_LINEVAL(var->yres - 1) |
333 VIDTCON2_HOZVAL(var->xres - 1);
334 writel(data, regs + VIDTCON2);
335 }
336
337 /* write the buffer address */
338
339 writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no));
340
341 data = info->fix.smem_start + info->fix.line_length * var->yres;
342 writel(data, regs + VIDW_BUF_END(win_no));
343
344 pagewidth = (var->xres * var->bits_per_pixel) >> 3;
345 data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
346 VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
347 writel(data, regs + VIDW_BUF_SIZE(win_no));
348
349 /* write 'OSD' registers to control position of framebuffer */
350
351 data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
352 writel(data, regs + VIDOSD_A(win_no));
353
354 data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
355 var->xres - 1)) |
356 VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
357
358 writel(data, regs + VIDOSD_B(win_no));
359
360 data = var->xres * var->yres;
361 if (s3c_fb_has_osd_d(win_no)) {
362 writel(data, regs + VIDOSD_D(win_no));
363 writel(0, regs + VIDOSD_C(win_no));
364 } else
365 writel(data, regs + VIDOSD_C(win_no));
366
367 data = WINCONx_ENWIN;
368
369 /* note, since we have to round up the bits-per-pixel, we end up
370 * relying on the bitfield information for r/g/b/a to work out
371 * exactly which mode of operation is intended. */
372
373 switch (var->bits_per_pixel) {
374 case 1:
375 data |= WINCON0_BPPMODE_1BPP;
376 data |= WINCONx_BITSWP;
377 data |= WINCONx_BURSTLEN_4WORD;
378 break;
379 case 2:
380 data |= WINCON0_BPPMODE_2BPP;
381 data |= WINCONx_BITSWP;
382 data |= WINCONx_BURSTLEN_8WORD;
383 break;
384 case 4:
385 data |= WINCON0_BPPMODE_4BPP;
386 data |= WINCONx_BITSWP;
387 data |= WINCONx_BURSTLEN_8WORD;
388 break;
389 case 8:
390 if (var->transp.length != 0)
391 data |= WINCON1_BPPMODE_8BPP_1232;
392 else
393 data |= WINCON0_BPPMODE_8BPP_PALETTE;
394 data |= WINCONx_BURSTLEN_8WORD;
395 data |= WINCONx_BYTSWP;
396 break;
397 case 16:
398 if (var->transp.length != 0)
399 data |= WINCON1_BPPMODE_16BPP_A1555;
400 else
401 data |= WINCON0_BPPMODE_16BPP_565;
402 data |= WINCONx_HAWSWP;
403 data |= WINCONx_BURSTLEN_16WORD;
404 break;
405 case 24:
406 case 32:
407 if (var->red.length == 6) {
408 if (var->transp.length != 0)
409 data |= WINCON1_BPPMODE_19BPP_A1666;
410 else
411 data |= WINCON1_BPPMODE_18BPP_666;
412 } else if (var->transp.length != 0)
413 data |= WINCON1_BPPMODE_25BPP_A1888;
414 else
415 data |= WINCON0_BPPMODE_24BPP_888;
416
417 data |= WINCONx_BURSTLEN_16WORD;
418 break;
419 }
420
421 writel(data, regs + WINCON(win_no));
422 writel(0x0, regs + WINxMAP(win_no));
423
424 return 0;
425}
426
427/**
428 * s3c_fb_update_palette() - set or schedule a palette update.
429 * @sfb: The hardware information.
430 * @win: The window being updated.
431 * @reg: The palette index being changed.
432 * @value: The computed palette value.
433 *
434 * Change the value of a palette register, either by directly writing to
435 * the palette (this requires the palette RAM to be disconnected from the
436 * hardware whilst this is in progress) or schedule the update for later.
437 *
438 * At the moment, since we have no VSYNC interrupt support, we simply set
439 * the palette entry directly.
440 */
441static void s3c_fb_update_palette(struct s3c_fb *sfb,
442 struct s3c_fb_win *win,
443 unsigned int reg,
444 u32 value)
445{
446 void __iomem *palreg;
447 u32 palcon;
448
449 palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg);
450
451 dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n",
452 __func__, win->index, reg, palreg, value);
453
454 win->palette_buffer[reg] = value;
455
456 palcon = readl(sfb->regs + WPALCON);
457 writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON);
458
459 if (s3c_fb_pal_is16(win->index))
460 writew(value, palreg);
461 else
462 writel(value, palreg);
463
464 writel(palcon, sfb->regs + WPALCON);
465}
466
467static inline unsigned int chan_to_field(unsigned int chan,
468 struct fb_bitfield *bf)
469{
470 chan &= 0xffff;
471 chan >>= 16 - bf->length;
472 return chan << bf->offset;
473}
474
475/**
476 * s3c_fb_setcolreg() - framebuffer layer request to change palette.
477 * @regno: The palette index to change.
478 * @red: The red field for the palette data.
479 * @green: The green field for the palette data.
480 * @blue: The blue field for the palette data.
481 * @trans: The transparency (alpha) field for the palette data.
482 * @info: The framebuffer being changed.
483 */
484static int s3c_fb_setcolreg(unsigned regno,
485 unsigned red, unsigned green, unsigned blue,
486 unsigned transp, struct fb_info *info)
487{
488 struct s3c_fb_win *win = info->par;
489 struct s3c_fb *sfb = win->parent;
490 unsigned int val;
491
492 dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n",
493 __func__, win->index, regno, red, green, blue);
494
495 switch (info->fix.visual) {
496 case FB_VISUAL_TRUECOLOR:
497 /* true-colour, use pseudo-palette */
498
499 if (regno < 16) {
500 u32 *pal = info->pseudo_palette;
501
502 val = chan_to_field(red, &info->var.red);
503 val |= chan_to_field(green, &info->var.green);
504 val |= chan_to_field(blue, &info->var.blue);
505
506 pal[regno] = val;
507 }
508 break;
509
510 case FB_VISUAL_PSEUDOCOLOR:
511 if (regno < s3c_fb_win_pal_size(win->index)) {
512 val = chan_to_field(red, &win->palette.r);
513 val |= chan_to_field(green, &win->palette.g);
514 val |= chan_to_field(blue, &win->palette.b);
515
516 s3c_fb_update_palette(sfb, win, regno, val);
517 }
518
519 break;
520
521 default:
522 return 1; /* unknown type */
523 }
524
525 return 0;
526}
527
528/**
529 * s3c_fb_enable() - Set the state of the main LCD output
530 * @sfb: The main framebuffer state.
531 * @enable: The state to set.
532 */
533static void s3c_fb_enable(struct s3c_fb *sfb, int enable)
534{
535 u32 vidcon0 = readl(sfb->regs + VIDCON0);
536
537 if (enable)
538 vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F;
539 else {
540 /* see the note in the framebuffer datasheet about
541 * why you cannot take both of these bits down at the
542 * same time. */
543
544 if (!(vidcon0 & VIDCON0_ENVID))
545 return;
546
547 vidcon0 |= VIDCON0_ENVID;
548 vidcon0 &= ~VIDCON0_ENVID_F;
549 }
550
551 writel(vidcon0, sfb->regs + VIDCON0);
552}
553
554/**
555 * s3c_fb_blank() - blank or unblank the given window
556 * @blank_mode: The blank state from FB_BLANK_*
557 * @info: The framebuffer to blank.
558 *
559 * Framebuffer layer request to change the power state.
560 */
561static int s3c_fb_blank(int blank_mode, struct fb_info *info)
562{
563 struct s3c_fb_win *win = info->par;
564 struct s3c_fb *sfb = win->parent;
565 unsigned int index = win->index;
566 u32 wincon;
567
568 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
569
570 wincon = readl(sfb->regs + WINCON(index));
571
572 switch (blank_mode) {
573 case FB_BLANK_POWERDOWN:
574 wincon &= ~WINCONx_ENWIN;
575 sfb->enabled &= ~(1 << index);
576 /* fall through to FB_BLANK_NORMAL */
577
578 case FB_BLANK_NORMAL:
579 /* disable the DMA and display 0x0 (black) */
580 writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
581 sfb->regs + WINxMAP(index));
582 break;
583
584 case FB_BLANK_UNBLANK:
585 writel(0x0, sfb->regs + WINxMAP(index));
586 wincon |= WINCONx_ENWIN;
587 sfb->enabled |= (1 << index);
588 break;
589
590 case FB_BLANK_VSYNC_SUSPEND:
591 case FB_BLANK_HSYNC_SUSPEND:
592 default:
593 return 1;
594 }
595
596 writel(wincon, sfb->regs + WINCON(index));
597
598 /* Check the enabled state to see if we need to be running the
599 * main LCD interface, as if there are no active windows then
600 * it is highly likely that we also do not need to output
601 * anything.
602 */
603
604 /* We could do something like the following code, but the current
605 * system of using framebuffer events means that we cannot make
606 * the distinction between just window 0 being inactive and all
607 * the windows being down.
608 *
609 * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0);
610 */
611
612 /* we're stuck with this until we can do something about overriding
613 * the power control using the blanking event for a single fb.
614 */
615 if (index == 0)
616 s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0);
617
618 return 0;
619}
620
621static struct fb_ops s3c_fb_ops = {
622 .owner = THIS_MODULE,
623 .fb_check_var = s3c_fb_check_var,
624 .fb_set_par = s3c_fb_set_par,
625 .fb_blank = s3c_fb_blank,
626 .fb_setcolreg = s3c_fb_setcolreg,
627 .fb_fillrect = cfb_fillrect,
628 .fb_copyarea = cfb_copyarea,
629 .fb_imageblit = cfb_imageblit,
630};
631
632/**
633 * s3c_fb_alloc_memory() - allocate display memory for framebuffer window
634 * @sfb: The base resources for the hardware.
635 * @win: The window to initialise memory for.
636 *
637 * Allocate memory for the given framebuffer.
638 */
639static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb,
640 struct s3c_fb_win *win)
641{
642 struct s3c_fb_pd_win *windata = win->windata;
643 unsigned int real_size, virt_size, size;
644 struct fb_info *fbi = win->fbinfo;
645 dma_addr_t map_dma;
646
647 dev_dbg(sfb->dev, "allocating memory for display\n");
648
649 real_size = windata->win_mode.xres * windata->win_mode.yres;
650 virt_size = windata->virtual_x * windata->virtual_y;
651
652 dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n",
653 real_size, windata->win_mode.xres, windata->win_mode.yres,
654 virt_size, windata->virtual_x, windata->virtual_y);
655
656 size = (real_size > virt_size) ? real_size : virt_size;
657 size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp;
658 size /= 8;
659
660 fbi->fix.smem_len = size;
661 size = PAGE_ALIGN(size);
662
663 dev_dbg(sfb->dev, "want %u bytes for window\n", size);
664
665 fbi->screen_base = dma_alloc_writecombine(sfb->dev, size,
666 &map_dma, GFP_KERNEL);
667 if (!fbi->screen_base)
668 return -ENOMEM;
669
670 dev_dbg(sfb->dev, "mapped %x to %p\n",
671 (unsigned int)map_dma, fbi->screen_base);
672
673 memset(fbi->screen_base, 0x0, size);
674 fbi->fix.smem_start = map_dma;
675
676 return 0;
677}
678
679/**
680 * s3c_fb_free_memory() - free the display memory for the given window
681 * @sfb: The base resources for the hardware.
682 * @win: The window to free the display memory for.
683 *
684 * Free the display memory allocated by s3c_fb_alloc_memory().
685 */
686static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
687{
688 struct fb_info *fbi = win->fbinfo;
689
690 dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
691 fbi->screen_base, fbi->fix.smem_start);
692}
693
694/**
695 * s3c_fb_release_win() - release resources for a framebuffer window.
696 * @win: The window to cleanup the resources for.
697 *
698 * Release the resources that where claimed for the hardware window,
699 * such as the framebuffer instance and any memory claimed for it.
700 */
701static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
702{
703 fb_dealloc_cmap(&win->fbinfo->cmap);
704 unregister_framebuffer(win->fbinfo);
705 s3c_fb_free_memory(sfb, win);
706}
707
708/**
709 * s3c_fb_probe_win() - register an hardware window
710 * @sfb: The base resources for the hardware
711 * @res: Pointer to where to place the resultant window.
712 *
713 * Allocate and do the basic initialisation for one of the hardware's graphics
714 * windows.
715 */
716static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
717 struct s3c_fb_win **res)
718{
719 struct fb_var_screeninfo *var;
720 struct fb_videomode *initmode;
721 struct s3c_fb_pd_win *windata;
722 struct s3c_fb_win *win;
723 struct fb_info *fbinfo;
724 int palette_size;
725 int ret;
726
727 dev_dbg(sfb->dev, "probing window %d\n", win_no);
728
729 palette_size = s3c_fb_win_pal_size(win_no);
730
731 fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
732 palette_size * sizeof(u32), sfb->dev);
733 if (!fbinfo) {
734 dev_err(sfb->dev, "failed to allocate framebuffer\n");
735 return -ENOENT;
736 }
737
738 windata = sfb->pdata->win[win_no];
739 initmode = &windata->win_mode;
740
741 WARN_ON(windata->max_bpp == 0);
742 WARN_ON(windata->win_mode.xres == 0);
743 WARN_ON(windata->win_mode.yres == 0);
744
745 win = fbinfo->par;
746 var = &fbinfo->var;
747 win->fbinfo = fbinfo;
748 win->parent = sfb;
749 win->windata = windata;
750 win->index = win_no;
751 win->palette_buffer = (u32 *)(win + 1);
752
753 ret = s3c_fb_alloc_memory(sfb, win);
754 if (ret) {
755 dev_err(sfb->dev, "failed to allocate display memory\n");
756 goto err_framebuffer;
757 }
758
759 /* setup the r/b/g positions for the window's palette */
760 s3c_fb_init_palette(win_no, &win->palette);
761
762 /* setup the initial video mode from the window */
763 fb_videomode_to_var(&fbinfo->var, initmode);
764
765 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
766 fbinfo->fix.accel = FB_ACCEL_NONE;
767 fbinfo->var.activate = FB_ACTIVATE_NOW;
768 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
769 fbinfo->var.bits_per_pixel = windata->default_bpp;
770 fbinfo->fbops = &s3c_fb_ops;
771 fbinfo->flags = FBINFO_FLAG_DEFAULT;
772 fbinfo->pseudo_palette = &win->pseudo_palette;
773
774 /* prepare to actually start the framebuffer */
775
776 ret = s3c_fb_check_var(&fbinfo->var, fbinfo);
777 if (ret < 0) {
778 dev_err(sfb->dev, "check_var failed on initial video params\n");
779 goto err_alloc_mem;
780 }
781
782 /* create initial colour map */
783
784 ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1);
785 if (ret == 0)
786 fb_set_cmap(&fbinfo->cmap, fbinfo);
787 else
788 dev_err(sfb->dev, "failed to allocate fb cmap\n");
789
790 s3c_fb_set_par(fbinfo);
791
792 dev_dbg(sfb->dev, "about to register framebuffer\n");
793
794 /* run the check_var and set_par on our configuration. */
795
796 ret = register_framebuffer(fbinfo);
797 if (ret < 0) {
798 dev_err(sfb->dev, "failed to register framebuffer\n");
799 goto err_alloc_mem;
800 }
801
802 *res = win;
803 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);
804
805 return 0;
806
807err_alloc_mem:
808 s3c_fb_free_memory(sfb, win);
809
810err_framebuffer:
811 unregister_framebuffer(fbinfo);
812 return ret;
813}
814
815/**
816 * s3c_fb_clear_win() - clear hardware window registers.
817 * @sfb: The base resources for the hardware.
818 * @win: The window to process.
819 *
820 * Reset the specific window registers to a known state.
821 */
822static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
823{
824 void __iomem *regs = sfb->regs;
825
826 writel(0, regs + WINCON(win));
827 writel(0xffffff, regs + WxKEYCONy(win, 0));
828 writel(0xffffff, regs + WxKEYCONy(win, 1));
829
830 writel(0, regs + VIDOSD_A(win));
831 writel(0, regs + VIDOSD_B(win));
832 writel(0, regs + VIDOSD_C(win));
833}
834
835static int __devinit s3c_fb_probe(struct platform_device *pdev)
836{
837 struct device *dev = &pdev->dev;
838 struct s3c_fb_platdata *pd;
839 struct s3c_fb *sfb;
840 struct resource *res;
841 int win;
842 int ret = 0;
843
844 pd = pdev->dev.platform_data;
845 if (!pd) {
846 dev_err(dev, "no platform data specified\n");
847 return -EINVAL;
848 }
849
850 sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
851 if (!sfb) {
852 dev_err(dev, "no memory for framebuffers\n");
853 return -ENOMEM;
854 }
855
856 sfb->dev = dev;
857 sfb->pdata = pd;
858
859 sfb->bus_clk = clk_get(dev, "lcd");
860 if (IS_ERR(sfb->bus_clk)) {
861 dev_err(dev, "failed to get bus clock\n");
862 goto err_sfb;
863 }
864
865 clk_enable(sfb->bus_clk);
866
867 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
868 if (!res) {
869 dev_err(dev, "failed to find registers\n");
870 ret = -ENOENT;
871 goto err_clk;
872 }
873
874 sfb->regs_res = request_mem_region(res->start, resource_size(res),
875 dev_name(dev));
876 if (!sfb->regs_res) {
877 dev_err(dev, "failed to claim register region\n");
878 ret = -ENOENT;
879 goto err_clk;
880 }
881
882 sfb->regs = ioremap(res->start, resource_size(res));
883 if (!sfb->regs) {
884 dev_err(dev, "failed to map registers\n");
885 ret = -ENXIO;
886 goto err_req_region;
887 }
888
889 dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
890
891 /* setup gpio and output polarity controls */
892
893 pd->setup_gpio();
894
895 writel(pd->vidcon1, sfb->regs + VIDCON1);
896
897 /* zero all windows before we do anything */
898
899 for (win = 0; win < S3C_FB_MAX_WIN; win++)
900 s3c_fb_clear_win(sfb, win);
901
902 /* we have the register setup, start allocating framebuffers */
903
904 for (win = 0; win < S3C_FB_MAX_WIN; win++) {
905 if (!pd->win[win])
906 continue;
907
908 ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]);
909 if (ret < 0) {
910 dev_err(dev, "failed to create window %d\n", win);
911 for (; win >= 0; win--)
912 s3c_fb_release_win(sfb, sfb->windows[win]);
913 goto err_ioremap;
914 }
915 }
916
917 platform_set_drvdata(pdev, sfb);
918
919 return 0;
920
921err_ioremap:
922 iounmap(sfb->regs);
923
924err_req_region:
925 release_resource(sfb->regs_res);
926 kfree(sfb->regs_res);
927
928err_clk:
929 clk_disable(sfb->bus_clk);
930 clk_put(sfb->bus_clk);
931
932err_sfb:
933 kfree(sfb);
934 return ret;
935}
936
937/**
938 * s3c_fb_remove() - Cleanup on module finalisation
939 * @pdev: The platform device we are bound to.
940 *
941 * Shutdown and then release all the resources that the driver allocated
942 * on initialisation.
943 */
944static int __devexit s3c_fb_remove(struct platform_device *pdev)
945{
946 struct s3c_fb *sfb = platform_get_drvdata(pdev);
947 int win;
948
949 for (win = 0; win <= S3C_FB_MAX_WIN; win++)
950 s3c_fb_release_win(sfb, sfb->windows[win]);
951
952 iounmap(sfb->regs);
953
954 clk_disable(sfb->bus_clk);
955 clk_put(sfb->bus_clk);
956
957 release_resource(sfb->regs_res);
958 kfree(sfb->regs_res);
959
960 kfree(sfb);
961
962 return 0;
963}
964
965#ifdef CONFIG_PM
966static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state)
967{
968 struct s3c_fb *sfb = platform_get_drvdata(pdev);
969 struct s3c_fb_win *win;
970 int win_no;
971
972 for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) {
973 win = sfb->windows[win_no];
974 if (!win)
975 continue;
976
977 /* use the blank function to push into power-down */
978 s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
979 }
980
981 clk_disable(sfb->bus_clk);
982 return 0;
983}
984
985static int s3c_fb_resume(struct platform_device *pdev)
986{
987 struct s3c_fb *sfb = platform_get_drvdata(pdev);
988 struct s3c_fb_win *win;
989 int win_no;
990
991 clk_enable(sfb->bus_clk);
992
993 for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
994 win = sfb->windows[win_no];
995 if (!win)
996 continue;
997
998 dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
999 s3c_fb_set_par(win->fbinfo);
1000 }
1001
1002 return 0;
1003}
1004#else
1005#define s3c_fb_suspend NULL
1006#define s3c_fb_resume NULL
1007#endif
1008
1009static struct platform_driver s3c_fb_driver = {
1010 .probe = s3c_fb_probe,
1011 .remove = s3c_fb_remove,
1012 .suspend = s3c_fb_suspend,
1013 .resume = s3c_fb_resume,
1014 .driver = {
1015 .name = "s3c-fb",
1016 .owner = THIS_MODULE,
1017 },
1018};
1019
1020static int __init s3c_fb_init(void)
1021{
1022 return platform_driver_register(&s3c_fb_driver);
1023}
1024
1025static void __exit s3c_fb_cleanup(void)
1026{
1027 platform_driver_unregister(&s3c_fb_driver);
1028}
1029
1030module_init(s3c_fb_init);
1031module_exit(s3c_fb_cleanup);
1032
1033MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
1034MODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver");
1035MODULE_LICENSE("GPL");
1036MODULE_ALIAS("platform:s3c-fb");
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index f5252c2552fd..bba53714a7b1 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -837,6 +837,8 @@ static int sgivwfb_remove(struct platform_device *dev)
837 iounmap(par->regs); 837 iounmap(par->regs);
838 iounmap(info->screen_base); 838 iounmap(info->screen_base);
839 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE); 839 release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
840 fb_dealloc_cmap(&info->cmap);
841 framebuffer_release(info);
840 } 842 }
841 return 0; 843 return 0;
842} 844}
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index df5336561d13..a439159204a8 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -795,8 +795,9 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
795 if (!retval || retval == 4) 795 if (!retval || retval == 4)
796 return -EINVAL; 796 return -EINVAL;
797 797
798 /* This has to been done !!! */ 798 /* This has to be done! */
799 fb_alloc_cmap(&info->cmap, cmap_len, 0); 799 if (fb_alloc_cmap(&info->cmap, cmap_len, 0))
800 return -ENOMEM;
800 801
801 /* 802 /*
802 * The following is done in the case of having hardware with a static 803 * The following is done in the case of having hardware with a static
@@ -820,8 +821,10 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
820 */ 821 */
821 /* xxxfb_set_par(info); */ 822 /* xxxfb_set_par(info); */
822 823
823 if (register_framebuffer(info) < 0) 824 if (register_framebuffer(info) < 0) {
825 fb_dealloc_cmap(&info->cmap);
824 return -EINVAL; 826 return -EINVAL;
827 }
825 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, 828 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
826 info->fix.id); 829 info->fix.id);
827 pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */ 830 pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index dcd98793d568..eb5d73a06702 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1525,7 +1525,10 @@ static int sm501fb_init_fb(struct fb_info *fb,
1525 } 1525 }
1526 1526
1527 /* initialise and set the palette */ 1527 /* initialise and set the palette */
1528 fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0); 1528 if (fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0)) {
1529 dev_err(info->dev, "failed to allocate cmap memory\n");
1530 return -ENOMEM;
1531 }
1529 fb_set_cmap(&fb->cmap, fb); 1532 fb_set_cmap(&fb->cmap, fb);
1530 1533
1531 ret = (fb->fbops->fb_check_var)(&fb->var, fb); 1534 ret = (fb->fbops->fb_check_var)(&fb->var, fb);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5b11a00f49bc..609d0a521ca2 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1421,13 +1421,16 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
1421 goto fail; 1421 goto fail;
1422 } 1422 }
1423 1423
1424 fb_alloc_cmap(&info->cmap, 256, 0); 1424 if (fb_alloc_cmap(&info->cmap, 256, 0)) {
1425 printk(KERN_ERR "sstfb: can't alloc cmap memory.\n");
1426 goto fail;
1427 }
1425 1428
1426 /* register fb */ 1429 /* register fb */
1427 info->device = &pdev->dev; 1430 info->device = &pdev->dev;
1428 if (register_framebuffer(info) < 0) { 1431 if (register_framebuffer(info) < 0) {
1429 printk(KERN_ERR "sstfb: can't register framebuffer.\n"); 1432 printk(KERN_ERR "sstfb: can't register framebuffer.\n");
1430 goto fail; 1433 goto fail_register;
1431 } 1434 }
1432 1435
1433 sstfb_clear_screen(info); 1436 sstfb_clear_screen(info);
@@ -1441,8 +1444,9 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
1441 1444
1442 return 0; 1445 return 0;
1443 1446
1444fail: 1447fail_register:
1445 fb_dealloc_cmap(&info->cmap); 1448 fb_dealloc_cmap(&info->cmap);
1449fail:
1446 iounmap(info->screen_base); 1450 iounmap(info->screen_base);
1447fail_fb_remap: 1451fail_fb_remap:
1448 iounmap(par->mmio_vbase); 1452 iounmap(par->mmio_vbase);
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 166481402412..eabaad765aeb 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1262,24 +1262,25 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1262 info->flags = FBINFO_DEFAULT; 1262 info->flags = FBINFO_DEFAULT;
1263 info->pseudo_palette = &fb->pseudo_palette; 1263 info->pseudo_palette = &fb->pseudo_palette;
1264 1264
1265 /* This has to been done !!! */ 1265 /* This has to be done !!! */
1266 fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); 1266 if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
1267 goto out_err1;
1267 stifb_init_display(fb); 1268 stifb_init_display(fb);
1268 1269
1269 if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) { 1270 if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
1270 printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n", 1271 printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
1271 fix->smem_start, fix->smem_start+fix->smem_len); 1272 fix->smem_start, fix->smem_start+fix->smem_len);
1272 goto out_err1; 1273 goto out_err2;
1273 } 1274 }
1274 1275
1275 if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) { 1276 if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
1276 printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n", 1277 printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
1277 fix->mmio_start, fix->mmio_start+fix->mmio_len); 1278 fix->mmio_start, fix->mmio_start+fix->mmio_len);
1278 goto out_err2; 1279 goto out_err3;
1279 } 1280 }
1280 1281
1281 if (register_framebuffer(&fb->info) < 0) 1282 if (register_framebuffer(&fb->info) < 0)
1282 goto out_err3; 1283 goto out_err4;
1283 1284
1284 sti->info = info; /* save for unregister_framebuffer() */ 1285 sti->info = info; /* save for unregister_framebuffer() */
1285 1286
@@ -1297,13 +1298,14 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1297 return 0; 1298 return 0;
1298 1299
1299 1300
1300out_err3: 1301out_err4:
1301 release_mem_region(fix->mmio_start, fix->mmio_len); 1302 release_mem_region(fix->mmio_start, fix->mmio_len);
1302out_err2: 1303out_err3:
1303 release_mem_region(fix->smem_start, fix->smem_len); 1304 release_mem_region(fix->smem_start, fix->smem_len);
1305out_err2:
1306 fb_dealloc_cmap(&info->cmap);
1304out_err1: 1307out_err1:
1305 iounmap(info->screen_base); 1308 iounmap(info->screen_base);
1306 fb_dealloc_cmap(&info->cmap);
1307out_err0: 1309out_err0:
1308 kfree(fb); 1310 kfree(fb);
1309 return -ENXIO; 1311 return -ENXIO;
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index c2ba51b7ea18..18b950706cad 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -349,11 +349,14 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
349 if (err < 0) { 349 if (err < 0) {
350 printk(KERN_ERR "e3d: Could not register framebuffer %s\n", 350 printk(KERN_ERR "e3d: Could not register framebuffer %s\n",
351 pci_name(pdev)); 351 pci_name(pdev));
352 goto err_unmap_fb; 352 goto err_free_cmap;
353 } 353 }
354 354
355 return 0; 355 return 0;
356 356
357err_free_cmap:
358 fb_dealloc_cmap(&info->cmap);
359
357err_unmap_fb: 360err_unmap_fb:
358 iounmap(ep->fb_base); 361 iounmap(ep->fb_base);
359 362
@@ -389,6 +392,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
389 pci_release_region(pdev, 0); 392 pci_release_region(pdev, 0);
390 pci_release_region(pdev, 1); 393 pci_release_region(pdev, 1);
391 394
395 fb_dealloc_cmap(&info->cmap);
392 framebuffer_release(info); 396 framebuffer_release(info);
393 397
394 pci_disable_device(pdev); 398 pci_disable_device(pdev);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 14bd3f3680b8..ee64771fbe3d 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1393,6 +1393,7 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
1393 release_mem_region(pci_resource_start(pdev, 0), 1393 release_mem_region(pci_resource_start(pdev, 0),
1394 pci_resource_len(pdev, 0)); 1394 pci_resource_len(pdev, 0));
1395 pci_set_drvdata(pdev, NULL); 1395 pci_set_drvdata(pdev, NULL);
1396 fb_dealloc_cmap(&info->cmap);
1396 framebuffer_release(info); 1397 framebuffer_release(info);
1397} 1398}
1398 1399
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 680642c089c9..a86046ff60ad 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -1663,7 +1663,7 @@ tgafb_register(struct device *dev)
1663 if (register_framebuffer(info) < 0) { 1663 if (register_framebuffer(info) < 0) {
1664 printk(KERN_ERR "tgafb: Could not register framebuffer\n"); 1664 printk(KERN_ERR "tgafb: Could not register framebuffer\n");
1665 ret = -EINVAL; 1665 ret = -EINVAL;
1666 goto err1; 1666 goto err2;
1667 } 1667 }
1668 1668
1669 if (tga_bus_pci) { 1669 if (tga_bus_pci) {
@@ -1682,6 +1682,8 @@ tgafb_register(struct device *dev)
1682 1682
1683 return 0; 1683 return 0;
1684 1684
1685 err2:
1686 fb_dealloc_cmap(&info->cmap);
1685 err1: 1687 err1:
1686 if (mem_base) 1688 if (mem_base)
1687 iounmap(mem_base); 1689 iounmap(mem_base);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 479b2e79ad68..03a9c35e9f55 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -2,7 +2,7 @@
2 * Frame buffer driver for Trident TGUI, Blade and Image series 2 * Frame buffer driver for Trident TGUI, Blade and Image series
3 * 3 *
4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro> 4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
5 * 5 * Copyright 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
6 * 6 *
7 * CREDITS:(in order of appearance) 7 * CREDITS:(in order of appearance)
8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video 8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
@@ -490,7 +490,6 @@ static void tgui_copy_rect(struct tridentfb_par *par,
490/* 490/*
491 * Accel functions called by the upper layers 491 * Accel functions called by the upper layers
492 */ 492 */
493#ifdef CONFIG_FB_TRIDENT_ACCEL
494static void tridentfb_fillrect(struct fb_info *info, 493static void tridentfb_fillrect(struct fb_info *info,
495 const struct fb_fillrect *fr) 494 const struct fb_fillrect *fr)
496{ 495{
@@ -565,11 +564,6 @@ static int tridentfb_sync(struct fb_info *info)
565 par->wait_engine(par); 564 par->wait_engine(par);
566 return 0; 565 return 0;
567} 566}
568#else
569#define tridentfb_fillrect cfb_fillrect
570#define tridentfb_copyarea cfb_copyarea
571#define tridentfb_imageblit cfb_imageblit
572#endif /* CONFIG_FB_TRIDENT_ACCEL */
573 567
574/* 568/*
575 * Hardware access functions 569 * Hardware access functions
@@ -1333,9 +1327,7 @@ static struct fb_ops tridentfb_ops = {
1333 .fb_fillrect = tridentfb_fillrect, 1327 .fb_fillrect = tridentfb_fillrect,
1334 .fb_copyarea = tridentfb_copyarea, 1328 .fb_copyarea = tridentfb_copyarea,
1335 .fb_imageblit = tridentfb_imageblit, 1329 .fb_imageblit = tridentfb_imageblit,
1336#ifdef CONFIG_FB_TRIDENT_ACCEL
1337 .fb_sync = tridentfb_sync, 1330 .fb_sync = tridentfb_sync,
1338#endif
1339}; 1331};
1340 1332
1341static int __devinit trident_pci_probe(struct pci_dev *dev, 1333static int __devinit trident_pci_probe(struct pci_dev *dev,
@@ -1359,10 +1351,6 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
1359 1351
1360 chip_id = id->device; 1352 chip_id = id->device;
1361 1353
1362#ifndef CONFIG_FB_TRIDENT_ACCEL
1363 noaccel = 1;
1364#endif
1365
1366 /* If PCI id is 0x9660 then further detect chip type */ 1354 /* If PCI id is 0x9660 then further detect chip type */
1367 1355
1368 if (chip_id == TGUI9660) { 1356 if (chip_id == TGUI9660) {
@@ -1490,6 +1478,9 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
1490 } else 1478 } else
1491 info->flags |= FBINFO_HWACCEL_DISABLED; 1479 info->flags |= FBINFO_HWACCEL_DISABLED;
1492 1480
1481 if (is_blade(chip_id) && chip_id != BLADE3D)
1482 info->flags |= FBINFO_READS_FAST;
1483
1493 info->pixmap.addr = kmalloc(4096, GFP_KERNEL); 1484 info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
1494 if (!info->pixmap.addr) { 1485 if (!info->pixmap.addr) {
1495 err = -ENOMEM; 1486 err = -ENOMEM;
@@ -1563,6 +1554,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev)
1563 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); 1554 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
1564 pci_set_drvdata(dev, NULL); 1555 pci_set_drvdata(dev, NULL);
1565 kfree(info->pixmap.addr); 1556 kfree(info->pixmap.addr);
1557 fb_dealloc_cmap(&info->cmap);
1566 framebuffer_release(info); 1558 framebuffer_release(info);
1567} 1559}
1568 1560
@@ -1663,4 +1655,5 @@ module_exit(tridentfb_exit);
1663MODULE_AUTHOR("Jani Monoses <jani@iv.ro>"); 1655MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");
1664MODULE_DESCRIPTION("Framebuffer driver for Trident cards"); 1656MODULE_DESCRIPTION("Framebuffer driver for Trident cards");
1665MODULE_LICENSE("GPL"); 1657MODULE_LICENSE("GPL");
1658MODULE_ALIAS("cyblafb");
1666 1659
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 74ae75899009..0b370aebdbfd 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -189,7 +189,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
189 uvfb_tasks[seq] = task; 189 uvfb_tasks[seq] = task;
190 mutex_unlock(&uvfb_lock); 190 mutex_unlock(&uvfb_lock);
191 191
192 err = cn_netlink_send(m, 0, gfp_any()); 192 err = cn_netlink_send(m, 0, GFP_KERNEL);
193 if (err == -ESRCH) { 193 if (err == -ESRCH) {
194 /* 194 /*
195 * Try to start the userspace helper if sending 195 * Try to start the userspace helper if sending
@@ -850,14 +850,16 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
850 if (vbemode) { 850 if (vbemode) {
851 for (i = 0; i < par->vbe_modes_cnt; i++) { 851 for (i = 0; i < par->vbe_modes_cnt; i++) {
852 if (par->vbe_modes[i].mode_id == vbemode) { 852 if (par->vbe_modes[i].mode_id == vbemode) {
853 modeid = i;
854 uvesafb_setup_var(&info->var, info,
855 &par->vbe_modes[modeid]);
853 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, 856 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
854 &info->var, info); 857 &info->var, info);
855 /* 858 /*
856 * With pixclock set to 0, the default BIOS 859 * With pixclock set to 0, the default BIOS
857 * timings will be used in set_par(). 860 * timings will be used in set_par().
858 */ 861 */
859 info->var.pixclock = 0; 862 info->var.pixclock = 0;
860 modeid = i;
861 goto gotmode; 863 goto gotmode;
862 } 864 }
863 } 865 }
@@ -904,8 +906,11 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
904 fb_videomode_to_var(&info->var, mode); 906 fb_videomode_to_var(&info->var, mode);
905 } else { 907 } else {
906 modeid = par->vbe_modes[0].mode_id; 908 modeid = par->vbe_modes[0].mode_id;
909 uvesafb_setup_var(&info->var, info,
910 &par->vbe_modes[modeid]);
907 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, 911 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
908 &info->var, info); 912 &info->var, info);
913
909 goto gotmode; 914 goto gotmode;
910 } 915 }
911 } 916 }
@@ -917,9 +922,9 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
917 if (modeid == -1) 922 if (modeid == -1)
918 return -EINVAL; 923 return -EINVAL;
919 924
920gotmode:
921 uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]); 925 uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
922 926
927gotmode:
923 /* 928 /*
924 * If we are not VBE3.0+ compliant, we're done -- the BIOS will 929 * If we are not VBE3.0+ compliant, we're done -- the BIOS will
925 * ignore our timings anyway. 930 * ignore our timings anyway.
@@ -1552,7 +1557,7 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
1552 } 1557 }
1553 1558
1554 info->flags = FBINFO_FLAG_DEFAULT | 1559 info->flags = FBINFO_FLAG_DEFAULT |
1555 (par->ypan) ? FBINFO_HWACCEL_YPAN : 0; 1560 (par->ypan ? FBINFO_HWACCEL_YPAN : 0);
1556 1561
1557 if (!par->ypan) 1562 if (!par->ypan)
1558 info->fbops->fb_pan_display = NULL; 1563 info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 7b0cef9ca8f9..4bb9a0b18950 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -119,7 +119,7 @@ static void set_valkyrie_clock(unsigned char *params);
119static int valkyrie_var_to_par(struct fb_var_screeninfo *var, 119static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
120 struct fb_par_valkyrie *par, const struct fb_info *fb_info); 120 struct fb_par_valkyrie *par, const struct fb_info *fb_info);
121 121
122static void valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p); 122static int valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
123static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix); 123static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix);
124static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p); 124static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p);
125 125
@@ -381,18 +381,22 @@ int __init valkyriefb_init(void)
381 381
382 valkyrie_choose_mode(p); 382 valkyrie_choose_mode(p);
383 mac_vmode_to_var(default_vmode, default_cmode, &p->info.var); 383 mac_vmode_to_var(default_vmode, default_cmode, &p->info.var);
384 valkyrie_init_info(&p->info, p); 384 err = valkyrie_init_info(&p->info, p);
385 if (err < 0)
386 goto out_free;
385 valkyrie_init_fix(&p->info.fix, p); 387 valkyrie_init_fix(&p->info.fix, p);
386 if (valkyriefb_set_par(&p->info)) 388 if (valkyriefb_set_par(&p->info))
387 /* "can't happen" */ 389 /* "can't happen" */
388 printk(KERN_ERR "valkyriefb: can't set default video mode\n"); 390 printk(KERN_ERR "valkyriefb: can't set default video mode\n");
389 391
390 if ((err = register_framebuffer(&p->info)) != 0) 392 if ((err = register_framebuffer(&p->info)) != 0)
391 goto out_free; 393 goto out_cmap_free;
392 394
393 printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node); 395 printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node);
394 return 0; 396 return 0;
395 397
398 out_cmap_free:
399 fb_dealloc_cmap(&p->info.cmap);
396 out_free: 400 out_free:
397 if (p->frame_buffer) 401 if (p->frame_buffer)
398 iounmap(p->frame_buffer); 402 iounmap(p->frame_buffer);
@@ -538,14 +542,15 @@ static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,
538 /* ywrapstep, xpanstep, ypanstep */ 542 /* ywrapstep, xpanstep, ypanstep */
539} 543}
540 544
541static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p) 545static int __init valkyrie_init_info(struct fb_info *info,
546 struct fb_info_valkyrie *p)
542{ 547{
543 info->fbops = &valkyriefb_ops; 548 info->fbops = &valkyriefb_ops;
544 info->screen_base = p->frame_buffer + 0x1000; 549 info->screen_base = p->frame_buffer + 0x1000;
545 info->flags = FBINFO_DEFAULT; 550 info->flags = FBINFO_DEFAULT;
546 info->pseudo_palette = p->pseudo_palette; 551 info->pseudo_palette = p->pseudo_palette;
547 fb_alloc_cmap(&info->cmap, 256, 0);
548 info->par = &p->par; 552 info->par = &p->par;
553 return fb_alloc_cmap(&info->cmap, 256, 0);
549} 554}
550 555
551 556
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index e16322d157d0..d6856f43d241 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -438,7 +438,7 @@ static int __init vesafb_probe(struct platform_device *dev)
438 info->var = vesafb_defined; 438 info->var = vesafb_defined;
439 info->fix = vesafb_fix; 439 info->fix = vesafb_fix;
440 info->flags = FBINFO_FLAG_DEFAULT | 440 info->flags = FBINFO_FLAG_DEFAULT |
441 (ypan) ? FBINFO_HWACCEL_YPAN : 0; 441 (ypan ? FBINFO_HWACCEL_YPAN : 0);
442 442
443 if (!ypan) 443 if (!ypan)
444 info->fbops->fb_pan_display = NULL; 444 info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 93fe08d6c78f..cc919ae46571 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -543,6 +543,7 @@ static int vfb_remove(struct platform_device *dev)
543 if (info) { 543 if (info) {
544 unregister_framebuffer(info); 544 unregister_framebuffer(info);
545 rvfree(videomemory, videomemorysize); 545 rvfree(videomemory, videomemorysize);
546 fb_dealloc_cmap(&info->cmap);
546 framebuffer_release(info); 547 framebuffer_release(info);
547 } 548 }
548 return 0; 549 return 0;
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 632523ff1fb7..45c54bfe99bb 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -267,13 +267,17 @@ int viafb_wait_engine_idle(void)
267 int loop = 0; 267 int loop = 0;
268 268
269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) & 269 while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
270 VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) 270 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
271 loop++;
271 cpu_relax(); 272 cpu_relax();
273 }
272 274
273 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) & 275 while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
274 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && 276 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
275 (loop++ < MAXLOOP)) 277 (loop < MAXLOOP)) {
278 loop++;
276 cpu_relax(); 279 cpu_relax();
280 }
277 281
278 return loop >= MAXLOOP; 282 return loop >= MAXLOOP;
279} 283}