aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-08-31 03:45:21 -0400
committerIngo Molnar <mingo@elte.hu>2010-08-31 03:45:46 -0400
commitdaab7fc734a53fdeaf844b7c03053118ad1769da (patch)
tree575deb3cdcc6dda562acaed6f7c29bc81ae01cf2 /drivers/video
parent774ea0bcb27f57b6fd521b3b6c43237782fed4b9 (diff)
parent2bfc96a127bc1cc94d26bfaa40159966064f9c8c (diff)
Merge commit 'v2.6.36-rc3' into x86/memblock
Conflicts: arch/x86/kernel/trampoline.c mm/memblock.c Merge reason: Resolve the conflicts, update to latest upstream. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig29
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/amba-clcd.c10
-rw-r--r--drivers/video/backlight/locomolcd.c4
-rw-r--r--drivers/video/bw2.c8
-rw-r--r--drivers/video/carminefb.c2
-rw-r--r--drivers/video/cg14.c10
-rw-r--r--drivers/video/cg3.c8
-rw-r--r--drivers/video/cg6.c10
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/console/bitblit.c2
-rw-r--r--drivers/video/console/fbcon.c32
-rw-r--r--drivers/video/console/fbcon.h1
-rw-r--r--drivers/video/console/fbcon_ccw.c2
-rw-r--r--drivers/video/console/fbcon_cw.c2
-rw-r--r--drivers/video/console/fbcon_ud.c2
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/controlfb.c2
-rw-r--r--drivers/video/efifb.c8
-rw-r--r--drivers/video/fbmem.c6
-rw-r--r--drivers/video/ffb.c8
-rw-r--r--drivers/video/fsl-diu-fb.c145
-rw-r--r--drivers/video/fsl-diu-fb.h223
-rw-r--r--drivers/video/igafb.c5
-rw-r--r--drivers/video/imxfb.c19
-rw-r--r--drivers/video/jz4740_fb.c847
-rw-r--r--drivers/video/leo.c10
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.h4
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c4
-rw-r--r--drivers/video/msm/mddi.c4
-rw-r--r--drivers/video/msm/mdp.c1
-rw-r--r--drivers/video/offb.c3
-rw-r--r--drivers/video/omap/lcd_apollon.c3
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c4
-rw-r--r--drivers/video/omap2/displays/panel-taal.c567
-rw-r--r--drivers/video/omap2/displays/panel-toppoly-tdo35s.c8
-rw-r--r--drivers/video/omap2/dss/dispc.c16
-rw-r--r--drivers/video/omap2/dss/display.c4
-rw-r--r--drivers/video/omap2/dss/dsi.c463
-rw-r--r--drivers/video/omap2/dss/dss.c6
-rw-r--r--drivers/video/omap2/dss/dss.h11
-rw-r--r--drivers/video/omap2/dss/manager.c204
-rw-r--r--drivers/video/omap2/dss/overlay.c2
-rw-r--r--drivers/video/omap2/dss/rfbi.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c188
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c229
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c70
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h29
-rw-r--r--drivers/video/p9100.c8
-rw-r--r--drivers/video/platinumfb.c4
-rw-r--r--drivers/video/s3c-fb.c811
-rw-r--r--drivers/video/sh_mipi_dsi.c505
-rw-r--r--drivers/video/sh_mobile_hdmi.c1028
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c196
-rw-r--r--drivers/video/sunxvr1000.c8
-rw-r--r--drivers/video/tcx.c10
-rw-r--r--drivers/video/tdfxfb.c4
-rw-r--r--drivers/video/tgafb.c2
-rw-r--r--drivers/video/uvesafb.c7
-rw-r--r--drivers/video/via/chip.h1
-rw-r--r--drivers/video/via/hw.c587
-rw-r--r--drivers/video/via/hw.h14
-rw-r--r--drivers/video/via/ioctl.h3
-rw-r--r--drivers/video/via/lcd.c117
-rw-r--r--drivers/video/via/lcd.h5
-rw-r--r--drivers/video/via/share.h309
-rw-r--r--drivers/video/via/via-core.c22
-rw-r--r--drivers/video/via/via-gpio.c2
-rw-r--r--drivers/video/via/viafbdev.c284
-rw-r--r--drivers/video/vt8623fb.c2
-rw-r--r--drivers/video/w100fb.c4
-rw-r--r--drivers/video/xen-fbfront.c2
-rw-r--r--drivers/video/xilinxfb.c6
74 files changed, 5226 insertions, 1941 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3d94a1471724..8b31fdfefc98 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1505,7 +1505,7 @@ config FB_SIS_315
1505 1505
1506config FB_VIA 1506config FB_VIA
1507 tristate "VIA UniChrome (Pro) and Chrome9 display support" 1507 tristate "VIA UniChrome (Pro) and Chrome9 display support"
1508 depends on FB && PCI 1508 depends on FB && PCI && X86
1509 select FB_CFB_FILLRECT 1509 select FB_CFB_FILLRECT
1510 select FB_CFB_COPYAREA 1510 select FB_CFB_COPYAREA
1511 select FB_CFB_IMAGEBLIT 1511 select FB_CFB_IMAGEBLIT
@@ -1871,6 +1871,7 @@ config FB_MBX_DEBUG
1871config FB_FSL_DIU 1871config FB_FSL_DIU
1872 tristate "Freescale DIU framebuffer support" 1872 tristate "Freescale DIU framebuffer support"
1873 depends on FB && FSL_SOC 1873 depends on FB && FSL_SOC
1874 select FB_MODE_HELPERS
1874 select FB_CFB_FILLRECT 1875 select FB_CFB_FILLRECT
1875 select FB_CFB_COPYAREA 1876 select FB_CFB_COPYAREA
1876 select FB_CFB_IMAGEBLIT 1877 select FB_CFB_IMAGEBLIT
@@ -1895,6 +1896,13 @@ config FB_W100
1895 1896
1896 If unsure, say N. 1897 If unsure, say N.
1897 1898
1899config SH_MIPI_DSI
1900 tristate
1901 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
1902
1903config SH_LCD_MIPI_DSI
1904 bool
1905
1898config FB_SH_MOBILE_LCDC 1906config FB_SH_MOBILE_LCDC
1899 tristate "SuperH Mobile LCDC framebuffer support" 1907 tristate "SuperH Mobile LCDC framebuffer support"
1900 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK 1908 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
@@ -1903,9 +1911,17 @@ config FB_SH_MOBILE_LCDC
1903 select FB_SYS_IMAGEBLIT 1911 select FB_SYS_IMAGEBLIT
1904 select FB_SYS_FOPS 1912 select FB_SYS_FOPS
1905 select FB_DEFERRED_IO 1913 select FB_DEFERRED_IO
1914 select SH_MIPI_DSI if SH_LCD_MIPI_DSI
1906 ---help--- 1915 ---help---
1907 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1916 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1908 1917
1918config FB_SH_MOBILE_HDMI
1919 tristate "SuperH Mobile HDMI controller support"
1920 depends on FB_SH_MOBILE_LCDC
1921 select FB_MODE_HELPERS
1922 ---help---
1923 Driver for the on-chip SH-Mobile HDMI controller.
1924
1909config FB_TMIO 1925config FB_TMIO
1910 tristate "Toshiba Mobile IO FrameBuffer support" 1926 tristate "Toshiba Mobile IO FrameBuffer support"
1911 depends on FB && MFD_CORE 1927 depends on FB && MFD_CORE
@@ -1930,7 +1946,7 @@ config FB_TMIO_ACCELL
1930 1946
1931config FB_S3C 1947config FB_S3C
1932 tristate "Samsung S3C framebuffer support" 1948 tristate "Samsung S3C framebuffer support"
1933 depends on FB && ARCH_S3C64XX 1949 depends on FB && S3C_DEV_FB
1934 select FB_CFB_FILLRECT 1950 select FB_CFB_FILLRECT
1935 select FB_CFB_COPYAREA 1951 select FB_CFB_COPYAREA
1936 select FB_CFB_IMAGEBLIT 1952 select FB_CFB_IMAGEBLIT
@@ -2229,6 +2245,15 @@ config FB_BROADSHEET
2229 and could also have been called by other names when coupled with 2245 and could also have been called by other names when coupled with
2230 a bridge adapter. 2246 a bridge adapter.
2231 2247
2248config FB_JZ4740
2249 tristate "JZ4740 LCD framebuffer support"
2250 depends on FB && MACH_JZ4740
2251 select FB_SYS_FILLRECT
2252 select FB_SYS_COPYAREA
2253 select FB_SYS_IMAGEBLIT
2254 help
2255 Framebuffer support for the JZ4740 SoC.
2256
2232source "drivers/video/omap/Kconfig" 2257source "drivers/video/omap/Kconfig"
2233source "drivers/video/omap2/Kconfig" 2258source "drivers/video/omap2/Kconfig"
2234 2259
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ddc2af2ba45b..485e8ed1318c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -123,6 +123,8 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
123obj-$(CONFIG_FB_PS3) += ps3fb.o 123obj-$(CONFIG_FB_PS3) += ps3fb.o
124obj-$(CONFIG_FB_SM501) += sm501fb.o 124obj-$(CONFIG_FB_SM501) += sm501fb.o
125obj-$(CONFIG_FB_XILINX) += xilinxfb.o 125obj-$(CONFIG_FB_XILINX) += xilinxfb.o
126obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
127obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
126obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o 128obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
127obj-$(CONFIG_FB_OMAP) += omap/ 129obj-$(CONFIG_FB_OMAP) += omap/
128obj-y += omap2/ 130obj-y += omap2/
@@ -131,6 +133,7 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o
131obj-$(CONFIG_FB_MB862XX) += mb862xx/ 133obj-$(CONFIG_FB_MB862XX) += mb862xx/
132obj-$(CONFIG_FB_MSM) += msm/ 134obj-$(CONFIG_FB_MSM) += msm/
133obj-$(CONFIG_FB_NUC900) += nuc900fb.o 135obj-$(CONFIG_FB_NUC900) += nuc900fb.o
136obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
134 137
135# Platform or fallback drivers go here 138# Platform or fallback drivers go here
136obj-$(CONFIG_FB_UVESA) += uvesafb.o 139obj-$(CONFIG_FB_UVESA) += uvesafb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index afe21e6eb544..1c2c68356ea7 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -80,7 +80,10 @@ static void clcdfb_disable(struct clcd_fb *fb)
80 /* 80 /*
81 * Disable CLCD clock source. 81 * Disable CLCD clock source.
82 */ 82 */
83 clk_disable(fb->clk); 83 if (fb->clk_enabled) {
84 fb->clk_enabled = false;
85 clk_disable(fb->clk);
86 }
84} 87}
85 88
86static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) 89static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
@@ -88,7 +91,10 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
88 /* 91 /*
89 * Enable the CLCD clock source. 92 * Enable the CLCD clock source.
90 */ 93 */
91 clk_enable(fb->clk); 94 if (!fb->clk_enabled) {
95 fb->clk_enabled = true;
96 clk_enable(fb->clk);
97 }
92 98
93 /* 99 /*
94 * Bring up by first enabling.. 100 * Bring up by first enabling..
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 7571bc26071e..d2f59015d517 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -2,7 +2,7 @@
2 * Backlight control code for Sharp Zaurus SL-5500 2 * Backlight control code for Sharp Zaurus SL-5500
3 * 3 *
4 * Copyright 2005 John Lenz <lenz@cs.wisc.edu> 4 * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
5 * Maintainer: Pavel Machek <pavel@suse.cz> (unless John wants to :-) 5 * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
6 * GPL v2 6 * GPL v2
7 * 7 *
8 * This driver assumes single CPU. That's okay, because collie is 8 * This driver assumes single CPU. That's okay, because collie is
@@ -246,6 +246,6 @@ static void __exit locomolcd_exit(void)
246module_init(locomolcd_init); 246module_init(locomolcd_init);
247module_exit(locomolcd_exit); 247module_exit(locomolcd_exit);
248 248
249MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>"); 249MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
250MODULE_DESCRIPTION("Collie LCD driver"); 250MODULE_DESCRIPTION("Collie LCD driver");
251MODULE_LICENSE("GPL"); 251MODULE_LICENSE("GPL");
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 09f1b9b462f4..4dc13467281d 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -273,7 +273,7 @@ static int __devinit bw2_do_default_mode(struct bw2_par *par,
273 return 0; 273 return 0;
274} 274}
275 275
276static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) 276static int __devinit bw2_probe(struct platform_device *op, const struct of_device_id *match)
277{ 277{
278 struct device_node *dp = op->dev.of_node; 278 struct device_node *dp = op->dev.of_node;
279 struct fb_info *info; 279 struct fb_info *info;
@@ -350,7 +350,7 @@ out_err:
350 return err; 350 return err;
351} 351}
352 352
353static int __devexit bw2_remove(struct of_device *op) 353static int __devexit bw2_remove(struct platform_device *op)
354{ 354{
355 struct fb_info *info = dev_get_drvdata(&op->dev); 355 struct fb_info *info = dev_get_drvdata(&op->dev);
356 struct bw2_par *par = info->par; 356 struct bw2_par *par = info->par;
@@ -390,12 +390,12 @@ static int __init bw2_init(void)
390 if (fb_get_options("bw2fb", NULL)) 390 if (fb_get_options("bw2fb", NULL))
391 return -ENODEV; 391 return -ENODEV;
392 392
393 return of_register_driver(&bw2_driver, &of_bus_type); 393 return of_register_platform_driver(&bw2_driver);
394} 394}
395 395
396static void __exit bw2_exit(void) 396static void __exit bw2_exit(void)
397{ 397{
398 of_unregister_driver(&bw2_driver); 398 of_unregister_platform_driver(&bw2_driver);
399} 399}
400 400
401module_init(bw2_init); 401module_init(bw2_init);
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index d8345fcc4fe3..6b19136aa181 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -432,7 +432,7 @@ static int init_hardware(struct carmine_hw *hw)
432 u32 loops; 432 u32 loops;
433 u32 ret; 433 u32 ret;
434 434
435 /* Initalize Carmine */ 435 /* Initialize Carmine */
436 /* Sets internal clock */ 436 /* Sets internal clock */
437 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 437 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE,
438 CARMINE_DFLT_IP_CLOCK_ENABLE); 438 CARMINE_DFLT_IP_CLOCK_ENABLE);
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index e5dc2241194f..24249535ac86 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -446,7 +446,7 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = {
446 { .size = 0 } 446 { .size = 0 }
447}; 447};
448 448
449static void cg14_unmap_regs(struct of_device *op, struct fb_info *info, 449static void cg14_unmap_regs(struct platform_device *op, struct fb_info *info,
450 struct cg14_par *par) 450 struct cg14_par *par)
451{ 451{
452 if (par->regs) 452 if (par->regs)
@@ -463,7 +463,7 @@ static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
463 info->screen_base, info->fix.smem_len); 463 info->screen_base, info->fix.smem_len);
464} 464}
465 465
466static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match) 466static int __devinit cg14_probe(struct platform_device *op, const struct of_device_id *match)
467{ 467{
468 struct device_node *dp = op->dev.of_node; 468 struct device_node *dp = op->dev.of_node;
469 struct fb_info *info; 469 struct fb_info *info;
@@ -570,7 +570,7 @@ out_err:
570 return err; 570 return err;
571} 571}
572 572
573static int __devexit cg14_remove(struct of_device *op) 573static int __devexit cg14_remove(struct platform_device *op)
574{ 574{
575 struct fb_info *info = dev_get_drvdata(&op->dev); 575 struct fb_info *info = dev_get_drvdata(&op->dev);
576 struct cg14_par *par = info->par; 576 struct cg14_par *par = info->par;
@@ -610,12 +610,12 @@ static int __init cg14_init(void)
610 if (fb_get_options("cg14fb", NULL)) 610 if (fb_get_options("cg14fb", NULL))
611 return -ENODEV; 611 return -ENODEV;
612 612
613 return of_register_driver(&cg14_driver, &of_bus_type); 613 return of_register_platform_driver(&cg14_driver);
614} 614}
615 615
616static void __exit cg14_exit(void) 616static void __exit cg14_exit(void)
617{ 617{
618 of_unregister_driver(&cg14_driver); 618 of_unregister_platform_driver(&cg14_driver);
619} 619}
620 620
621module_init(cg14_init); 621module_init(cg14_init);
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 558d73a948a0..09c0c3c42482 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -346,7 +346,7 @@ static int __devinit cg3_do_default_mode(struct cg3_par *par)
346 return 0; 346 return 0;
347} 347}
348 348
349static int __devinit cg3_probe(struct of_device *op, 349static int __devinit cg3_probe(struct platform_device *op,
350 const struct of_device_id *match) 350 const struct of_device_id *match)
351{ 351{
352 struct device_node *dp = op->dev.of_node; 352 struct device_node *dp = op->dev.of_node;
@@ -433,7 +433,7 @@ out_err:
433 return err; 433 return err;
434} 434}
435 435
436static int __devexit cg3_remove(struct of_device *op) 436static int __devexit cg3_remove(struct platform_device *op)
437{ 437{
438 struct fb_info *info = dev_get_drvdata(&op->dev); 438 struct fb_info *info = dev_get_drvdata(&op->dev);
439 struct cg3_par *par = info->par; 439 struct cg3_par *par = info->par;
@@ -477,12 +477,12 @@ static int __init cg3_init(void)
477 if (fb_get_options("cg3fb", NULL)) 477 if (fb_get_options("cg3fb", NULL))
478 return -ENODEV; 478 return -ENODEV;
479 479
480 return of_register_driver(&cg3_driver, &of_bus_type); 480 return of_register_platform_driver(&cg3_driver);
481} 481}
482 482
483static void __exit cg3_exit(void) 483static void __exit cg3_exit(void)
484{ 484{
485 of_unregister_driver(&cg3_driver); 485 of_unregister_platform_driver(&cg3_driver);
486} 486}
487 487
488module_init(cg3_init); 488module_init(cg3_init);
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 480d761a27a8..2b5a97058b08 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -718,7 +718,7 @@ static void __devinit cg6_chip_init(struct fb_info *info)
718 sbus_writel(info->var.yres - 1, &fbc->clipmaxy); 718 sbus_writel(info->var.yres - 1, &fbc->clipmaxy);
719} 719}
720 720
721static void cg6_unmap_regs(struct of_device *op, struct fb_info *info, 721static void cg6_unmap_regs(struct platform_device *op, struct fb_info *info,
722 struct cg6_par *par) 722 struct cg6_par *par)
723{ 723{
724 if (par->fbc) 724 if (par->fbc)
@@ -737,7 +737,7 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info,
737 info->fix.smem_len); 737 info->fix.smem_len);
738} 738}
739 739
740static int __devinit cg6_probe(struct of_device *op, 740static int __devinit cg6_probe(struct platform_device *op,
741 const struct of_device_id *match) 741 const struct of_device_id *match)
742{ 742{
743 struct device_node *dp = op->dev.of_node; 743 struct device_node *dp = op->dev.of_node;
@@ -827,7 +827,7 @@ out_err:
827 return err; 827 return err;
828} 828}
829 829
830static int __devexit cg6_remove(struct of_device *op) 830static int __devexit cg6_remove(struct platform_device *op)
831{ 831{
832 struct fb_info *info = dev_get_drvdata(&op->dev); 832 struct fb_info *info = dev_get_drvdata(&op->dev);
833 struct cg6_par *par = info->par; 833 struct cg6_par *par = info->par;
@@ -870,12 +870,12 @@ static int __init cg6_init(void)
870 if (fb_get_options("cg6fb", NULL)) 870 if (fb_get_options("cg6fb", NULL))
871 return -ENODEV; 871 return -ENODEV;
872 872
873 return of_register_driver(&cg6_driver, &of_bus_type); 873 return of_register_platform_driver(&cg6_driver);
874} 874}
875 875
876static void __exit cg6_exit(void) 876static void __exit cg6_exit(void)
877{ 877{
878 of_unregister_driver(&cg6_driver); 878 of_unregister_platform_driver(&cg6_driver);
879} 879}
880 880
881module_init(cg6_init); 881module_init(cg6_init);
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 8e8f18d29d7a..5a35f22372b9 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
6 6
7config VGA_CONSOLE 7config VGA_CONSOLE
8 bool "VGA text console" if EMBEDDED || !X86 8 bool "VGA text console" if EMBEDDED || !X86
9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 9 depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER)
10 default y 10 default y
11 help 11 help
12 Saying Y here will allow you to use Linux in text mode through a 12 Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index af88651b0735..28b1a834906b 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,7 +22,7 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static void update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc) 26 struct vc_data *vc)
27{ 27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2; 28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index b0a3fa00706d..84f842331dfa 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -283,10 +283,11 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
283 struct fbcon_ops *ops = info->fbcon_par; 283 struct fbcon_ops *ops = info->fbcon_par;
284 284
285 return (info->state != FBINFO_STATE_RUNNING || 285 return (info->state != FBINFO_STATE_RUNNING ||
286 vc->vc_mode != KD_TEXT || ops->graphics); 286 vc->vc_mode != KD_TEXT || ops->graphics) &&
287 !vt_force_oops_output(vc);
287} 288}
288 289
289static inline int get_color(struct vc_data *vc, struct fb_info *info, 290static int get_color(struct vc_data *vc, struct fb_info *info,
290 u16 c, int is_fg) 291 u16 c, int is_fg)
291{ 292{
292 int depth = fb_get_color_depth(&info->var, &info->fix); 293 int depth = fb_get_color_depth(&info->var, &info->fix);
@@ -1073,6 +1074,7 @@ static void fbcon_init(struct vc_data *vc, int init)
1073 if (p->userfont) 1074 if (p->userfont)
1074 charcnt = FNTCHARCNT(p->fontdata); 1075 charcnt = FNTCHARCNT(p->fontdata);
1075 1076
1077 vc->vc_panic_force_write = !!(info->flags & FBINFO_CAN_FORCE_OUTPUT);
1076 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1078 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1077 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1079 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1078 if (charcnt == 256) { 1080 if (charcnt == 256) {
@@ -2342,6 +2344,30 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2342 return 0; 2344 return 0;
2343} 2345}
2344 2346
2347static int fbcon_debug_enter(struct vc_data *vc)
2348{
2349 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2350 struct fbcon_ops *ops = info->fbcon_par;
2351
2352 ops->save_graphics = ops->graphics;
2353 ops->graphics = 0;
2354 if (info->fbops->fb_debug_enter)
2355 info->fbops->fb_debug_enter(info);
2356 fbcon_set_palette(vc, color_table);
2357 return 0;
2358}
2359
2360static int fbcon_debug_leave(struct vc_data *vc)
2361{
2362 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2363 struct fbcon_ops *ops = info->fbcon_par;
2364
2365 ops->graphics = ops->save_graphics;
2366 if (info->fbops->fb_debug_leave)
2367 info->fbops->fb_debug_leave(info);
2368 return 0;
2369}
2370
2345static int fbcon_get_font(struct vc_data *vc, struct console_font *font) 2371static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
2346{ 2372{
2347 u8 *fontdata = vc->vc_font.data; 2373 u8 *fontdata = vc->vc_font.data;
@@ -3276,6 +3302,8 @@ static const struct consw fb_con = {
3276 .con_screen_pos = fbcon_screen_pos, 3302 .con_screen_pos = fbcon_screen_pos,
3277 .con_getxy = fbcon_getxy, 3303 .con_getxy = fbcon_getxy,
3278 .con_resize = fbcon_resize, 3304 .con_resize = fbcon_resize,
3305 .con_debug_enter = fbcon_debug_enter,
3306 .con_debug_leave = fbcon_debug_leave,
3279}; 3307};
3280 3308
3281static struct notifier_block fbcon_event_notifier = { 3309static struct notifier_block fbcon_event_notifier = {
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 89a346880ec0..6bd2e0c7f209 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -74,6 +74,7 @@ struct fbcon_ops {
74 int cursor_reset; 74 int cursor_reset;
75 int blank_state; 75 int blank_state;
76 int graphics; 76 int graphics;
77 int save_graphics; /* for debug enter/leave */
77 int flags; 78 int flags;
78 int rotate; 79 int rotate;
79 int cur_rotate; 80 int cur_rotate;
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index d135671d9961..41b32ae23dac 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -22,7 +22,7 @@
22 * Rotation 270 degrees 22 * Rotation 270 degrees
23 */ 23 */
24 24
25static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute, 25static void ccw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc) 26 struct vc_data *vc)
27{ 27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2; 28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 126110f8454f..6a737827beb1 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -22,7 +22,7 @@
22 * Rotation 90 degrees 22 * Rotation 90 degrees
23 */ 23 */
24 24
25static inline void cw_update_attr(u8 *dst, u8 *src, int attribute, 25static void cw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc) 26 struct vc_data *vc)
27{ 27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2; 28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index 93a3e7381b50..ff0872c0498b 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -22,7 +22,7 @@
22 * Rotation 180 degrees 22 * Rotation 180 degrees
23 */ 23 */
24 24
25static inline void ud_update_attr(u8 *dst, u8 *src, int attribute, 25static void ud_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc) 26 struct vc_data *vc)
27{ 27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2; 28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 182dd6f8aadd..54e32c513610 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1108,7 +1108,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1108 charmap += 4 * cmapsz; 1108 charmap += 4 * cmapsz;
1109#endif 1109#endif
1110 1110
1111 unlock_kernel();
1112 spin_lock_irq(&vga_lock); 1111 spin_lock_irq(&vga_lock);
1113 /* First, the Sequencer */ 1112 /* First, the Sequencer */
1114 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 1113 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -1192,7 +1191,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1192 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); 1191 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
1193 } 1192 }
1194 spin_unlock_irq(&vga_lock); 1193 spin_unlock_irq(&vga_lock);
1195 lock_kernel();
1196 return 0; 1194 return 0;
1197} 1195}
1198 1196
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 49fcbe8f18ac..c225dcce89e7 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -40,6 +40,8 @@
40#include <linux/vmalloc.h> 40#include <linux/vmalloc.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/of.h>
44#include <linux/of_address.h>
43#include <linux/fb.h> 45#include <linux/fb.h>
44#include <linux/init.h> 46#include <linux/init.h>
45#include <linux/pci.h> 47#include <linux/pci.h>
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 4a56f46af40a..815f84b07933 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -16,7 +16,7 @@
16 16
17#include <video/vga.h> 17#include <video/vga.h>
18 18
19static struct fb_var_screeninfo efifb_defined __initdata = { 19static struct fb_var_screeninfo efifb_defined __devinitdata = {
20 .activate = FB_ACTIVATE_NOW, 20 .activate = FB_ACTIVATE_NOW,
21 .height = -1, 21 .height = -1,
22 .width = -1, 22 .width = -1,
@@ -27,7 +27,7 @@ static struct fb_var_screeninfo efifb_defined __initdata = {
27 .vmode = FB_VMODE_NONINTERLACED, 27 .vmode = FB_VMODE_NONINTERLACED,
28}; 28};
29 29
30static struct fb_fix_screeninfo efifb_fix __initdata = { 30static struct fb_fix_screeninfo efifb_fix __devinitdata = {
31 .id = "EFI VGA", 31 .id = "EFI VGA",
32 .type = FB_TYPE_PACKED_PIXELS, 32 .type = FB_TYPE_PACKED_PIXELS,
33 .accel = FB_ACCEL_NONE, 33 .accel = FB_ACCEL_NONE,
@@ -59,7 +59,7 @@ static struct efifb_dmi_info {
59 int stride; 59 int stride;
60 int width; 60 int width;
61 int height; 61 int height;
62} dmi_list[] = { 62} dmi_list[] __initdata = {
63 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 }, 63 [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
64 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ 64 [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
65 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, 65 [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
@@ -83,7 +83,7 @@ static int set_system(const struct dmi_system_id *id);
83 DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ 83 DMI_MATCH(DMI_PRODUCT_NAME, name) }, \
84 &dmi_list[enumid] } 84 &dmi_list[enumid] }
85 85
86static struct dmi_system_id __initdata dmi_system_table[] = { 86static const struct dmi_system_id dmi_system_table[] __initconst = {
87 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), 87 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
88 /* At least one of these two will be right; maybe both? */ 88 /* At least one of these two will be right; maybe both? */
89 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), 89 EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 731fce64df9d..b06647517c0e 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1362,6 +1362,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
1362 vma->vm_pgoff = off >> PAGE_SHIFT; 1362 vma->vm_pgoff = off >> PAGE_SHIFT;
1363 /* This is an IO map - tell maydump to skip this VMA */ 1363 /* This is an IO map - tell maydump to skip this VMA */
1364 vma->vm_flags |= VM_IO | VM_RESERVED; 1364 vma->vm_flags |= VM_IO | VM_RESERVED;
1365 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1365 fb_pgprotect(file, vma, off); 1366 fb_pgprotect(file, vma, off);
1366 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1367 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1367 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 1368 vma->vm_end - vma->vm_start, vma->vm_page_prot))
@@ -1786,7 +1787,7 @@ static int ofonly __read_mostly;
1786int fb_get_options(char *name, char **option) 1787int fb_get_options(char *name, char **option)
1787{ 1788{
1788 char *opt, *options = NULL; 1789 char *opt, *options = NULL;
1789 int opt_len, retval = 0; 1790 int retval = 0;
1790 int name_len = strlen(name), i; 1791 int name_len = strlen(name), i;
1791 1792
1792 if (name_len && ofonly && strncmp(name, "offb", 4)) 1793 if (name_len && ofonly && strncmp(name, "offb", 4))
@@ -1796,8 +1797,7 @@ int fb_get_options(char *name, char **option)
1796 for (i = 0; i < FB_MAX; i++) { 1797 for (i = 0; i < FB_MAX; i++) {
1797 if (video_options[i] == NULL) 1798 if (video_options[i] == NULL)
1798 continue; 1799 continue;
1799 opt_len = strlen(video_options[i]); 1800 if (!video_options[i][0])
1800 if (!opt_len)
1801 continue; 1801 continue;
1802 opt = video_options[i]; 1802 opt = video_options[i];
1803 if (!strncmp(name, opt, name_len) && 1803 if (!strncmp(name, opt, name_len) &&
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 95c0227f47fc..6739b2af3bc0 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -893,7 +893,7 @@ static void ffb_init_fix(struct fb_info *info)
893 info->fix.accel = FB_ACCEL_SUN_CREATOR; 893 info->fix.accel = FB_ACCEL_SUN_CREATOR;
894} 894}
895 895
896static int __devinit ffb_probe(struct of_device *op, 896static int __devinit ffb_probe(struct platform_device *op,
897 const struct of_device_id *match) 897 const struct of_device_id *match)
898{ 898{
899 struct device_node *dp = op->dev.of_node; 899 struct device_node *dp = op->dev.of_node;
@@ -1023,7 +1023,7 @@ out_err:
1023 return err; 1023 return err;
1024} 1024}
1025 1025
1026static int __devexit ffb_remove(struct of_device *op) 1026static int __devexit ffb_remove(struct platform_device *op)
1027{ 1027{
1028 struct fb_info *info = dev_get_drvdata(&op->dev); 1028 struct fb_info *info = dev_get_drvdata(&op->dev);
1029 struct ffb_par *par = info->par; 1029 struct ffb_par *par = info->par;
@@ -1067,12 +1067,12 @@ static int __init ffb_init(void)
1067 if (fb_get_options("ffb", NULL)) 1067 if (fb_get_options("ffb", NULL))
1068 return -ENODEV; 1068 return -ENODEV;
1069 1069
1070 return of_register_driver(&ffb_driver, &of_bus_type); 1070 return of_register_platform_driver(&ffb_driver);
1071} 1071}
1072 1072
1073static void __exit ffb_exit(void) 1073static void __exit ffb_exit(void)
1074{ 1074{
1075 of_unregister_driver(&ffb_driver); 1075 of_unregister_platform_driver(&ffb_driver);
1076} 1076}
1077 1077
1078module_init(ffb_init); 1078module_init(ffb_init);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 27455ce298b7..8bbbf08fa3ce 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -34,7 +34,8 @@
34#include <linux/of_platform.h> 34#include <linux/of_platform.h>
35 35
36#include <sysdev/fsl_soc.h> 36#include <sysdev/fsl_soc.h>
37#include "fsl-diu-fb.h" 37#include <linux/fsl-diu-fb.h>
38#include "edid.h"
38 39
39/* 40/*
40 * These parameters give default parameters 41 * These parameters give default parameters
@@ -217,6 +218,7 @@ struct mfb_info {
217 int x_aoi_d; /* aoi display x offset to physical screen */ 218 int x_aoi_d; /* aoi display x offset to physical screen */
218 int y_aoi_d; /* aoi display y offset to physical screen */ 219 int y_aoi_d; /* aoi display y offset to physical screen */
219 struct fsl_diu_data *parent; 220 struct fsl_diu_data *parent;
221 u8 *edid_data;
220}; 222};
221 223
222 224
@@ -317,6 +319,17 @@ static void fsl_diu_free(void *virt, size_t size)
317 free_pages_exact(virt, size); 319 free_pages_exact(virt, size);
318} 320}
319 321
322/*
323 * Workaround for failed writing desc register of planes.
324 * Needed with MPC5121 DIU rev 2.0 silicon.
325 */
326void wr_reg_wa(u32 *reg, u32 val)
327{
328 do {
329 out_be32(reg, val);
330 } while (in_be32(reg) != val);
331}
332
320static int fsl_diu_enable_panel(struct fb_info *info) 333static int fsl_diu_enable_panel(struct fb_info *info)
321{ 334{
322 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par; 335 struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
@@ -330,7 +343,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
330 switch (mfbi->index) { 343 switch (mfbi->index) {
331 case 0: /* plane 0 */ 344 case 0: /* plane 0 */
332 if (hw->desc[0] != ad->paddr) 345 if (hw->desc[0] != ad->paddr)
333 out_be32(&hw->desc[0], ad->paddr); 346 wr_reg_wa(&hw->desc[0], ad->paddr);
334 break; 347 break;
335 case 1: /* plane 1 AOI 0 */ 348 case 1: /* plane 1 AOI 0 */
336 cmfbi = machine_data->fsl_diu_info[2]->par; 349 cmfbi = machine_data->fsl_diu_info[2]->par;
@@ -340,7 +353,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
340 cpu_to_le32(cmfbi->ad->paddr); 353 cpu_to_le32(cmfbi->ad->paddr);
341 else 354 else
342 ad->next_ad = 0; 355 ad->next_ad = 0;
343 out_be32(&hw->desc[1], ad->paddr); 356 wr_reg_wa(&hw->desc[1], ad->paddr);
344 } 357 }
345 break; 358 break;
346 case 3: /* plane 2 AOI 0 */ 359 case 3: /* plane 2 AOI 0 */
@@ -351,14 +364,14 @@ static int fsl_diu_enable_panel(struct fb_info *info)
351 cpu_to_le32(cmfbi->ad->paddr); 364 cpu_to_le32(cmfbi->ad->paddr);
352 else 365 else
353 ad->next_ad = 0; 366 ad->next_ad = 0;
354 out_be32(&hw->desc[2], ad->paddr); 367 wr_reg_wa(&hw->desc[2], ad->paddr);
355 } 368 }
356 break; 369 break;
357 case 2: /* plane 1 AOI 1 */ 370 case 2: /* plane 1 AOI 1 */
358 pmfbi = machine_data->fsl_diu_info[1]->par; 371 pmfbi = machine_data->fsl_diu_info[1]->par;
359 ad->next_ad = 0; 372 ad->next_ad = 0;
360 if (hw->desc[1] == machine_data->dummy_ad->paddr) 373 if (hw->desc[1] == machine_data->dummy_ad->paddr)
361 out_be32(&hw->desc[1], ad->paddr); 374 wr_reg_wa(&hw->desc[1], ad->paddr);
362 else /* AOI0 open */ 375 else /* AOI0 open */
363 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); 376 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
364 break; 377 break;
@@ -366,7 +379,7 @@ static int fsl_diu_enable_panel(struct fb_info *info)
366 pmfbi = machine_data->fsl_diu_info[3]->par; 379 pmfbi = machine_data->fsl_diu_info[3]->par;
367 ad->next_ad = 0; 380 ad->next_ad = 0;
368 if (hw->desc[2] == machine_data->dummy_ad->paddr) 381 if (hw->desc[2] == machine_data->dummy_ad->paddr)
369 out_be32(&hw->desc[2], ad->paddr); 382 wr_reg_wa(&hw->desc[2], ad->paddr);
370 else /* AOI0 was open */ 383 else /* AOI0 was open */
371 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr); 384 pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
372 break; 385 break;
@@ -390,27 +403,24 @@ static int fsl_diu_disable_panel(struct fb_info *info)
390 switch (mfbi->index) { 403 switch (mfbi->index) {
391 case 0: /* plane 0 */ 404 case 0: /* plane 0 */
392 if (hw->desc[0] != machine_data->dummy_ad->paddr) 405 if (hw->desc[0] != machine_data->dummy_ad->paddr)
393 out_be32(&hw->desc[0], 406 wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr);
394 machine_data->dummy_ad->paddr);
395 break; 407 break;
396 case 1: /* plane 1 AOI 0 */ 408 case 1: /* plane 1 AOI 0 */
397 cmfbi = machine_data->fsl_diu_info[2]->par; 409 cmfbi = machine_data->fsl_diu_info[2]->par;
398 if (cmfbi->count > 0) /* AOI1 is open */ 410 if (cmfbi->count > 0) /* AOI1 is open */
399 out_be32(&hw->desc[1], cmfbi->ad->paddr); 411 wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr);
400 /* move AOI1 to the first */ 412 /* move AOI1 to the first */
401 else /* AOI1 was closed */ 413 else /* AOI1 was closed */
402 out_be32(&hw->desc[1], 414 wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
403 machine_data->dummy_ad->paddr);
404 /* close AOI 0 */ 415 /* close AOI 0 */
405 break; 416 break;
406 case 3: /* plane 2 AOI 0 */ 417 case 3: /* plane 2 AOI 0 */
407 cmfbi = machine_data->fsl_diu_info[4]->par; 418 cmfbi = machine_data->fsl_diu_info[4]->par;
408 if (cmfbi->count > 0) /* AOI1 is open */ 419 if (cmfbi->count > 0) /* AOI1 is open */
409 out_be32(&hw->desc[2], cmfbi->ad->paddr); 420 wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr);
410 /* move AOI1 to the first */ 421 /* move AOI1 to the first */
411 else /* AOI1 was closed */ 422 else /* AOI1 was closed */
412 out_be32(&hw->desc[2], 423 wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
413 machine_data->dummy_ad->paddr);
414 /* close AOI 0 */ 424 /* close AOI 0 */
415 break; 425 break;
416 case 2: /* plane 1 AOI 1 */ 426 case 2: /* plane 1 AOI 1 */
@@ -421,7 +431,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
421 /* AOI0 is open, must be the first */ 431 /* AOI0 is open, must be the first */
422 pmfbi->ad->next_ad = 0; 432 pmfbi->ad->next_ad = 0;
423 } else /* AOI1 is the first in the chain */ 433 } else /* AOI1 is the first in the chain */
424 out_be32(&hw->desc[1], machine_data->dummy_ad->paddr); 434 wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
425 /* close AOI 1 */ 435 /* close AOI 1 */
426 break; 436 break;
427 case 4: /* plane 2 AOI 1 */ 437 case 4: /* plane 2 AOI 1 */
@@ -432,7 +442,7 @@ static int fsl_diu_disable_panel(struct fb_info *info)
432 /* AOI0 is open, must be the first */ 442 /* AOI0 is open, must be the first */
433 pmfbi->ad->next_ad = 0; 443 pmfbi->ad->next_ad = 0;
434 } else /* AOI1 is the first in the chain */ 444 } else /* AOI1 is the first in the chain */
435 out_be32(&hw->desc[2], machine_data->dummy_ad->paddr); 445 wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
436 /* close AOI 1 */ 446 /* close AOI 1 */
437 break; 447 break;
438 default: 448 default:
@@ -1100,6 +1110,10 @@ static int fsl_diu_open(struct fb_info *info, int user)
1100 struct mfb_info *mfbi = info->par; 1110 struct mfb_info *mfbi = info->par;
1101 int res = 0; 1111 int res = 0;
1102 1112
1113 /* free boot splash memory on first /dev/fb0 open */
1114 if (!mfbi->index && diu_ops.release_bootmem)
1115 diu_ops.release_bootmem();
1116
1103 spin_lock(&diu_lock); 1117 spin_lock(&diu_lock);
1104 mfbi->count++; 1118 mfbi->count++;
1105 if (mfbi->count == 1) { 1119 if (mfbi->count == 1) {
@@ -1173,18 +1187,30 @@ static int __devinit install_fb(struct fb_info *info)
1173 int rc; 1187 int rc;
1174 struct mfb_info *mfbi = info->par; 1188 struct mfb_info *mfbi = info->par;
1175 const char *aoi_mode, *init_aoi_mode = "320x240"; 1189 const char *aoi_mode, *init_aoi_mode = "320x240";
1190 struct fb_videomode *db = fsl_diu_mode_db;
1191 unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
1192 int has_default_mode = 1;
1176 1193
1177 if (init_fbinfo(info)) 1194 if (init_fbinfo(info))
1178 return -EINVAL; 1195 return -EINVAL;
1179 1196
1180 if (mfbi->index == 0) /* plane 0 */ 1197 if (mfbi->index == 0) { /* plane 0 */
1198 if (mfbi->edid_data) {
1199 /* Now build modedb from EDID */
1200 fb_edid_to_monspecs(mfbi->edid_data, &info->monspecs);
1201 fb_videomode_to_modelist(info->monspecs.modedb,
1202 info->monspecs.modedb_len,
1203 &info->modelist);
1204 db = info->monspecs.modedb;
1205 dbsize = info->monspecs.modedb_len;
1206 }
1181 aoi_mode = fb_mode; 1207 aoi_mode = fb_mode;
1182 else 1208 } else {
1183 aoi_mode = init_aoi_mode; 1209 aoi_mode = init_aoi_mode;
1210 }
1184 pr_debug("mode used = %s\n", aoi_mode); 1211 pr_debug("mode used = %s\n", aoi_mode);
1185 rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db, 1212 rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize,
1186 ARRAY_SIZE(fsl_diu_mode_db), &fsl_diu_default_mode, default_bpp); 1213 &fsl_diu_default_mode, default_bpp);
1187
1188 switch (rc) { 1214 switch (rc) {
1189 case 1: 1215 case 1:
1190 pr_debug("using mode specified in @mode\n"); 1216 pr_debug("using mode specified in @mode\n");
@@ -1202,10 +1228,50 @@ static int __devinit install_fb(struct fb_info *info)
1202 default: 1228 default:
1203 pr_debug("rc = %d\n", rc); 1229 pr_debug("rc = %d\n", rc);
1204 pr_debug("failed to find mode\n"); 1230 pr_debug("failed to find mode\n");
1205 return -EINVAL; 1231 /*
1232 * For plane 0 we continue and look into
1233 * driver's internal modedb.
1234 */
1235 if (mfbi->index == 0 && mfbi->edid_data)
1236 has_default_mode = 0;
1237 else
1238 return -EINVAL;
1206 break; 1239 break;
1207 } 1240 }
1208 1241
1242 if (!has_default_mode) {
1243 rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db,
1244 ARRAY_SIZE(fsl_diu_mode_db),
1245 &fsl_diu_default_mode,
1246 default_bpp);
1247 if (rc > 0 && rc < 5)
1248 has_default_mode = 1;
1249 }
1250
1251 /* Still not found, use preferred mode from database if any */
1252 if (!has_default_mode && info->monspecs.modedb) {
1253 struct fb_monspecs *specs = &info->monspecs;
1254 struct fb_videomode *modedb = &specs->modedb[0];
1255
1256 /*
1257 * Get preferred timing. If not found,
1258 * first mode in database will be used.
1259 */
1260 if (specs->misc & FB_MISC_1ST_DETAIL) {
1261 int i;
1262
1263 for (i = 0; i < specs->modedb_len; i++) {
1264 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1265 modedb = &specs->modedb[i];
1266 break;
1267 }
1268 }
1269 }
1270
1271 info->var.bits_per_pixel = default_bpp;
1272 fb_videomode_to_var(&info->var, modedb);
1273 }
1274
1209 pr_debug("xres_virtual %d\n", info->var.xres_virtual); 1275 pr_debug("xres_virtual %d\n", info->var.xres_virtual);
1210 pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel); 1276 pr_debug("bits_per_pixel %d\n", info->var.bits_per_pixel);
1211 1277
@@ -1244,6 +1310,9 @@ static void uninstall_fb(struct fb_info *info)
1244 if (!mfbi->registered) 1310 if (!mfbi->registered)
1245 return; 1311 return;
1246 1312
1313 if (mfbi->index == 0)
1314 kfree(mfbi->edid_data);
1315
1247 unregister_framebuffer(info); 1316 unregister_framebuffer(info);
1248 unmap_video_memory(info); 1317 unmap_video_memory(info);
1249 if (&info->cmap) 1318 if (&info->cmap)
@@ -1324,7 +1393,7 @@ static void free_irq_local(int irq)
1324 * Power management hooks. Note that we won't be called from IRQ context, 1393 * Power management hooks. Note that we won't be called from IRQ context,
1325 * unlike the blank functions above, so we may sleep. 1394 * unlike the blank functions above, so we may sleep.
1326 */ 1395 */
1327static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) 1396static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
1328{ 1397{
1329 struct fsl_diu_data *machine_data; 1398 struct fsl_diu_data *machine_data;
1330 1399
@@ -1334,7 +1403,7 @@ static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state)
1334 return 0; 1403 return 0;
1335} 1404}
1336 1405
1337static int fsl_diu_resume(struct of_device *ofdev) 1406static int fsl_diu_resume(struct platform_device *ofdev)
1338{ 1407{
1339 struct fsl_diu_data *machine_data; 1408 struct fsl_diu_data *machine_data;
1340 1409
@@ -1418,7 +1487,7 @@ static ssize_t show_monitor(struct device *device,
1418 return diu_ops.show_monitor_port(machine_data->monitor_port, buf); 1487 return diu_ops.show_monitor_port(machine_data->monitor_port, buf);
1419} 1488}
1420 1489
1421static int __devinit fsl_diu_probe(struct of_device *ofdev, 1490static int __devinit fsl_diu_probe(struct platform_device *ofdev,
1422 const struct of_device_id *match) 1491 const struct of_device_id *match)
1423{ 1492{
1424 struct device_node *np = ofdev->dev.of_node; 1493 struct device_node *np = ofdev->dev.of_node;
@@ -1427,6 +1496,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
1427 int ret, i, error = 0; 1496 int ret, i, error = 0;
1428 struct resource res; 1497 struct resource res;
1429 struct fsl_diu_data *machine_data; 1498 struct fsl_diu_data *machine_data;
1499 int diu_mode;
1430 1500
1431 machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL); 1501 machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL);
1432 if (!machine_data) 1502 if (!machine_data)
@@ -1443,6 +1513,17 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
1443 mfbi = machine_data->fsl_diu_info[i]->par; 1513 mfbi = machine_data->fsl_diu_info[i]->par;
1444 memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info)); 1514 memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
1445 mfbi->parent = machine_data; 1515 mfbi->parent = machine_data;
1516
1517 if (mfbi->index == 0) {
1518 const u8 *prop;
1519 int len;
1520
1521 /* Get EDID */
1522 prop = of_get_property(np, "edid", &len);
1523 if (prop && len == EDID_LENGTH)
1524 mfbi->edid_data = kmemdup(prop, EDID_LENGTH,
1525 GFP_KERNEL);
1526 }
1446 } 1527 }
1447 1528
1448 ret = of_address_to_resource(np, 0, &res); 1529 ret = of_address_to_resource(np, 0, &res);
@@ -1463,7 +1544,9 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
1463 goto error2; 1544 goto error2;
1464 } 1545 }
1465 1546
1466 out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU anyway*/ 1547 diu_mode = in_be32(&dr.diu_reg->diu_mode);
1548 if (diu_mode != MFB_MODE1)
1549 out_be32(&dr.diu_reg->diu_mode, 0); /* disable DIU */
1467 1550
1468 /* Get the IRQ of the DIU */ 1551 /* Get the IRQ of the DIU */
1469 machine_data->irq = irq_of_parse_and_map(np, 0); 1552 machine_data->irq = irq_of_parse_and_map(np, 0);
@@ -1511,7 +1594,13 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
1511 machine_data->dummy_ad->offset_xyd = 0; 1594 machine_data->dummy_ad->offset_xyd = 0;
1512 machine_data->dummy_ad->next_ad = 0; 1595 machine_data->dummy_ad->next_ad = 0;
1513 1596
1514 out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr); 1597 /*
1598 * Let DIU display splash screen if it was pre-initialized
1599 * by the bootloader, set dummy area descriptor otherwise.
1600 */
1601 if (diu_mode != MFB_MODE1)
1602 out_be32(&dr.diu_reg->desc[0], machine_data->dummy_ad->paddr);
1603
1515 out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr); 1604 out_be32(&dr.diu_reg->desc[1], machine_data->dummy_ad->paddr);
1516 out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr); 1605 out_be32(&dr.diu_reg->desc[2], machine_data->dummy_ad->paddr);
1517 1606
@@ -1578,7 +1667,7 @@ error2:
1578} 1667}
1579 1668
1580 1669
1581static int fsl_diu_remove(struct of_device *ofdev) 1670static int fsl_diu_remove(struct platform_device *ofdev)
1582{ 1671{
1583 struct fsl_diu_data *machine_data; 1672 struct fsl_diu_data *machine_data;
1584 int i; 1673 int i;
diff --git a/drivers/video/fsl-diu-fb.h b/drivers/video/fsl-diu-fb.h
deleted file mode 100644
index fc295d7ea463..000000000000
--- a/drivers/video/fsl-diu-fb.h
+++ /dev/null
@@ -1,223 +0,0 @@
1/*
2 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Freescale DIU Frame Buffer device driver
5 *
6 * Authors: Hongjun Chen <hong-jun.chen@freescale.com>
7 * Paul Widmer <paul.widmer@freescale.com>
8 * Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
9 * York Sun <yorksun@freescale.com>
10 *
11 * Based on imxfb.c Copyright (C) 2004 S.Hauer, Pengutronix
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 */
19
20#ifndef __FSL_DIU_FB_H__
21#define __FSL_DIU_FB_H__
22
23/* Arbitrary threshold to determine the allocation method
24 * See mpc8610fb_set_par(), map_video_memory(), and unmap_video_memory()
25 */
26#define MEM_ALLOC_THRESHOLD (1024*768*4+32)
27/* Minimum value that the pixel clock can be set to in pico seconds
28 * This is determined by platform clock/3 where the minimum platform
29 * clock is 533MHz. This gives 5629 pico seconds.
30 */
31#define MIN_PIX_CLK 5629
32#define MAX_PIX_CLK 96096
33
34#include <linux/types.h>
35
36struct mfb_alpha {
37 int enable;
38 int alpha;
39};
40
41struct mfb_chroma_key {
42 int enable;
43 __u8 red_max;
44 __u8 green_max;
45 __u8 blue_max;
46 __u8 red_min;
47 __u8 green_min;
48 __u8 blue_min;
49};
50
51struct aoi_display_offset {
52 int x_aoi_d;
53 int y_aoi_d;
54};
55
56#define MFB_SET_CHROMA_KEY _IOW('M', 1, struct mfb_chroma_key)
57#define MFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
58#define MFB_SET_BRIGHTNESS _IOW('M', 3, __u8)
59
60#define MFB_SET_ALPHA 0x80014d00
61#define MFB_GET_ALPHA 0x40014d00
62#define MFB_SET_AOID 0x80084d04
63#define MFB_GET_AOID 0x40084d04
64#define MFB_SET_PIXFMT 0x80014d08
65#define MFB_GET_PIXFMT 0x40014d08
66
67#define FBIOGET_GWINFO 0x46E0
68#define FBIOPUT_GWINFO 0x46E1
69
70#ifdef __KERNEL__
71#include <linux/spinlock.h>
72
73/*
74 * These are the fields of area descriptor(in DDR memory) for every plane
75 */
76struct diu_ad {
77 /* Word 0(32-bit) in DDR memory */
78/* __u16 comp; */
79/* __u16 pixel_s:2; */
80/* __u16 pallete:1; */
81/* __u16 red_c:2; */
82/* __u16 green_c:2; */
83/* __u16 blue_c:2; */
84/* __u16 alpha_c:3; */
85/* __u16 byte_f:1; */
86/* __u16 res0:3; */
87
88 __be32 pix_fmt; /* hard coding pixel format */
89
90 /* Word 1(32-bit) in DDR memory */
91 __le32 addr;
92
93 /* Word 2(32-bit) in DDR memory */
94/* __u32 delta_xs:11; */
95/* __u32 res1:1; */
96/* __u32 delta_ys:11; */
97/* __u32 res2:1; */
98/* __u32 g_alpha:8; */
99 __le32 src_size_g_alpha;
100
101 /* Word 3(32-bit) in DDR memory */
102/* __u32 delta_xi:11; */
103/* __u32 res3:5; */
104/* __u32 delta_yi:11; */
105/* __u32 res4:3; */
106/* __u32 flip:2; */
107 __le32 aoi_size;
108
109 /* Word 4(32-bit) in DDR memory */
110 /*__u32 offset_xi:11;
111 __u32 res5:5;
112 __u32 offset_yi:11;
113 __u32 res6:5;
114 */
115 __le32 offset_xyi;
116
117 /* Word 5(32-bit) in DDR memory */
118 /*__u32 offset_xd:11;
119 __u32 res7:5;
120 __u32 offset_yd:11;
121 __u32 res8:5; */
122 __le32 offset_xyd;
123
124
125 /* Word 6(32-bit) in DDR memory */
126 __u8 ckmax_r;
127 __u8 ckmax_g;
128 __u8 ckmax_b;
129 __u8 res9;
130
131 /* Word 7(32-bit) in DDR memory */
132 __u8 ckmin_r;
133 __u8 ckmin_g;
134 __u8 ckmin_b;
135 __u8 res10;
136/* __u32 res10:8; */
137
138 /* Word 8(32-bit) in DDR memory */
139 __le32 next_ad;
140
141 /* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
142 __u32 paddr;
143} __attribute__ ((packed));
144
145/* DIU register map */
146struct diu {
147 __be32 desc[3];
148 __be32 gamma;
149 __be32 pallete;
150 __be32 cursor;
151 __be32 curs_pos;
152 __be32 diu_mode;
153 __be32 bgnd;
154 __be32 bgnd_wb;
155 __be32 disp_size;
156 __be32 wb_size;
157 __be32 wb_mem_addr;
158 __be32 hsyn_para;
159 __be32 vsyn_para;
160 __be32 syn_pol;
161 __be32 thresholds;
162 __be32 int_status;
163 __be32 int_mask;
164 __be32 colorbar[8];
165 __be32 filling;
166 __be32 plut;
167} __attribute__ ((packed));
168
169struct diu_hw {
170 struct diu *diu_reg;
171 spinlock_t reg_lock;
172
173 __u32 mode; /* DIU operation mode */
174};
175
176struct diu_addr {
177 __u8 __iomem *vaddr; /* Virtual address */
178 dma_addr_t paddr; /* Physical address */
179 __u32 offset;
180};
181
182struct diu_pool {
183 struct diu_addr ad;
184 struct diu_addr gamma;
185 struct diu_addr pallete;
186 struct diu_addr cursor;
187};
188
189#define FSL_DIU_BASE_OFFSET 0x2C000 /* Offset of DIU */
190#define INT_LCDC 64 /* DIU interrupt number */
191
192#define FSL_AOI_NUM 6 /* 5 AOIs and one dummy AOI */
193 /* 1 for plane 0, 2 for plane 1&2 each */
194
195/* Minimum X and Y resolutions */
196#define MIN_XRES 64
197#define MIN_YRES 64
198
199/* HW cursor parameters */
200#define MAX_CURS 32
201
202/* Modes of operation of DIU */
203#define MFB_MODE0 0 /* DIU off */
204#define MFB_MODE1 1 /* All three planes output to display */
205#define MFB_MODE2 2 /* Plane 1 to display, planes 2+3 written back*/
206#define MFB_MODE3 3 /* All three planes written back to memory */
207#define MFB_MODE4 4 /* Color bar generation */
208
209/* INT_STATUS/INT_MASK field descriptions */
210#define INT_VSYNC 0x01 /* Vsync interrupt */
211#define INT_VSYNC_WB 0x02 /* Vsync interrupt for write back operation */
212#define INT_UNDRUN 0x04 /* Under run exception interrupt */
213#define INT_PARERR 0x08 /* Display parameters error interrupt */
214#define INT_LS_BF_VS 0x10 /* Lines before vsync. interrupt */
215
216/* Panels'operation modes */
217#define MFB_TYPE_OUTPUT 0 /* Panel output to display */
218#define MFB_TYPE_OFF 1 /* Panel off */
219#define MFB_TYPE_WB 2 /* Panel written back to memory */
220#define MFB_TYPE_TEST 3 /* Panel generate color bar */
221
222#endif /* __KERNEL__ */
223#endif /* __FSL_DIU_FB_H__ */
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 15d200109446..d885c770eb84 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -368,7 +368,7 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)
368 return 1; 368 return 1;
369} 369}
370 370
371int __init igafb_init(void) 371static int __init igafb_init(void)
372{ 372{
373 struct fb_info *info; 373 struct fb_info *info;
374 struct pci_dev *pdev; 374 struct pci_dev *pdev;
@@ -531,6 +531,7 @@ int __init igafb_init(void)
531 iounmap(info->screen_base); 531 iounmap(info->screen_base);
532 kfree(par->mmap_map); 532 kfree(par->mmap_map);
533 kfree(info); 533 kfree(info);
534 return -ENODEV;
534 } 535 }
535 536
536#ifdef CONFIG_SPARC 537#ifdef CONFIG_SPARC
@@ -556,7 +557,7 @@ int __init igafb_init(void)
556 return 0; 557 return 0;
557} 558}
558 559
559int __init igafb_setup(char *options) 560static int __init igafb_setup(char *options)
560{ 561{
561 char *this_opt; 562 char *this_opt;
562 563
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 43f0639b1c10..5c363d026f64 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -40,6 +40,12 @@
40 */ 40 */
41#define DEBUG_VAR 1 41#define DEBUG_VAR 1
42 42
43#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
44 (defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \
45 defined(CONFIG_FB_IMX_MODULE))
46#define PWMR_BACKLIGHT_AVAILABLE
47#endif
48
43#define DRIVER_NAME "imx-fb" 49#define DRIVER_NAME "imx-fb"
44 50
45#define LCDC_SSA 0x00 51#define LCDC_SSA 0x00
@@ -175,7 +181,9 @@ struct imxfb_info {
175 181
176 struct imx_fb_videomode *mode; 182 struct imx_fb_videomode *mode;
177 int num_modes; 183 int num_modes;
184#ifdef PWMR_BACKLIGHT_AVAILABLE
178 struct backlight_device *bl; 185 struct backlight_device *bl;
186#endif
179 187
180 void (*lcd_power)(int); 188 void (*lcd_power)(int);
181 void (*backlight_power)(int); 189 void (*backlight_power)(int);
@@ -450,8 +458,7 @@ static int imxfb_set_par(struct fb_info *info)
450 return 0; 458 return 0;
451} 459}
452 460
453 461#ifdef PWMR_BACKLIGHT_AVAILABLE
454
455static int imxfb_bl_get_brightness(struct backlight_device *bl) 462static int imxfb_bl_get_brightness(struct backlight_device *bl)
456{ 463{
457 struct imxfb_info *fbi = bl_get_data(bl); 464 struct imxfb_info *fbi = bl_get_data(bl);
@@ -516,6 +523,7 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
516 if (fbi->bl) 523 if (fbi->bl)
517 backlight_device_unregister(fbi->bl); 524 backlight_device_unregister(fbi->bl);
518} 525}
526#endif
519 527
520static void imxfb_enable_controller(struct imxfb_info *fbi) 528static void imxfb_enable_controller(struct imxfb_info *fbi)
521{ 529{
@@ -647,6 +655,9 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
647 fbi->regs + LCDC_SIZE); 655 fbi->regs + LCDC_SIZE);
648 656
649 writel(fbi->pcr, fbi->regs + LCDC_PCR); 657 writel(fbi->pcr, fbi->regs + LCDC_PCR);
658#ifndef PWMR_BACKLIGHT_AVAILABLE
659 writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
660#endif
650 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); 661 writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
651 writel(fbi->dmacr, fbi->regs + LCDC_DMACR); 662 writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
652 663
@@ -847,7 +858,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
847 858
848 imxfb_enable_controller(fbi); 859 imxfb_enable_controller(fbi);
849 fbi->pdev = pdev; 860 fbi->pdev = pdev;
861#ifdef PWMR_BACKLIGHT_AVAILABLE
850 imxfb_init_backlight(fbi); 862 imxfb_init_backlight(fbi);
863#endif
851 864
852 return 0; 865 return 0;
853 866
@@ -885,7 +898,9 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
885 898
886 imxfb_disable_controller(fbi); 899 imxfb_disable_controller(fbi);
887 900
901#ifdef PWMR_BACKLIGHT_AVAILABLE
888 imxfb_exit_backlight(fbi); 902 imxfb_exit_backlight(fbi);
903#endif
889 unregister_framebuffer(info); 904 unregister_framebuffer(info);
890 905
891 pdata = pdev->dev.platform_data; 906 pdata = pdev->dev.platform_data;
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
new file mode 100644
index 000000000000..670ecaa0385a
--- /dev/null
+++ b/drivers/video/jz4740_fb.c
@@ -0,0 +1,847 @@
1/*
2 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC LCD framebuffer driver
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/mutex.h>
19#include <linux/platform_device.h>
20
21#include <linux/clk.h>
22#include <linux/delay.h>
23
24#include <linux/console.h>
25#include <linux/fb.h>
26
27#include <linux/dma-mapping.h>
28
29#include <asm/mach-jz4740/jz4740_fb.h>
30#include <asm/mach-jz4740/gpio.h>
31
32#define JZ_REG_LCD_CFG 0x00
33#define JZ_REG_LCD_VSYNC 0x04
34#define JZ_REG_LCD_HSYNC 0x08
35#define JZ_REG_LCD_VAT 0x0C
36#define JZ_REG_LCD_DAH 0x10
37#define JZ_REG_LCD_DAV 0x14
38#define JZ_REG_LCD_PS 0x18
39#define JZ_REG_LCD_CLS 0x1C
40#define JZ_REG_LCD_SPL 0x20
41#define JZ_REG_LCD_REV 0x24
42#define JZ_REG_LCD_CTRL 0x30
43#define JZ_REG_LCD_STATE 0x34
44#define JZ_REG_LCD_IID 0x38
45#define JZ_REG_LCD_DA0 0x40
46#define JZ_REG_LCD_SA0 0x44
47#define JZ_REG_LCD_FID0 0x48
48#define JZ_REG_LCD_CMD0 0x4C
49#define JZ_REG_LCD_DA1 0x50
50#define JZ_REG_LCD_SA1 0x54
51#define JZ_REG_LCD_FID1 0x58
52#define JZ_REG_LCD_CMD1 0x5C
53
54#define JZ_LCD_CFG_SLCD BIT(31)
55#define JZ_LCD_CFG_PS_DISABLE BIT(23)
56#define JZ_LCD_CFG_CLS_DISABLE BIT(22)
57#define JZ_LCD_CFG_SPL_DISABLE BIT(21)
58#define JZ_LCD_CFG_REV_DISABLE BIT(20)
59#define JZ_LCD_CFG_HSYNCM BIT(19)
60#define JZ_LCD_CFG_PCLKM BIT(18)
61#define JZ_LCD_CFG_INV BIT(17)
62#define JZ_LCD_CFG_SYNC_DIR BIT(16)
63#define JZ_LCD_CFG_PS_POLARITY BIT(15)
64#define JZ_LCD_CFG_CLS_POLARITY BIT(14)
65#define JZ_LCD_CFG_SPL_POLARITY BIT(13)
66#define JZ_LCD_CFG_REV_POLARITY BIT(12)
67#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11)
68#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10)
69#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9)
70#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8)
71#define JZ_LCD_CFG_18_BIT BIT(7)
72#define JZ_LCD_CFG_PDW (BIT(5) | BIT(4))
73#define JZ_LCD_CFG_MODE_MASK 0xf
74
75#define JZ_LCD_CTRL_BURST_4 (0x0 << 28)
76#define JZ_LCD_CTRL_BURST_8 (0x1 << 28)
77#define JZ_LCD_CTRL_BURST_16 (0x2 << 28)
78#define JZ_LCD_CTRL_RGB555 BIT(27)
79#define JZ_LCD_CTRL_OFUP BIT(26)
80#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24)
81#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24)
82#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24)
83#define JZ_LCD_CTRL_PDD_MASK (0xff << 16)
84#define JZ_LCD_CTRL_EOF_IRQ BIT(13)
85#define JZ_LCD_CTRL_SOF_IRQ BIT(12)
86#define JZ_LCD_CTRL_OFU_IRQ BIT(11)
87#define JZ_LCD_CTRL_IFU0_IRQ BIT(10)
88#define JZ_LCD_CTRL_IFU1_IRQ BIT(9)
89#define JZ_LCD_CTRL_DD_IRQ BIT(8)
90#define JZ_LCD_CTRL_QDD_IRQ BIT(7)
91#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6)
92#define JZ_LCD_CTRL_LSB_FISRT BIT(5)
93#define JZ_LCD_CTRL_DISABLE BIT(4)
94#define JZ_LCD_CTRL_ENABLE BIT(3)
95#define JZ_LCD_CTRL_BPP_1 0x0
96#define JZ_LCD_CTRL_BPP_2 0x1
97#define JZ_LCD_CTRL_BPP_4 0x2
98#define JZ_LCD_CTRL_BPP_8 0x3
99#define JZ_LCD_CTRL_BPP_15_16 0x4
100#define JZ_LCD_CTRL_BPP_18_24 0x5
101
102#define JZ_LCD_CMD_SOF_IRQ BIT(15)
103#define JZ_LCD_CMD_EOF_IRQ BIT(16)
104#define JZ_LCD_CMD_ENABLE_PAL BIT(12)
105
106#define JZ_LCD_SYNC_MASK 0x3ff
107
108#define JZ_LCD_STATE_DISABLED BIT(0)
109
110struct jzfb_framedesc {
111 uint32_t next;
112 uint32_t addr;
113 uint32_t id;
114 uint32_t cmd;
115} __packed;
116
117struct jzfb {
118 struct fb_info *fb;
119 struct platform_device *pdev;
120 void __iomem *base;
121 struct resource *mem;
122 struct jz4740_fb_platform_data *pdata;
123
124 size_t vidmem_size;
125 void *vidmem;
126 dma_addr_t vidmem_phys;
127 struct jzfb_framedesc *framedesc;
128 dma_addr_t framedesc_phys;
129
130 struct clk *ldclk;
131 struct clk *lpclk;
132
133 unsigned is_enabled:1;
134 struct mutex lock;
135
136 uint32_t pseudo_palette[16];
137};
138
139static const struct fb_fix_screeninfo jzfb_fix __devinitdata = {
140 .id = "JZ4740 FB",
141 .type = FB_TYPE_PACKED_PIXELS,
142 .visual = FB_VISUAL_TRUECOLOR,
143 .xpanstep = 0,
144 .ypanstep = 0,
145 .ywrapstep = 0,
146 .accel = FB_ACCEL_NONE,
147};
148
149static const struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = {
150 JZ_GPIO_BULK_PIN(LCD_PCLK),
151 JZ_GPIO_BULK_PIN(LCD_HSYNC),
152 JZ_GPIO_BULK_PIN(LCD_VSYNC),
153 JZ_GPIO_BULK_PIN(LCD_DE),
154 JZ_GPIO_BULK_PIN(LCD_PS),
155 JZ_GPIO_BULK_PIN(LCD_REV),
156 JZ_GPIO_BULK_PIN(LCD_CLS),
157 JZ_GPIO_BULK_PIN(LCD_SPL),
158};
159
160static const struct jz_gpio_bulk_request jz_lcd_data_pins[] = {
161 JZ_GPIO_BULK_PIN(LCD_DATA0),
162 JZ_GPIO_BULK_PIN(LCD_DATA1),
163 JZ_GPIO_BULK_PIN(LCD_DATA2),
164 JZ_GPIO_BULK_PIN(LCD_DATA3),
165 JZ_GPIO_BULK_PIN(LCD_DATA4),
166 JZ_GPIO_BULK_PIN(LCD_DATA5),
167 JZ_GPIO_BULK_PIN(LCD_DATA6),
168 JZ_GPIO_BULK_PIN(LCD_DATA7),
169 JZ_GPIO_BULK_PIN(LCD_DATA8),
170 JZ_GPIO_BULK_PIN(LCD_DATA9),
171 JZ_GPIO_BULK_PIN(LCD_DATA10),
172 JZ_GPIO_BULK_PIN(LCD_DATA11),
173 JZ_GPIO_BULK_PIN(LCD_DATA12),
174 JZ_GPIO_BULK_PIN(LCD_DATA13),
175 JZ_GPIO_BULK_PIN(LCD_DATA14),
176 JZ_GPIO_BULK_PIN(LCD_DATA15),
177 JZ_GPIO_BULK_PIN(LCD_DATA16),
178 JZ_GPIO_BULK_PIN(LCD_DATA17),
179};
180
181static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb)
182{
183 unsigned int num;
184
185 switch (jzfb->pdata->lcd_type) {
186 case JZ_LCD_TYPE_GENERIC_16_BIT:
187 num = 4;
188 break;
189 case JZ_LCD_TYPE_GENERIC_18_BIT:
190 num = 4;
191 break;
192 case JZ_LCD_TYPE_8BIT_SERIAL:
193 num = 3;
194 break;
195 case JZ_LCD_TYPE_SPECIAL_TFT_1:
196 case JZ_LCD_TYPE_SPECIAL_TFT_2:
197 case JZ_LCD_TYPE_SPECIAL_TFT_3:
198 num = 8;
199 break;
200 default:
201 num = 0;
202 break;
203 }
204 return num;
205}
206
207static unsigned int jzfb_num_data_pins(struct jzfb *jzfb)
208{
209 unsigned int num;
210
211 switch (jzfb->pdata->lcd_type) {
212 case JZ_LCD_TYPE_GENERIC_16_BIT:
213 num = 16;
214 break;
215 case JZ_LCD_TYPE_GENERIC_18_BIT:
216 num = 18;
217 break;
218 case JZ_LCD_TYPE_8BIT_SERIAL:
219 num = 8;
220 break;
221 case JZ_LCD_TYPE_SPECIAL_TFT_1:
222 case JZ_LCD_TYPE_SPECIAL_TFT_2:
223 case JZ_LCD_TYPE_SPECIAL_TFT_3:
224 if (jzfb->pdata->bpp == 18)
225 num = 18;
226 else
227 num = 16;
228 break;
229 default:
230 num = 0;
231 break;
232 }
233 return num;
234}
235
236/* Based on CNVT_TOHW macro from skeletonfb.c */
237static inline uint32_t jzfb_convert_color_to_hw(unsigned val,
238 struct fb_bitfield *bf)
239{
240 return (((val << bf->length) + 0x7FFF - val) >> 16) << bf->offset;
241}
242
243static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green,
244 unsigned blue, unsigned transp, struct fb_info *fb)
245{
246 uint32_t color;
247
248 if (regno >= 16)
249 return -EINVAL;
250
251 color = jzfb_convert_color_to_hw(red, &fb->var.red);
252 color |= jzfb_convert_color_to_hw(green, &fb->var.green);
253 color |= jzfb_convert_color_to_hw(blue, &fb->var.blue);
254 color |= jzfb_convert_color_to_hw(transp, &fb->var.transp);
255
256 ((uint32_t *)(fb->pseudo_palette))[regno] = color;
257
258 return 0;
259}
260
261static int jzfb_get_controller_bpp(struct jzfb *jzfb)
262{
263 switch (jzfb->pdata->bpp) {
264 case 18:
265 case 24:
266 return 32;
267 case 15:
268 return 16;
269 default:
270 return jzfb->pdata->bpp;
271 }
272}
273
274static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb,
275 struct fb_var_screeninfo *var)
276{
277 size_t i;
278 struct fb_videomode *mode = jzfb->pdata->modes;
279
280 for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
281 if (mode->xres == var->xres && mode->yres == var->yres)
282 return mode;
283 }
284
285 return NULL;
286}
287
288static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
289{
290 struct jzfb *jzfb = fb->par;
291 struct fb_videomode *mode;
292
293 if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
294 var->bits_per_pixel != jzfb->pdata->bpp)
295 return -EINVAL;
296
297 mode = jzfb_get_mode(jzfb, var);
298 if (mode == NULL)
299 return -EINVAL;
300
301 fb_videomode_to_var(var, mode);
302
303 switch (jzfb->pdata->bpp) {
304 case 8:
305 break;
306 case 15:
307 var->red.offset = 10;
308 var->red.length = 5;
309 var->green.offset = 6;
310 var->green.length = 5;
311 var->blue.offset = 0;
312 var->blue.length = 5;
313 break;
314 case 16:
315 var->red.offset = 11;
316 var->red.length = 5;
317 var->green.offset = 5;
318 var->green.length = 6;
319 var->blue.offset = 0;
320 var->blue.length = 5;
321 break;
322 case 18:
323 var->red.offset = 16;
324 var->red.length = 6;
325 var->green.offset = 8;
326 var->green.length = 6;
327 var->blue.offset = 0;
328 var->blue.length = 6;
329 var->bits_per_pixel = 32;
330 break;
331 case 32:
332 case 24:
333 var->transp.offset = 24;
334 var->transp.length = 8;
335 var->red.offset = 16;
336 var->red.length = 8;
337 var->green.offset = 8;
338 var->green.length = 8;
339 var->blue.offset = 0;
340 var->blue.length = 8;
341 var->bits_per_pixel = 32;
342 break;
343 default:
344 break;
345 }
346
347 return 0;
348}
349
350static int jzfb_set_par(struct fb_info *info)
351{
352 struct jzfb *jzfb = info->par;
353 struct jz4740_fb_platform_data *pdata = jzfb->pdata;
354 struct fb_var_screeninfo *var = &info->var;
355 struct fb_videomode *mode;
356 uint16_t hds, vds;
357 uint16_t hde, vde;
358 uint16_t ht, vt;
359 uint32_t ctrl;
360 uint32_t cfg;
361 unsigned long rate;
362
363 mode = jzfb_get_mode(jzfb, var);
364 if (mode == NULL)
365 return -EINVAL;
366
367 if (mode == info->mode)
368 return 0;
369
370 info->mode = mode;
371
372 hds = mode->hsync_len + mode->left_margin;
373 hde = hds + mode->xres;
374 ht = hde + mode->right_margin;
375
376 vds = mode->vsync_len + mode->upper_margin;
377 vde = vds + mode->yres;
378 vt = vde + mode->lower_margin;
379
380 ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16;
381
382 switch (pdata->bpp) {
383 case 1:
384 ctrl |= JZ_LCD_CTRL_BPP_1;
385 break;
386 case 2:
387 ctrl |= JZ_LCD_CTRL_BPP_2;
388 break;
389 case 4:
390 ctrl |= JZ_LCD_CTRL_BPP_4;
391 break;
392 case 8:
393 ctrl |= JZ_LCD_CTRL_BPP_8;
394 break;
395 case 15:
396 ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */
397 case 16:
398 ctrl |= JZ_LCD_CTRL_BPP_15_16;
399 break;
400 case 18:
401 case 24:
402 case 32:
403 ctrl |= JZ_LCD_CTRL_BPP_18_24;
404 break;
405 default:
406 break;
407 }
408
409 cfg = pdata->lcd_type & 0xf;
410
411 if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT))
412 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
413
414 if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT))
415 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW;
416
417 if (pdata->pixclk_falling_edge)
418 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE;
419
420 if (pdata->date_enable_active_low)
421 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW;
422
423 if (pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT)
424 cfg |= JZ_LCD_CFG_18_BIT;
425
426 if (mode->pixclock) {
427 rate = PICOS2KHZ(mode->pixclock) * 1000;
428 mode->refresh = rate / vt / ht;
429 } else {
430 if (pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL)
431 rate = mode->refresh * (vt + 2 * mode->xres) * ht;
432 else
433 rate = mode->refresh * vt * ht;
434
435 mode->pixclock = KHZ2PICOS(rate / 1000);
436 }
437
438 mutex_lock(&jzfb->lock);
439 if (!jzfb->is_enabled)
440 clk_enable(jzfb->ldclk);
441 else
442 ctrl |= JZ_LCD_CTRL_ENABLE;
443
444 switch (pdata->lcd_type) {
445 case JZ_LCD_TYPE_SPECIAL_TFT_1:
446 case JZ_LCD_TYPE_SPECIAL_TFT_2:
447 case JZ_LCD_TYPE_SPECIAL_TFT_3:
448 writel(pdata->special_tft_config.spl, jzfb->base + JZ_REG_LCD_SPL);
449 writel(pdata->special_tft_config.cls, jzfb->base + JZ_REG_LCD_CLS);
450 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_PS);
451 writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_REV);
452 break;
453 default:
454 cfg |= JZ_LCD_CFG_PS_DISABLE;
455 cfg |= JZ_LCD_CFG_CLS_DISABLE;
456 cfg |= JZ_LCD_CFG_SPL_DISABLE;
457 cfg |= JZ_LCD_CFG_REV_DISABLE;
458 break;
459 }
460
461 writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC);
462 writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC);
463
464 writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT);
465
466 writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH);
467 writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV);
468
469 writel(cfg, jzfb->base + JZ_REG_LCD_CFG);
470
471 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
472
473 if (!jzfb->is_enabled)
474 clk_disable(jzfb->ldclk);
475
476 mutex_unlock(&jzfb->lock);
477
478 clk_set_rate(jzfb->lpclk, rate);
479 clk_set_rate(jzfb->ldclk, rate * 3);
480
481 return 0;
482}
483
484static void jzfb_enable(struct jzfb *jzfb)
485{
486 uint32_t ctrl;
487
488 clk_enable(jzfb->ldclk);
489
490 jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
491 jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
492
493 writel(0, jzfb->base + JZ_REG_LCD_STATE);
494
495 writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
496
497 ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
498 ctrl |= JZ_LCD_CTRL_ENABLE;
499 ctrl &= ~JZ_LCD_CTRL_DISABLE;
500 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
501}
502
503static void jzfb_disable(struct jzfb *jzfb)
504{
505 uint32_t ctrl;
506
507 ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
508 ctrl |= JZ_LCD_CTRL_DISABLE;
509 writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
510 do {
511 ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
512 } while (!(ctrl & JZ_LCD_STATE_DISABLED));
513
514 jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
515 jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
516
517 clk_disable(jzfb->ldclk);
518}
519
520static int jzfb_blank(int blank_mode, struct fb_info *info)
521{
522 struct jzfb *jzfb = info->par;
523
524 switch (blank_mode) {
525 case FB_BLANK_UNBLANK:
526 mutex_lock(&jzfb->lock);
527 if (jzfb->is_enabled) {
528 mutex_unlock(&jzfb->lock);
529 return 0;
530 }
531
532 jzfb_enable(jzfb);
533 jzfb->is_enabled = 1;
534
535 mutex_unlock(&jzfb->lock);
536 break;
537 default:
538 mutex_lock(&jzfb->lock);
539 if (!jzfb->is_enabled) {
540 mutex_unlock(&jzfb->lock);
541 return 0;
542 }
543
544 jzfb_disable(jzfb);
545 jzfb->is_enabled = 0;
546
547 mutex_unlock(&jzfb->lock);
548 break;
549 }
550
551 return 0;
552}
553
554static int jzfb_alloc_devmem(struct jzfb *jzfb)
555{
556 int max_videosize = 0;
557 struct fb_videomode *mode = jzfb->pdata->modes;
558 void *page;
559 int i;
560
561 for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
562 if (max_videosize < mode->xres * mode->yres)
563 max_videosize = mode->xres * mode->yres;
564 }
565
566 max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3;
567
568 jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev,
569 sizeof(*jzfb->framedesc),
570 &jzfb->framedesc_phys, GFP_KERNEL);
571
572 if (!jzfb->framedesc)
573 return -ENOMEM;
574
575 jzfb->vidmem_size = PAGE_ALIGN(max_videosize);
576 jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev,
577 jzfb->vidmem_size,
578 &jzfb->vidmem_phys, GFP_KERNEL);
579
580 if (!jzfb->vidmem)
581 goto err_free_framedesc;
582
583 for (page = jzfb->vidmem;
584 page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
585 page += PAGE_SIZE) {
586 SetPageReserved(virt_to_page(page));
587 }
588
589 jzfb->framedesc->next = jzfb->framedesc_phys;
590 jzfb->framedesc->addr = jzfb->vidmem_phys;
591 jzfb->framedesc->id = 0xdeafbead;
592 jzfb->framedesc->cmd = 0;
593 jzfb->framedesc->cmd |= max_videosize / 4;
594
595 return 0;
596
597err_free_framedesc:
598 dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
599 jzfb->framedesc, jzfb->framedesc_phys);
600 return -ENOMEM;
601}
602
603static void jzfb_free_devmem(struct jzfb *jzfb)
604{
605 dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size,
606 jzfb->vidmem, jzfb->vidmem_phys);
607 dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc),
608 jzfb->framedesc, jzfb->framedesc_phys);
609}
610
611static struct fb_ops jzfb_ops = {
612 .owner = THIS_MODULE,
613 .fb_check_var = jzfb_check_var,
614 .fb_set_par = jzfb_set_par,
615 .fb_blank = jzfb_blank,
616 .fb_fillrect = sys_fillrect,
617 .fb_copyarea = sys_copyarea,
618 .fb_imageblit = sys_imageblit,
619 .fb_setcolreg = jzfb_setcolreg,
620};
621
622static int __devinit jzfb_probe(struct platform_device *pdev)
623{
624 int ret;
625 struct jzfb *jzfb;
626 struct fb_info *fb;
627 struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data;
628 struct resource *mem;
629
630 if (!pdata) {
631 dev_err(&pdev->dev, "Missing platform data\n");
632 return -ENXIO;
633 }
634
635 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
636 if (!mem) {
637 dev_err(&pdev->dev, "Failed to get register memory resource\n");
638 return -ENXIO;
639 }
640
641 mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
642 if (!mem) {
643 dev_err(&pdev->dev, "Failed to request register memory region\n");
644 return -EBUSY;
645 }
646
647 fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
648 if (!fb) {
649 dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
650 ret = -ENOMEM;
651 goto err_release_mem_region;
652 }
653
654 fb->fbops = &jzfb_ops;
655 fb->flags = FBINFO_DEFAULT;
656
657 jzfb = fb->par;
658 jzfb->pdev = pdev;
659 jzfb->pdata = pdata;
660 jzfb->mem = mem;
661
662 jzfb->ldclk = clk_get(&pdev->dev, "lcd");
663 if (IS_ERR(jzfb->ldclk)) {
664 ret = PTR_ERR(jzfb->ldclk);
665 dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
666 goto err_framebuffer_release;
667 }
668
669 jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
670 if (IS_ERR(jzfb->lpclk)) {
671 ret = PTR_ERR(jzfb->lpclk);
672 dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
673 goto err_put_ldclk;
674 }
675
676 jzfb->base = ioremap(mem->start, resource_size(mem));
677 if (!jzfb->base) {
678 dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
679 ret = -EBUSY;
680 goto err_put_lpclk;
681 }
682
683 platform_set_drvdata(pdev, jzfb);
684
685 mutex_init(&jzfb->lock);
686
687 fb_videomode_to_modelist(pdata->modes, pdata->num_modes,
688 &fb->modelist);
689 fb_videomode_to_var(&fb->var, pdata->modes);
690 fb->var.bits_per_pixel = pdata->bpp;
691 jzfb_check_var(&fb->var, fb);
692
693 ret = jzfb_alloc_devmem(jzfb);
694 if (ret) {
695 dev_err(&pdev->dev, "Failed to allocate video memory\n");
696 goto err_iounmap;
697 }
698
699 fb->fix = jzfb_fix;
700 fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8;
701 fb->fix.mmio_start = mem->start;
702 fb->fix.mmio_len = resource_size(mem);
703 fb->fix.smem_start = jzfb->vidmem_phys;
704 fb->fix.smem_len = fb->fix.line_length * fb->var.yres;
705 fb->screen_base = jzfb->vidmem;
706 fb->pseudo_palette = jzfb->pseudo_palette;
707
708 fb_alloc_cmap(&fb->cmap, 256, 0);
709
710 clk_enable(jzfb->ldclk);
711 jzfb->is_enabled = 1;
712
713 writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
714
715 fb->mode = NULL;
716 jzfb_set_par(fb);
717
718 jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
719 jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
720
721 ret = register_framebuffer(fb);
722 if (ret) {
723 dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
724 goto err_free_devmem;
725 }
726
727 jzfb->fb = fb;
728
729 return 0;
730
731err_free_devmem:
732 jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
733 jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
734
735 fb_dealloc_cmap(&fb->cmap);
736 jzfb_free_devmem(jzfb);
737err_iounmap:
738 iounmap(jzfb->base);
739err_put_lpclk:
740 clk_put(jzfb->lpclk);
741err_put_ldclk:
742 clk_put(jzfb->ldclk);
743err_framebuffer_release:
744 framebuffer_release(fb);
745err_release_mem_region:
746 release_mem_region(mem->start, resource_size(mem));
747 return ret;
748}
749
750static int __devexit jzfb_remove(struct platform_device *pdev)
751{
752 struct jzfb *jzfb = platform_get_drvdata(pdev);
753
754 jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb);
755
756 jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
757 jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
758
759 iounmap(jzfb->base);
760 release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
761
762 fb_dealloc_cmap(&jzfb->fb->cmap);
763 jzfb_free_devmem(jzfb);
764
765 platform_set_drvdata(pdev, NULL);
766
767 clk_put(jzfb->lpclk);
768 clk_put(jzfb->ldclk);
769
770 framebuffer_release(jzfb->fb);
771
772 return 0;
773}
774
775#ifdef CONFIG_PM
776
777static int jzfb_suspend(struct device *dev)
778{
779 struct jzfb *jzfb = dev_get_drvdata(dev);
780
781 acquire_console_sem();
782 fb_set_suspend(jzfb->fb, 1);
783 release_console_sem();
784
785 mutex_lock(&jzfb->lock);
786 if (jzfb->is_enabled)
787 jzfb_disable(jzfb);
788 mutex_unlock(&jzfb->lock);
789
790 return 0;
791}
792
793static int jzfb_resume(struct device *dev)
794{
795 struct jzfb *jzfb = dev_get_drvdata(dev);
796 clk_enable(jzfb->ldclk);
797
798 mutex_lock(&jzfb->lock);
799 if (jzfb->is_enabled)
800 jzfb_enable(jzfb);
801 mutex_unlock(&jzfb->lock);
802
803 acquire_console_sem();
804 fb_set_suspend(jzfb->fb, 0);
805 release_console_sem();
806
807 return 0;
808}
809
810static const struct dev_pm_ops jzfb_pm_ops = {
811 .suspend = jzfb_suspend,
812 .resume = jzfb_resume,
813 .poweroff = jzfb_suspend,
814 .restore = jzfb_resume,
815};
816
817#define JZFB_PM_OPS (&jzfb_pm_ops)
818
819#else
820#define JZFB_PM_OPS NULL
821#endif
822
823static struct platform_driver jzfb_driver = {
824 .probe = jzfb_probe,
825 .remove = __devexit_p(jzfb_remove),
826 .driver = {
827 .name = "jz4740-fb",
828 .pm = JZFB_PM_OPS,
829 },
830};
831
832static int __init jzfb_init(void)
833{
834 return platform_driver_register(&jzfb_driver);
835}
836module_init(jzfb_init);
837
838static void __exit jzfb_exit(void)
839{
840 platform_driver_unregister(&jzfb_driver);
841}
842module_exit(jzfb_exit);
843
844MODULE_LICENSE("GPL");
845MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
846MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver");
847MODULE_ALIAS("platform:jz4740-fb");
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 9e8bf7d5e249..b599e5e36ced 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -529,7 +529,7 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
529 var->transp.length = 0; 529 var->transp.length = 0;
530} 530}
531 531
532static void leo_unmap_regs(struct of_device *op, struct fb_info *info, 532static void leo_unmap_regs(struct platform_device *op, struct fb_info *info,
533 struct leo_par *par) 533 struct leo_par *par)
534{ 534{
535 if (par->lc_ss0_usr) 535 if (par->lc_ss0_usr)
@@ -547,7 +547,7 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info,
547 of_iounmap(&op->resource[0], info->screen_base, 0x800000); 547 of_iounmap(&op->resource[0], info->screen_base, 0x800000);
548} 548}
549 549
550static int __devinit leo_probe(struct of_device *op, 550static int __devinit leo_probe(struct platform_device *op,
551 const struct of_device_id *match) 551 const struct of_device_id *match)
552{ 552{
553 struct device_node *dp = op->dev.of_node; 553 struct device_node *dp = op->dev.of_node;
@@ -637,7 +637,7 @@ out_err:
637 return err; 637 return err;
638} 638}
639 639
640static int __devexit leo_remove(struct of_device *op) 640static int __devexit leo_remove(struct platform_device *op)
641{ 641{
642 struct fb_info *info = dev_get_drvdata(&op->dev); 642 struct fb_info *info = dev_get_drvdata(&op->dev);
643 struct leo_par *par = info->par; 643 struct leo_par *par = info->par;
@@ -677,12 +677,12 @@ static int __init leo_init(void)
677 if (fb_get_options("leofb", NULL)) 677 if (fb_get_options("leofb", NULL))
678 return -ENODEV; 678 return -ENODEV;
679 679
680 return of_register_driver(&leo_driver, &of_bus_type); 680 return of_register_platform_driver(&leo_driver);
681} 681}
682 682
683static void __exit leo_exit(void) 683static void __exit leo_exit(void)
684{ 684{
685 of_unregister_driver(&leo_driver); 685 of_unregister_platform_driver(&leo_driver);
686} 686}
687 687
688module_init(leo_init); 688module_init(leo_init);
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 403b14445a78..0fb280ead3dc 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -191,7 +191,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
191 }; 191 };
192 192
193 i2c_new_probed_device(&m2info->maven.adapter, 193 i2c_new_probed_device(&m2info->maven.adapter,
194 &maven_info, addr_list); 194 &maven_info, addr_list, NULL);
195 } 195 }
196 } 196 }
197 return m2info; 197 return m2info;
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index f3a4e15672d9..f96a471cb1a8 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -151,13 +151,13 @@ static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) {
151static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { 151static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) {
152#if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) 152#if defined(__alpha__) || defined(__i386__) || defined(__x86_64__)
153 /* 153 /*
154 * memcpy_toio works for us if: 154 * iowrite32_rep works for us if:
155 * (1) Copies data as 32bit quantities, not byte after byte, 155 * (1) Copies data as 32bit quantities, not byte after byte,
156 * (2) Performs LE ordered stores, and 156 * (2) Performs LE ordered stores, and
157 * (3) It copes with unaligned source (destination is guaranteed to be page 157 * (3) It copes with unaligned source (destination is guaranteed to be page
158 * aligned and length is guaranteed to be multiple of 4). 158 * aligned and length is guaranteed to be multiple of 4).
159 */ 159 */
160 memcpy_toio(va.vaddr, src, len); 160 iowrite32_rep(va.vaddr, src, len >> 2);
161#else 161#else
162 u_int32_t __iomem* addr = va.vaddr; 162 u_int32_t __iomem* addr = va.vaddr;
163 163
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c
index 4e2b8cc3d460..b1c4374cf940 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfb.c
@@ -550,7 +550,7 @@ static int mb862xx_gdc_init(struct mb862xxfb_par *par)
550 return 0; 550 return 0;
551} 551}
552 552
553static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, 553static int __devinit of_platform_mb862xx_probe(struct platform_device *ofdev,
554 const struct of_device_id *id) 554 const struct of_device_id *id)
555{ 555{
556 struct device_node *np = ofdev->dev.of_node; 556 struct device_node *np = ofdev->dev.of_node;
@@ -669,7 +669,7 @@ fbrel:
669 return ret; 669 return ret;
670} 670}
671 671
672static int __devexit of_platform_mb862xx_remove(struct of_device *ofdev) 672static int __devexit of_platform_mb862xx_remove(struct platform_device *ofdev)
673{ 673{
674 struct fb_info *fbi = dev_get_drvdata(&ofdev->dev); 674 struct fb_info *fbi = dev_get_drvdata(&ofdev->dev);
675 struct mb862xxfb_par *par = fbi->par; 675 struct mb862xxfb_par *par = fbi->par;
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index c1ff271017a9..7c316c34dfca 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -187,10 +187,8 @@ static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
187 187
188static void mddi_handle_rev_data_avail(struct mddi_info *mddi) 188static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
189{ 189{
190 union mddi_rev *rev = mddi->rev_data;
191 uint32_t rev_data_count; 190 uint32_t rev_data_count;
192 uint32_t rev_crc_err_count; 191 uint32_t rev_crc_err_count;
193 int i;
194 struct reg_read_info *ri; 192 struct reg_read_info *ri;
195 size_t prev_offset; 193 size_t prev_offset;
196 uint16_t length; 194 uint16_t length;
@@ -670,7 +668,7 @@ static int __init mddi_rev_data_setup(struct mddi_info *mddi)
670 return 0; 668 return 0;
671} 669}
672 670
673static int __init mddi_probe(struct platform_device *pdev) 671static int __devinit mddi_probe(struct platform_device *pdev)
674{ 672{
675 struct msm_mddi_platform_data *pdata = pdev->dev.platform_data; 673 struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
676 struct mddi_info *mddi = &mddi_info[pdev->id]; 674 struct mddi_info *mddi = &mddi_info[pdev->id];
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 19c01c6208e8..3c28db03ad39 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -258,7 +258,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
258{ 258{
259 int put_needed, ret = 0; 259 int put_needed, ret = 0;
260 struct file *file; 260 struct file *file;
261 unsigned long vstart;
262 261
263 file = fget_light(img->memory_id, &put_needed); 262 file = fget_light(img->memory_id, &put_needed);
264 if (file == NULL) 263 if (file == NULL)
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 46dda7d8aaee..cb163a5397be 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -19,13 +19,14 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/of.h>
23#include <linux/of_address.h>
22#include <linux/interrupt.h> 24#include <linux/interrupt.h>
23#include <linux/fb.h> 25#include <linux/fb.h>
24#include <linux/init.h> 26#include <linux/init.h>
25#include <linux/ioport.h> 27#include <linux/ioport.h>
26#include <linux/pci.h> 28#include <linux/pci.h>
27#include <asm/io.h> 29#include <asm/io.h>
28#include <asm/prom.h>
29 30
30#ifdef CONFIG_PPC64 31#ifdef CONFIG_PPC64
31#include <asm/pci-bridge.h> 32#include <asm/pci-bridge.h>
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
index 2be94eb3bbf5..10459d8bd9a0 100644
--- a/drivers/video/omap/lcd_apollon.c
+++ b/drivers/video/omap/lcd_apollon.c
@@ -25,7 +25,6 @@
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27#include <mach/gpio.h> 27#include <mach/gpio.h>
28#include <plat/mux.h>
29 28
30#include "omapfb.h" 29#include "omapfb.h"
31 30
@@ -34,8 +33,6 @@
34static int apollon_panel_init(struct lcd_panel *panel, 33static int apollon_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev) 34 struct omapfb_device *fbdev)
36{ 35{
37 /* configure LCD PWR_EN */
38 omap_cfg_reg(M21_242X_GPIO11);
39 return 0; 36 return 0;
40} 37}
41 38
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 1f8eb70e2937..07fbb8a733bb 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -592,7 +592,7 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
592 r = omapdss_sdi_display_enable(dssdev); 592 r = omapdss_sdi_display_enable(dssdev);
593 if (r) { 593 if (r) {
594 pr_err("%s sdi enable failed\n", __func__); 594 pr_err("%s sdi enable failed\n", __func__);
595 return r; 595 goto fail_unlock;
596 } 596 }
597 597
598 /*FIXME tweak me */ 598 /*FIXME tweak me */
@@ -633,6 +633,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
633 return acx565akm_bl_update_status(md->bl_dev); 633 return acx565akm_bl_update_status(md->bl_dev);
634fail: 634fail:
635 omapdss_sdi_display_disable(dssdev); 635 omapdss_sdi_display_disable(dssdev);
636fail_unlock:
637 mutex_unlock(&md->mutex);
636 return r; 638 return r;
637} 639}
638 640
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index aaf5d308a046..e1c765d11419 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -28,12 +28,13 @@
28#include <linux/fb.h> 28#include <linux/fb.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <linux/completion.h>
32#include <linux/workqueue.h> 31#include <linux/workqueue.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/regulator/consumer.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35 35
36#include <plat/display.h> 36#include <plat/display.h>
37#include <plat/nokia-dsi-panel.h>
37 38
38/* DSI Virtual channel. Hardcoded for now. */ 39/* DSI Virtual channel. Hardcoded for now. */
39#define TCH 0 40#define TCH 0
@@ -62,11 +63,136 @@
62#define DCS_GET_ID2 0xdb 63#define DCS_GET_ID2 0xdb
63#define DCS_GET_ID3 0xdc 64#define DCS_GET_ID3 0xdc
64 65
65/* #define TAAL_USE_ESD_CHECK */
66#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000) 66#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
67 67
68static irqreturn_t taal_te_isr(int irq, void *data);
69static void taal_te_timeout_work_callback(struct work_struct *work);
68static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 70static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
69 71
72struct panel_regulator {
73 struct regulator *regulator;
74 const char *name;
75 int min_uV;
76 int max_uV;
77};
78
79static void free_regulators(struct panel_regulator *regulators, int n)
80{
81 int i;
82
83 for (i = 0; i < n; i++) {
84 /* disable/put in reverse order */
85 regulator_disable(regulators[n - i - 1].regulator);
86 regulator_put(regulators[n - i - 1].regulator);
87 }
88}
89
90static int init_regulators(struct omap_dss_device *dssdev,
91 struct panel_regulator *regulators, int n)
92{
93 int r, i, v;
94
95 for (i = 0; i < n; i++) {
96 struct regulator *reg;
97
98 reg = regulator_get(&dssdev->dev, regulators[i].name);
99 if (IS_ERR(reg)) {
100 dev_err(&dssdev->dev, "failed to get regulator %s\n",
101 regulators[i].name);
102 r = PTR_ERR(reg);
103 goto err;
104 }
105
106 /* FIXME: better handling of fixed vs. variable regulators */
107 v = regulator_get_voltage(reg);
108 if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
109 r = regulator_set_voltage(reg, regulators[i].min_uV,
110 regulators[i].max_uV);
111 if (r) {
112 dev_err(&dssdev->dev,
113 "failed to set regulator %s voltage\n",
114 regulators[i].name);
115 regulator_put(reg);
116 goto err;
117 }
118 }
119
120 r = regulator_enable(reg);
121 if (r) {
122 dev_err(&dssdev->dev, "failed to enable regulator %s\n",
123 regulators[i].name);
124 regulator_put(reg);
125 goto err;
126 }
127
128 regulators[i].regulator = reg;
129 }
130
131 return 0;
132
133err:
134 free_regulators(regulators, i);
135
136 return r;
137}
138
139/**
140 * struct panel_config - panel configuration
141 * @name: panel name
142 * @type: panel type
143 * @timings: panel resolution
144 * @sleep: various panel specific delays, passed to msleep() if non-zero
145 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
146 * @regulators: array of panel regulators
147 * @num_regulators: number of regulators in the array
148 */
149struct panel_config {
150 const char *name;
151 int type;
152
153 struct omap_video_timings timings;
154
155 struct {
156 unsigned int sleep_in;
157 unsigned int sleep_out;
158 unsigned int hw_reset;
159 unsigned int enable_te;
160 } sleep;
161
162 struct {
163 unsigned int high;
164 unsigned int low;
165 } reset_sequence;
166
167 struct panel_regulator *regulators;
168 int num_regulators;
169};
170
171enum {
172 PANEL_TAAL,
173};
174
175static struct panel_config panel_configs[] = {
176 {
177 .name = "taal",
178 .type = PANEL_TAAL,
179 .timings = {
180 .x_res = 864,
181 .y_res = 480,
182 },
183 .sleep = {
184 .sleep_in = 5,
185 .sleep_out = 5,
186 .hw_reset = 5,
187 .enable_te = 100, /* possible panel bug */
188 },
189 .reset_sequence = {
190 .high = 10,
191 .low = 10,
192 },
193 },
194};
195
70struct taal_data { 196struct taal_data {
71 struct mutex lock; 197 struct mutex lock;
72 198
@@ -84,8 +210,15 @@ struct taal_data {
84 bool mirror; 210 bool mirror;
85 211
86 bool te_enabled; 212 bool te_enabled;
87 bool use_ext_te; 213
88 struct completion te_completion; 214 atomic_t do_update;
215 struct {
216 u16 x;
217 u16 y;
218 u16 w;
219 u16 h;
220 } update_region;
221 struct delayed_work te_timeout_work;
89 222
90 bool use_dsi_bl; 223 bool use_dsi_bl;
91 224
@@ -96,8 +229,16 @@ struct taal_data {
96 229
97 struct workqueue_struct *esd_wq; 230 struct workqueue_struct *esd_wq;
98 struct delayed_work esd_work; 231 struct delayed_work esd_work;
232
233 struct panel_config *panel_config;
99}; 234};
100 235
236static inline struct nokia_dsi_panel_data
237*get_panel_data(const struct omap_dss_device *dssdev)
238{
239 return (struct nokia_dsi_panel_data *) dssdev->data;
240}
241
101static void taal_esd_work(struct work_struct *work); 242static void taal_esd_work(struct work_struct *work);
102 243
103static void hw_guard_start(struct taal_data *td, int guard_msec) 244static void hw_guard_start(struct taal_data *td, int guard_msec)
@@ -159,7 +300,8 @@ static int taal_sleep_in(struct taal_data *td)
159 300
160 hw_guard_start(td, 120); 301 hw_guard_start(td, 120);
161 302
162 msleep(5); 303 if (td->panel_config->sleep.sleep_in)
304 msleep(td->panel_config->sleep.sleep_in);
163 305
164 return 0; 306 return 0;
165} 307}
@@ -176,7 +318,8 @@ static int taal_sleep_out(struct taal_data *td)
176 318
177 hw_guard_start(td, 120); 319 hw_guard_start(td, 120);
178 320
179 msleep(5); 321 if (td->panel_config->sleep.sleep_out)
322 msleep(td->panel_config->sleep.sleep_out);
180 323
181 return 0; 324 return 0;
182} 325}
@@ -279,6 +422,7 @@ static int taal_bl_update_status(struct backlight_device *dev)
279{ 422{
280 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); 423 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
281 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 424 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
425 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
282 int r; 426 int r;
283 int level; 427 int level;
284 428
@@ -290,24 +434,26 @@ static int taal_bl_update_status(struct backlight_device *dev)
290 434
291 dev_dbg(&dssdev->dev, "update brightness to %d\n", level); 435 dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
292 436
437 mutex_lock(&td->lock);
438
293 if (td->use_dsi_bl) { 439 if (td->use_dsi_bl) {
294 if (td->enabled) { 440 if (td->enabled) {
295 dsi_bus_lock(); 441 dsi_bus_lock();
296 r = taal_dcs_write_1(DCS_BRIGHTNESS, level); 442 r = taal_dcs_write_1(DCS_BRIGHTNESS, level);
297 dsi_bus_unlock(); 443 dsi_bus_unlock();
298 if (r) 444 } else {
299 return r; 445 r = 0;
300 } 446 }
301 } else { 447 } else {
302 if (!dssdev->set_backlight) 448 if (!panel_data->set_backlight)
303 return -EINVAL; 449 r = -EINVAL;
304 450 else
305 r = dssdev->set_backlight(dssdev, level); 451 r = panel_data->set_backlight(dssdev, level);
306 if (r)
307 return r;
308 } 452 }
309 453
310 return 0; 454 mutex_unlock(&td->lock);
455
456 return r;
311} 457}
312 458
313static int taal_bl_get_intensity(struct backlight_device *dev) 459static int taal_bl_get_intensity(struct backlight_device *dev)
@@ -344,16 +490,6 @@ static void taal_get_resolution(struct omap_dss_device *dssdev,
344 } 490 }
345} 491}
346 492
347static irqreturn_t taal_te_isr(int irq, void *data)
348{
349 struct omap_dss_device *dssdev = data;
350 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
351
352 complete_all(&td->te_completion);
353
354 return IRQ_HANDLED;
355}
356
357static ssize_t taal_num_errors_show(struct device *dev, 493static ssize_t taal_num_errors_show(struct device *dev,
358 struct device_attribute *attr, char *buf) 494 struct device_attribute *attr, char *buf)
359{ 495{
@@ -362,6 +498,8 @@ static ssize_t taal_num_errors_show(struct device *dev,
362 u8 errors; 498 u8 errors;
363 int r; 499 int r;
364 500
501 mutex_lock(&td->lock);
502
365 if (td->enabled) { 503 if (td->enabled) {
366 dsi_bus_lock(); 504 dsi_bus_lock();
367 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); 505 r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors);
@@ -370,6 +508,8 @@ static ssize_t taal_num_errors_show(struct device *dev,
370 r = -ENODEV; 508 r = -ENODEV;
371 } 509 }
372 510
511 mutex_unlock(&td->lock);
512
373 if (r) 513 if (r)
374 return r; 514 return r;
375 515
@@ -384,6 +524,8 @@ static ssize_t taal_hw_revision_show(struct device *dev,
384 u8 id1, id2, id3; 524 u8 id1, id2, id3;
385 int r; 525 int r;
386 526
527 mutex_lock(&td->lock);
528
387 if (td->enabled) { 529 if (td->enabled) {
388 dsi_bus_lock(); 530 dsi_bus_lock();
389 r = taal_get_id(&id1, &id2, &id3); 531 r = taal_get_id(&id1, &id2, &id3);
@@ -392,6 +534,8 @@ static ssize_t taal_hw_revision_show(struct device *dev,
392 r = -ENODEV; 534 r = -ENODEV;
393 } 535 }
394 536
537 mutex_unlock(&td->lock);
538
395 if (r) 539 if (r)
396 return r; 540 return r;
397 541
@@ -441,6 +585,8 @@ static ssize_t store_cabc_mode(struct device *dev,
441 if (i == ARRAY_SIZE(cabc_modes)) 585 if (i == ARRAY_SIZE(cabc_modes))
442 return -EINVAL; 586 return -EINVAL;
443 587
588 mutex_lock(&td->lock);
589
444 if (td->enabled) { 590 if (td->enabled) {
445 dsi_bus_lock(); 591 dsi_bus_lock();
446 if (!td->cabc_broken) 592 if (!td->cabc_broken)
@@ -450,6 +596,8 @@ static ssize_t store_cabc_mode(struct device *dev,
450 596
451 td->cabc_mode = i; 597 td->cabc_mode = i;
452 598
599 mutex_unlock(&td->lock);
600
453 return count; 601 return count;
454} 602}
455 603
@@ -488,47 +636,93 @@ static struct attribute_group taal_attr_group = {
488 .attrs = taal_attrs, 636 .attrs = taal_attrs,
489}; 637};
490 638
639static void taal_hw_reset(struct omap_dss_device *dssdev)
640{
641 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
642 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
643
644 if (panel_data->reset_gpio == -1)
645 return;
646
647 gpio_set_value(panel_data->reset_gpio, 1);
648 if (td->panel_config->reset_sequence.high)
649 udelay(td->panel_config->reset_sequence.high);
650 /* reset the panel */
651 gpio_set_value(panel_data->reset_gpio, 0);
652 /* assert reset */
653 if (td->panel_config->reset_sequence.low)
654 udelay(td->panel_config->reset_sequence.low);
655 gpio_set_value(panel_data->reset_gpio, 1);
656 /* wait after releasing reset */
657 if (td->panel_config->sleep.hw_reset)
658 msleep(td->panel_config->sleep.hw_reset);
659}
660
491static int taal_probe(struct omap_dss_device *dssdev) 661static int taal_probe(struct omap_dss_device *dssdev)
492{ 662{
493 struct backlight_properties props; 663 struct backlight_properties props;
494 struct taal_data *td; 664 struct taal_data *td;
495 struct backlight_device *bldev; 665 struct backlight_device *bldev;
496 int r; 666 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
497 667 struct panel_config *panel_config = NULL;
498 const struct omap_video_timings taal_panel_timings = { 668 int r, i;
499 .x_res = 864,
500 .y_res = 480,
501 };
502 669
503 dev_dbg(&dssdev->dev, "probe\n"); 670 dev_dbg(&dssdev->dev, "probe\n");
504 671
672 if (!panel_data || !panel_data->name) {
673 r = -EINVAL;
674 goto err;
675 }
676
677 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
678 if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
679 panel_config = &panel_configs[i];
680 break;
681 }
682 }
683
684 if (!panel_config) {
685 r = -EINVAL;
686 goto err;
687 }
688
505 dssdev->panel.config = OMAP_DSS_LCD_TFT; 689 dssdev->panel.config = OMAP_DSS_LCD_TFT;
506 dssdev->panel.timings = taal_panel_timings; 690 dssdev->panel.timings = panel_config->timings;
507 dssdev->ctrl.pixel_size = 24; 691 dssdev->ctrl.pixel_size = 24;
508 692
509 td = kzalloc(sizeof(*td), GFP_KERNEL); 693 td = kzalloc(sizeof(*td), GFP_KERNEL);
510 if (!td) { 694 if (!td) {
511 r = -ENOMEM; 695 r = -ENOMEM;
512 goto err0; 696 goto err;
513 } 697 }
514 td->dssdev = dssdev; 698 td->dssdev = dssdev;
699 td->panel_config = panel_config;
515 700
516 mutex_init(&td->lock); 701 mutex_init(&td->lock);
517 702
703 atomic_set(&td->do_update, 0);
704
705 r = init_regulators(dssdev, panel_config->regulators,
706 panel_config->num_regulators);
707 if (r)
708 goto err_reg;
709
518 td->esd_wq = create_singlethread_workqueue("taal_esd"); 710 td->esd_wq = create_singlethread_workqueue("taal_esd");
519 if (td->esd_wq == NULL) { 711 if (td->esd_wq == NULL) {
520 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 712 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
521 r = -ENOMEM; 713 r = -ENOMEM;
522 goto err1; 714 goto err_wq;
523 } 715 }
524 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); 716 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
525 717
526 dev_set_drvdata(&dssdev->dev, td); 718 dev_set_drvdata(&dssdev->dev, td);
527 719
720 taal_hw_reset(dssdev);
721
528 /* if no platform set_backlight() defined, presume DSI backlight 722 /* if no platform set_backlight() defined, presume DSI backlight
529 * control */ 723 * control */
530 memset(&props, 0, sizeof(struct backlight_properties)); 724 memset(&props, 0, sizeof(struct backlight_properties));
531 if (!dssdev->set_backlight) 725 if (!panel_data->set_backlight)
532 td->use_dsi_bl = true; 726 td->use_dsi_bl = true;
533 727
534 if (td->use_dsi_bl) 728 if (td->use_dsi_bl)
@@ -539,7 +733,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
539 &taal_bl_ops, &props); 733 &taal_bl_ops, &props);
540 if (IS_ERR(bldev)) { 734 if (IS_ERR(bldev)) {
541 r = PTR_ERR(bldev); 735 r = PTR_ERR(bldev);
542 goto err2; 736 goto err_bl;
543 } 737 }
544 738
545 td->bldev = bldev; 739 td->bldev = bldev;
@@ -553,13 +747,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
553 747
554 taal_bl_update_status(bldev); 748 taal_bl_update_status(bldev);
555 749
556 if (dssdev->phy.dsi.ext_te) { 750 if (panel_data->use_ext_te) {
557 int gpio = dssdev->phy.dsi.ext_te_gpio; 751 int gpio = panel_data->ext_te_gpio;
558 752
559 r = gpio_request(gpio, "taal irq"); 753 r = gpio_request(gpio, "taal irq");
560 if (r) { 754 if (r) {
561 dev_err(&dssdev->dev, "GPIO request failed\n"); 755 dev_err(&dssdev->dev, "GPIO request failed\n");
562 goto err3; 756 goto err_gpio;
563 } 757 }
564 758
565 gpio_direction_input(gpio); 759 gpio_direction_input(gpio);
@@ -571,49 +765,52 @@ static int taal_probe(struct omap_dss_device *dssdev)
571 if (r) { 765 if (r) {
572 dev_err(&dssdev->dev, "IRQ request failed\n"); 766 dev_err(&dssdev->dev, "IRQ request failed\n");
573 gpio_free(gpio); 767 gpio_free(gpio);
574 goto err3; 768 goto err_irq;
575 } 769 }
576 770
577 init_completion(&td->te_completion); 771 INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
772 taal_te_timeout_work_callback);
578 773
579 td->use_ext_te = true; 774 dev_dbg(&dssdev->dev, "Using GPIO TE\n");
580 } 775 }
581 776
582 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); 777 r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group);
583 if (r) { 778 if (r) {
584 dev_err(&dssdev->dev, "failed to create sysfs files\n"); 779 dev_err(&dssdev->dev, "failed to create sysfs files\n");
585 goto err4; 780 goto err_sysfs;
586 } 781 }
587 782
588 return 0; 783 return 0;
589err4: 784err_sysfs:
590 if (td->use_ext_te) { 785 if (panel_data->use_ext_te)
591 int gpio = dssdev->phy.dsi.ext_te_gpio; 786 free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
592 free_irq(gpio_to_irq(gpio), dssdev); 787err_irq:
593 gpio_free(gpio); 788 if (panel_data->use_ext_te)
594 } 789 gpio_free(panel_data->ext_te_gpio);
595err3: 790err_gpio:
596 backlight_device_unregister(bldev); 791 backlight_device_unregister(bldev);
597err2: 792err_bl:
598 cancel_delayed_work_sync(&td->esd_work);
599 destroy_workqueue(td->esd_wq); 793 destroy_workqueue(td->esd_wq);
600err1: 794err_wq:
795 free_regulators(panel_config->regulators, panel_config->num_regulators);
796err_reg:
601 kfree(td); 797 kfree(td);
602err0: 798err:
603 return r; 799 return r;
604} 800}
605 801
606static void taal_remove(struct omap_dss_device *dssdev) 802static void taal_remove(struct omap_dss_device *dssdev)
607{ 803{
608 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 804 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
805 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
609 struct backlight_device *bldev; 806 struct backlight_device *bldev;
610 807
611 dev_dbg(&dssdev->dev, "remove\n"); 808 dev_dbg(&dssdev->dev, "remove\n");
612 809
613 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); 810 sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
614 811
615 if (td->use_ext_te) { 812 if (panel_data->use_ext_te) {
616 int gpio = dssdev->phy.dsi.ext_te_gpio; 813 int gpio = panel_data->ext_te_gpio;
617 free_irq(gpio_to_irq(gpio), dssdev); 814 free_irq(gpio_to_irq(gpio), dssdev);
618 gpio_free(gpio); 815 gpio_free(gpio);
619 } 816 }
@@ -623,9 +820,15 @@ static void taal_remove(struct omap_dss_device *dssdev)
623 taal_bl_update_status(bldev); 820 taal_bl_update_status(bldev);
624 backlight_device_unregister(bldev); 821 backlight_device_unregister(bldev);
625 822
626 cancel_delayed_work_sync(&td->esd_work); 823 cancel_delayed_work(&td->esd_work);
627 destroy_workqueue(td->esd_wq); 824 destroy_workqueue(td->esd_wq);
628 825
826 /* reset, to be sure that the panel is in a valid state */
827 taal_hw_reset(dssdev);
828
829 free_regulators(td->panel_config->regulators,
830 td->panel_config->num_regulators);
831
629 kfree(td); 832 kfree(td);
630} 833}
631 834
@@ -635,23 +838,14 @@ static int taal_power_on(struct omap_dss_device *dssdev)
635 u8 id1, id2, id3; 838 u8 id1, id2, id3;
636 int r; 839 int r;
637 840
638 if (dssdev->platform_enable) {
639 r = dssdev->platform_enable(dssdev);
640 if (r)
641 return r;
642 }
643
644 /* it seems we have to wait a bit until taal is ready */
645 msleep(5);
646
647 dsi_bus_lock();
648
649 r = omapdss_dsi_display_enable(dssdev); 841 r = omapdss_dsi_display_enable(dssdev);
650 if (r) { 842 if (r) {
651 dev_err(&dssdev->dev, "failed to enable DSI\n"); 843 dev_err(&dssdev->dev, "failed to enable DSI\n");
652 goto err0; 844 goto err0;
653 } 845 }
654 846
847 taal_hw_reset(dssdev);
848
655 omapdss_dsi_vc_enable_hs(TCH, false); 849 omapdss_dsi_vc_enable_hs(TCH, false);
656 850
657 r = taal_sleep_out(td); 851 r = taal_sleep_out(td);
@@ -662,34 +856,47 @@ static int taal_power_on(struct omap_dss_device *dssdev)
662 if (r) 856 if (r)
663 goto err; 857 goto err;
664 858
665 /* on early revisions CABC is broken */ 859 /* on early Taal revisions CABC is broken */
666 if (id2 == 0x00 || id2 == 0xff || id2 == 0x81) 860 if (td->panel_config->type == PANEL_TAAL &&
861 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
667 td->cabc_broken = true; 862 td->cabc_broken = true;
668 863
669 taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); 864 r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff);
670 taal_dcs_write_1(DCS_CTRL_DISPLAY, (1<<2) | (1<<5)); /* BL | BCTRL */ 865 if (r)
866 goto err;
867
868 r = taal_dcs_write_1(DCS_CTRL_DISPLAY,
869 (1<<2) | (1<<5)); /* BL | BCTRL */
870 if (r)
871 goto err;
872
873 r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
874 if (r)
875 goto err;
671 876
672 taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 877 r = taal_set_addr_mode(td->rotate, td->mirror);
878 if (r)
879 goto err;
673 880
674 taal_set_addr_mode(td->rotate, td->mirror); 881 if (!td->cabc_broken) {
675 if (!td->cabc_broken) 882 r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode);
676 taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); 883 if (r)
884 goto err;
885 }
677 886
678 taal_dcs_write_0(DCS_DISPLAY_ON); 887 r = taal_dcs_write_0(DCS_DISPLAY_ON);
888 if (r)
889 goto err;
679 890
680 r = _taal_enable_te(dssdev, td->te_enabled); 891 r = _taal_enable_te(dssdev, td->te_enabled);
681 if (r) 892 if (r)
682 goto err; 893 goto err;
683 894
684#ifdef TAAL_USE_ESD_CHECK
685 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD);
686#endif
687
688 td->enabled = 1; 895 td->enabled = 1;
689 896
690 if (!td->intro_printed) { 897 if (!td->intro_printed) {
691 dev_info(&dssdev->dev, "revision %02x.%02x.%02x\n", 898 dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n",
692 id1, id2, id3); 899 td->panel_config->name, id1, id2, id3);
693 if (td->cabc_broken) 900 if (td->cabc_broken)
694 dev_info(&dssdev->dev, 901 dev_info(&dssdev->dev,
695 "old Taal version, CABC disabled\n"); 902 "old Taal version, CABC disabled\n");
@@ -698,46 +905,44 @@ static int taal_power_on(struct omap_dss_device *dssdev)
698 905
699 omapdss_dsi_vc_enable_hs(TCH, true); 906 omapdss_dsi_vc_enable_hs(TCH, true);
700 907
701 dsi_bus_unlock();
702
703 return 0; 908 return 0;
704err: 909err:
910 dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
911
912 taal_hw_reset(dssdev);
913
705 omapdss_dsi_display_disable(dssdev); 914 omapdss_dsi_display_disable(dssdev);
706err0: 915err0:
707 dsi_bus_unlock();
708 if (dssdev->platform_disable)
709 dssdev->platform_disable(dssdev);
710
711 return r; 916 return r;
712} 917}
713 918
714static void taal_power_off(struct omap_dss_device *dssdev) 919static void taal_power_off(struct omap_dss_device *dssdev)
715{ 920{
716 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 921 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
922 int r;
717 923
718 dsi_bus_lock(); 924 r = taal_dcs_write_0(DCS_DISPLAY_OFF);
719 925 if (!r) {
720 cancel_delayed_work(&td->esd_work); 926 r = taal_sleep_in(td);
721 927 /* HACK: wait a bit so that the message goes through */
722 taal_dcs_write_0(DCS_DISPLAY_OFF); 928 msleep(10);
723 taal_sleep_in(td); 929 }
724 930
725 /* wait a bit so that the message goes through */ 931 if (r) {
726 msleep(10); 932 dev_err(&dssdev->dev,
933 "error disabling panel, issuing HW reset\n");
934 taal_hw_reset(dssdev);
935 }
727 936
728 omapdss_dsi_display_disable(dssdev); 937 omapdss_dsi_display_disable(dssdev);
729 938
730 if (dssdev->platform_disable)
731 dssdev->platform_disable(dssdev);
732
733 td->enabled = 0; 939 td->enabled = 0;
734
735 dsi_bus_unlock();
736} 940}
737 941
738static int taal_enable(struct omap_dss_device *dssdev) 942static int taal_enable(struct omap_dss_device *dssdev)
739{ 943{
740 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 944 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
945 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
741 int r; 946 int r;
742 947
743 dev_dbg(&dssdev->dev, "enable\n"); 948 dev_dbg(&dssdev->dev, "enable\n");
@@ -749,10 +954,19 @@ static int taal_enable(struct omap_dss_device *dssdev)
749 goto err; 954 goto err;
750 } 955 }
751 956
957 dsi_bus_lock();
958
752 r = taal_power_on(dssdev); 959 r = taal_power_on(dssdev);
960
961 dsi_bus_unlock();
962
753 if (r) 963 if (r)
754 goto err; 964 goto err;
755 965
966 if (panel_data->use_esd_check)
967 queue_delayed_work(td->esd_wq, &td->esd_work,
968 TAAL_ESD_CHECK_PERIOD);
969
756 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 970 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
757 971
758 mutex_unlock(&td->lock); 972 mutex_unlock(&td->lock);
@@ -772,9 +986,15 @@ static void taal_disable(struct omap_dss_device *dssdev)
772 986
773 mutex_lock(&td->lock); 987 mutex_lock(&td->lock);
774 988
989 cancel_delayed_work(&td->esd_work);
990
991 dsi_bus_lock();
992
775 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 993 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
776 taal_power_off(dssdev); 994 taal_power_off(dssdev);
777 995
996 dsi_bus_unlock();
997
778 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 998 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
779 999
780 mutex_unlock(&td->lock); 1000 mutex_unlock(&td->lock);
@@ -794,7 +1014,14 @@ static int taal_suspend(struct omap_dss_device *dssdev)
794 goto err; 1014 goto err;
795 } 1015 }
796 1016
1017 cancel_delayed_work(&td->esd_work);
1018
1019 dsi_bus_lock();
1020
797 taal_power_off(dssdev); 1021 taal_power_off(dssdev);
1022
1023 dsi_bus_unlock();
1024
798 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 1025 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
799 1026
800 mutex_unlock(&td->lock); 1027 mutex_unlock(&td->lock);
@@ -808,6 +1035,7 @@ err:
808static int taal_resume(struct omap_dss_device *dssdev) 1035static int taal_resume(struct omap_dss_device *dssdev)
809{ 1036{
810 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1037 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1038 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
811 int r; 1039 int r;
812 1040
813 dev_dbg(&dssdev->dev, "resume\n"); 1041 dev_dbg(&dssdev->dev, "resume\n");
@@ -819,8 +1047,20 @@ static int taal_resume(struct omap_dss_device *dssdev)
819 goto err; 1047 goto err;
820 } 1048 }
821 1049
1050 dsi_bus_lock();
1051
822 r = taal_power_on(dssdev); 1052 r = taal_power_on(dssdev);
823 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 1053
1054 dsi_bus_unlock();
1055
1056 if (r) {
1057 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1058 } else {
1059 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1060 if (panel_data->use_esd_check)
1061 queue_delayed_work(td->esd_wq, &td->esd_work,
1062 TAAL_ESD_CHECK_PERIOD);
1063 }
824 1064
825 mutex_unlock(&td->lock); 1065 mutex_unlock(&td->lock);
826 1066
@@ -837,10 +1077,52 @@ static void taal_framedone_cb(int err, void *data)
837 dsi_bus_unlock(); 1077 dsi_bus_unlock();
838} 1078}
839 1079
1080static irqreturn_t taal_te_isr(int irq, void *data)
1081{
1082 struct omap_dss_device *dssdev = data;
1083 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1084 int old;
1085 int r;
1086
1087 old = atomic_cmpxchg(&td->do_update, 1, 0);
1088
1089 if (old) {
1090 cancel_delayed_work(&td->te_timeout_work);
1091
1092 r = omap_dsi_update(dssdev, TCH,
1093 td->update_region.x,
1094 td->update_region.y,
1095 td->update_region.w,
1096 td->update_region.h,
1097 taal_framedone_cb, dssdev);
1098 if (r)
1099 goto err;
1100 }
1101
1102 return IRQ_HANDLED;
1103err:
1104 dev_err(&dssdev->dev, "start update failed\n");
1105 dsi_bus_unlock();
1106 return IRQ_HANDLED;
1107}
1108
1109static void taal_te_timeout_work_callback(struct work_struct *work)
1110{
1111 struct taal_data *td = container_of(work, struct taal_data,
1112 te_timeout_work.work);
1113 struct omap_dss_device *dssdev = td->dssdev;
1114
1115 dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1116
1117 atomic_set(&td->do_update, 0);
1118 dsi_bus_unlock();
1119}
1120
840static int taal_update(struct omap_dss_device *dssdev, 1121static int taal_update(struct omap_dss_device *dssdev,
841 u16 x, u16 y, u16 w, u16 h) 1122 u16 x, u16 y, u16 w, u16 h)
842{ 1123{
843 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1124 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1125 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
844 int r; 1126 int r;
845 1127
846 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 1128 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -853,7 +1135,7 @@ static int taal_update(struct omap_dss_device *dssdev,
853 goto err; 1135 goto err;
854 } 1136 }
855 1137
856 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h); 1138 r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
857 if (r) 1139 if (r)
858 goto err; 1140 goto err;
859 1141
@@ -861,10 +1143,21 @@ static int taal_update(struct omap_dss_device *dssdev,
861 if (r) 1143 if (r)
862 goto err; 1144 goto err;
863 1145
864 r = omap_dsi_update(dssdev, TCH, x, y, w, h, 1146 if (td->te_enabled && panel_data->use_ext_te) {
865 taal_framedone_cb, dssdev); 1147 td->update_region.x = x;
866 if (r) 1148 td->update_region.y = y;
867 goto err; 1149 td->update_region.w = w;
1150 td->update_region.h = h;
1151 barrier();
1152 schedule_delayed_work(&td->te_timeout_work,
1153 msecs_to_jiffies(250));
1154 atomic_set(&td->do_update, 1);
1155 } else {
1156 r = omap_dsi_update(dssdev, TCH, x, y, w, h,
1157 taal_framedone_cb, dssdev);
1158 if (r)
1159 goto err;
1160 }
868 1161
869 /* note: no bus_unlock here. unlock is in framedone_cb */ 1162 /* note: no bus_unlock here. unlock is in framedone_cb */
870 mutex_unlock(&td->lock); 1163 mutex_unlock(&td->lock);
@@ -894,20 +1187,19 @@ static int taal_sync(struct omap_dss_device *dssdev)
894static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) 1187static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
895{ 1188{
896 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1189 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1190 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
897 int r; 1191 int r;
898 1192
899 td->te_enabled = enable;
900
901 if (enable) 1193 if (enable)
902 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1194 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
903 else 1195 else
904 r = taal_dcs_write_0(DCS_TEAR_OFF); 1196 r = taal_dcs_write_0(DCS_TEAR_OFF);
905 1197
906 omapdss_dsi_enable_te(dssdev, enable); 1198 if (!panel_data->use_ext_te)
1199 omapdss_dsi_enable_te(dssdev, enable);
907 1200
908 /* XXX for some reason, DSI TE breaks if we don't wait here. 1201 if (td->panel_config->sleep.enable_te)
909 * Panel bug? Needs more studying */ 1202 msleep(td->panel_config->sleep.enable_te);
910 msleep(100);
911 1203
912 return r; 1204 return r;
913} 1205}
@@ -918,10 +1210,26 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
918 int r; 1210 int r;
919 1211
920 mutex_lock(&td->lock); 1212 mutex_lock(&td->lock);
1213
1214 if (td->te_enabled == enable)
1215 goto end;
1216
921 dsi_bus_lock(); 1217 dsi_bus_lock();
922 1218
923 r = _taal_enable_te(dssdev, enable); 1219 if (td->enabled) {
1220 r = _taal_enable_te(dssdev, enable);
1221 if (r)
1222 goto err;
1223 }
1224
1225 td->te_enabled = enable;
1226
1227 dsi_bus_unlock();
1228end:
1229 mutex_unlock(&td->lock);
924 1230
1231 return 0;
1232err:
925 dsi_bus_unlock(); 1233 dsi_bus_unlock();
926 mutex_unlock(&td->lock); 1234 mutex_unlock(&td->lock);
927 1235
@@ -948,6 +1256,10 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
948 dev_dbg(&dssdev->dev, "rotate %d\n", rotate); 1256 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
949 1257
950 mutex_lock(&td->lock); 1258 mutex_lock(&td->lock);
1259
1260 if (td->rotate == rotate)
1261 goto end;
1262
951 dsi_bus_lock(); 1263 dsi_bus_lock();
952 1264
953 if (td->enabled) { 1265 if (td->enabled) {
@@ -959,6 +1271,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
959 td->rotate = rotate; 1271 td->rotate = rotate;
960 1272
961 dsi_bus_unlock(); 1273 dsi_bus_unlock();
1274end:
962 mutex_unlock(&td->lock); 1275 mutex_unlock(&td->lock);
963 return 0; 1276 return 0;
964err: 1277err:
@@ -987,6 +1300,10 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
987 dev_dbg(&dssdev->dev, "mirror %d\n", enable); 1300 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
988 1301
989 mutex_lock(&td->lock); 1302 mutex_lock(&td->lock);
1303
1304 if (td->mirror == enable)
1305 goto end;
1306
990 dsi_bus_lock(); 1307 dsi_bus_lock();
991 if (td->enabled) { 1308 if (td->enabled) {
992 r = taal_set_addr_mode(td->rotate, enable); 1309 r = taal_set_addr_mode(td->rotate, enable);
@@ -997,6 +1314,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
997 td->mirror = enable; 1314 td->mirror = enable;
998 1315
999 dsi_bus_unlock(); 1316 dsi_bus_unlock();
1317end:
1000 mutex_unlock(&td->lock); 1318 mutex_unlock(&td->lock);
1001 return 0; 1319 return 0;
1002err: 1320err:
@@ -1024,23 +1342,30 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1024 int r; 1342 int r;
1025 1343
1026 mutex_lock(&td->lock); 1344 mutex_lock(&td->lock);
1345
1346 if (!td->enabled) {
1347 r = -ENODEV;
1348 goto err1;
1349 }
1350
1027 dsi_bus_lock(); 1351 dsi_bus_lock();
1028 1352
1029 r = taal_dcs_read_1(DCS_GET_ID1, &id1); 1353 r = taal_dcs_read_1(DCS_GET_ID1, &id1);
1030 if (r) 1354 if (r)
1031 goto err; 1355 goto err2;
1032 r = taal_dcs_read_1(DCS_GET_ID2, &id2); 1356 r = taal_dcs_read_1(DCS_GET_ID2, &id2);
1033 if (r) 1357 if (r)
1034 goto err; 1358 goto err2;
1035 r = taal_dcs_read_1(DCS_GET_ID3, &id3); 1359 r = taal_dcs_read_1(DCS_GET_ID3, &id3);
1036 if (r) 1360 if (r)
1037 goto err; 1361 goto err2;
1038 1362
1039 dsi_bus_unlock(); 1363 dsi_bus_unlock();
1040 mutex_unlock(&td->lock); 1364 mutex_unlock(&td->lock);
1041 return 0; 1365 return 0;
1042err: 1366err2:
1043 dsi_bus_unlock(); 1367 dsi_bus_unlock();
1368err1:
1044 mutex_unlock(&td->lock); 1369 mutex_unlock(&td->lock);
1045 return r; 1370 return r;
1046} 1371}
@@ -1128,6 +1453,7 @@ static void taal_esd_work(struct work_struct *work)
1128 struct taal_data *td = container_of(work, struct taal_data, 1453 struct taal_data *td = container_of(work, struct taal_data,
1129 esd_work.work); 1454 esd_work.work);
1130 struct omap_dss_device *dssdev = td->dssdev; 1455 struct omap_dss_device *dssdev = td->dssdev;
1456 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1131 u8 state1, state2; 1457 u8 state1, state2;
1132 int r; 1458 int r;
1133 1459
@@ -1168,7 +1494,7 @@ static void taal_esd_work(struct work_struct *work)
1168 } 1494 }
1169 /* Self-diagnostics result is also shown on TE GPIO line. We need 1495 /* Self-diagnostics result is also shown on TE GPIO line. We need
1170 * to re-enable TE after self diagnostics */ 1496 * to re-enable TE after self diagnostics */
1171 if (td->use_ext_te && td->te_enabled) { 1497 if (td->te_enabled && panel_data->use_ext_te) {
1172 r = taal_dcs_write_1(DCS_TEAR_ON, 0); 1498 r = taal_dcs_write_1(DCS_TEAR_ON, 0);
1173 if (r) 1499 if (r)
1174 goto err; 1500 goto err;
@@ -1184,6 +1510,7 @@ err:
1184 dev_err(&dssdev->dev, "performing LCD reset\n"); 1510 dev_err(&dssdev->dev, "performing LCD reset\n");
1185 1511
1186 taal_power_off(dssdev); 1512 taal_power_off(dssdev);
1513 taal_hw_reset(dssdev);
1187 taal_power_on(dssdev); 1514 taal_power_on(dssdev);
1188 1515
1189 dsi_bus_unlock(); 1516 dsi_bus_unlock();
diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
index fa434ca6e4b7..e320e67d06f3 100644
--- a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
+++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
@@ -73,8 +73,12 @@ static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
73 73
74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) 74static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
75{ 75{
76 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | 76 dssdev->panel.config = OMAP_DSS_LCD_TFT |
77 OMAP_DSS_LCD_IHS; 77 OMAP_DSS_LCD_IVS |
78 OMAP_DSS_LCD_IHS |
79 OMAP_DSS_LCD_IPC |
80 OMAP_DSS_LCD_ONOFF;
81
78 dssdev->panel.timings = toppoly_tdo_panel_timings; 82 dssdev->panel.timings = toppoly_tdo_panel_timings;
79 83
80 return 0; 84 return 0;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e777e352dbcd..5ecdc0004094 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -31,6 +31,7 @@
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/hardirq.h>
34 35
35#include <plat/sram.h> 36#include <plat/sram.h>
36#include <plat/clock.h> 37#include <plat/clock.h>
@@ -335,7 +336,7 @@ void dispc_save_context(void)
335void dispc_restore_context(void) 336void dispc_restore_context(void)
336{ 337{
337 RR(SYSCONFIG); 338 RR(SYSCONFIG);
338 RR(IRQENABLE); 339 /*RR(IRQENABLE);*/
339 /*RR(CONTROL);*/ 340 /*RR(CONTROL);*/
340 RR(CONFIG); 341 RR(CONFIG);
341 RR(DEFAULT_COLOR0); 342 RR(DEFAULT_COLOR0);
@@ -472,6 +473,15 @@ void dispc_restore_context(void)
472 473
473 /* enable last, because LCD & DIGIT enable are here */ 474 /* enable last, because LCD & DIGIT enable are here */
474 RR(CONTROL); 475 RR(CONTROL);
476
477 /* clear spurious SYNC_LOST_DIGIT interrupts */
478 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
479
480 /*
481 * enable last so IRQs won't trigger before
482 * the context is fully restored
483 */
484 RR(IRQENABLE);
475} 485}
476 486
477#undef SR 487#undef SR
@@ -3019,7 +3029,7 @@ void dispc_fake_vsync_irq(void)
3019 u32 irqstatus = DISPC_IRQ_VSYNC; 3029 u32 irqstatus = DISPC_IRQ_VSYNC;
3020 int i; 3030 int i;
3021 3031
3022 local_irq_disable(); 3032 WARN_ON(!in_interrupt());
3023 3033
3024 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { 3034 for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
3025 struct omap_dispc_isr_data *isr_data; 3035 struct omap_dispc_isr_data *isr_data;
@@ -3031,8 +3041,6 @@ void dispc_fake_vsync_irq(void)
3031 if (isr_data->mask & irqstatus) 3041 if (isr_data->mask & irqstatus)
3032 isr_data->isr(isr_data->arg, irqstatus); 3042 isr_data->isr(isr_data->arg, irqstatus);
3033 } 3043 }
3034
3035 local_irq_enable();
3036} 3044}
3037#endif 3045#endif
3038 3046
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index ef8c8529dda2..22dd7a474f79 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -82,6 +82,9 @@ static ssize_t display_upd_mode_store(struct device *dev,
82 int val, r; 82 int val, r;
83 enum omap_dss_update_mode mode; 83 enum omap_dss_update_mode mode;
84 84
85 if (!dssdev->driver->set_update_mode)
86 return -EINVAL;
87
85 val = simple_strtoul(buf, NULL, 10); 88 val = simple_strtoul(buf, NULL, 10);
86 89
87 switch (val) { 90 switch (val) {
@@ -343,7 +346,6 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
343 case OMAP_DISPLAY_TYPE_VENC: 346 case OMAP_DISPLAY_TYPE_VENC:
344 case OMAP_DISPLAY_TYPE_SDI: 347 case OMAP_DISPLAY_TYPE_SDI:
345 return 24; 348 return 24;
346 return 24;
347 default: 349 default:
348 BUG(); 350 BUG();
349 } 351 }
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 3af207b2bde3..b3fa3a7db911 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -165,6 +165,14 @@ struct dsi_reg { u16 idx; };
165#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) 165#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) 166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
167#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) 167#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
168#define DSI_CIO_IRQ_ERROR_MASK \
169 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
170 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
171 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRCONTROL1 | \
172 DSI_CIO_IRQ_ERRCONTROL2 | DSI_CIO_IRQ_ERRCONTROL3 | \
173 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
174 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
175 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3)
168 176
169#define DSI_DT_DCS_SHORT_WRITE_0 0x05 177#define DSI_DT_DCS_SHORT_WRITE_0 0x05
170#define DSI_DT_DCS_SHORT_WRITE_1 0x15 178#define DSI_DT_DCS_SHORT_WRITE_1 0x15
@@ -232,13 +240,15 @@ static struct
232 unsigned pll_locked; 240 unsigned pll_locked;
233 241
234 struct completion bta_completion; 242 struct completion bta_completion;
243 void (*bta_callback)(void);
235 244
236 int update_channel; 245 int update_channel;
237 struct dsi_update_region update_region; 246 struct dsi_update_region update_region;
238 247
239 bool te_enabled; 248 bool te_enabled;
240 249
241 struct work_struct framedone_work; 250 struct workqueue_struct *workqueue;
251
242 void (*framedone_callback)(int, void *); 252 void (*framedone_callback)(int, void *);
243 void *framedone_data; 253 void *framedone_data;
244 254
@@ -509,9 +519,13 @@ void dsi_irq_handler(void)
509 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]); 519 dss_collect_irq_stats(vcstatus, dsi.irq_stats.vc_irqs[i]);
510#endif 520#endif
511 521
512 if (vcstatus & DSI_VC_IRQ_BTA) 522 if (vcstatus & DSI_VC_IRQ_BTA) {
513 complete(&dsi.bta_completion); 523 complete(&dsi.bta_completion);
514 524
525 if (dsi.bta_callback)
526 dsi.bta_callback();
527 }
528
515 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { 529 if (vcstatus & DSI_VC_IRQ_ERROR_MASK) {
516 DSSERR("DSI VC(%d) error, vc irqstatus %x\n", 530 DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
517 i, vcstatus); 531 i, vcstatus);
@@ -536,8 +550,12 @@ void dsi_irq_handler(void)
536 /* flush posted write */ 550 /* flush posted write */
537 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 551 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
538 552
539 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); 553 if (ciostatus & DSI_CIO_IRQ_ERROR_MASK) {
540 print_irq_status_cio(ciostatus); 554 DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
555 print_irq_status_cio(ciostatus);
556 } else if (debug_irq) {
557 print_irq_status_cio(ciostatus);
558 }
541 } 559 }
542 560
543 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 561 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
@@ -584,11 +602,8 @@ static void _dsi_initialize_irq(void)
584 for (i = 0; i < 4; ++i) 602 for (i = 0; i < 4; ++i)
585 dsi_write_reg(DSI_VC_IRQENABLE(i), l); 603 dsi_write_reg(DSI_VC_IRQENABLE(i), l);
586 604
587 /* XXX zonda responds incorrectly, causing control error: 605 l = DSI_CIO_IRQ_ERROR_MASK;
588 Exit from LP-ESC mode to LP11 uses wrong transition states on the 606 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, l);
589 data lines LP0 and LN0. */
590 dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE,
591 -1 & (~DSI_CIO_IRQ_ERRCONTROL2));
592} 607}
593 608
594static u32 dsi_get_errors(void) 609static u32 dsi_get_errors(void)
@@ -1098,6 +1113,7 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1098 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { 1113 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
1099 DSSERR("PLL not coming out of reset.\n"); 1114 DSSERR("PLL not coming out of reset.\n");
1100 r = -ENODEV; 1115 r = -ENODEV;
1116 dispc_pck_free_enable(0);
1101 goto err1; 1117 goto err1;
1102 } 1118 }
1103 1119
@@ -1740,42 +1756,52 @@ static void dsi_vc_initial_config(int channel)
1740 dsi.vc[channel].mode = DSI_VC_MODE_L4; 1756 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1741} 1757}
1742 1758
1743static void dsi_vc_config_l4(int channel) 1759static int dsi_vc_config_l4(int channel)
1744{ 1760{
1745 if (dsi.vc[channel].mode == DSI_VC_MODE_L4) 1761 if (dsi.vc[channel].mode == DSI_VC_MODE_L4)
1746 return; 1762 return 0;
1747 1763
1748 DSSDBGF("%d", channel); 1764 DSSDBGF("%d", channel);
1749 1765
1750 dsi_vc_enable(channel, 0); 1766 dsi_vc_enable(channel, 0);
1751 1767
1752 if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */ 1768 /* VC_BUSY */
1769 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
1753 DSSERR("vc(%d) busy when trying to config for L4\n", channel); 1770 DSSERR("vc(%d) busy when trying to config for L4\n", channel);
1771 return -EIO;
1772 }
1754 1773
1755 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ 1774 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
1756 1775
1757 dsi_vc_enable(channel, 1); 1776 dsi_vc_enable(channel, 1);
1758 1777
1759 dsi.vc[channel].mode = DSI_VC_MODE_L4; 1778 dsi.vc[channel].mode = DSI_VC_MODE_L4;
1779
1780 return 0;
1760} 1781}
1761 1782
1762static void dsi_vc_config_vp(int channel) 1783static int dsi_vc_config_vp(int channel)
1763{ 1784{
1764 if (dsi.vc[channel].mode == DSI_VC_MODE_VP) 1785 if (dsi.vc[channel].mode == DSI_VC_MODE_VP)
1765 return; 1786 return 0;
1766 1787
1767 DSSDBGF("%d", channel); 1788 DSSDBGF("%d", channel);
1768 1789
1769 dsi_vc_enable(channel, 0); 1790 dsi_vc_enable(channel, 0);
1770 1791
1771 if (REG_GET(DSI_VC_CTRL(channel), 15, 15)) /* VC_BUSY */ 1792 /* VC_BUSY */
1793 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
1772 DSSERR("vc(%d) busy when trying to config for VP\n", channel); 1794 DSSERR("vc(%d) busy when trying to config for VP\n", channel);
1795 return -EIO;
1796 }
1773 1797
1774 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ 1798 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */
1775 1799
1776 dsi_vc_enable(channel, 1); 1800 dsi_vc_enable(channel, 1);
1777 1801
1778 dsi.vc[channel].mode = DSI_VC_MODE_VP; 1802 dsi.vc[channel].mode = DSI_VC_MODE_VP;
1803
1804 return 0;
1779} 1805}
1780 1806
1781 1807
@@ -1854,19 +1880,19 @@ static u16 dsi_vc_flush_receive_data(int channel)
1854 u32 val; 1880 u32 val;
1855 u8 dt; 1881 u8 dt;
1856 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 1882 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
1857 DSSDBG("\trawval %#08x\n", val); 1883 DSSERR("\trawval %#08x\n", val);
1858 dt = FLD_GET(val, 5, 0); 1884 dt = FLD_GET(val, 5, 0);
1859 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 1885 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
1860 u16 err = FLD_GET(val, 23, 8); 1886 u16 err = FLD_GET(val, 23, 8);
1861 dsi_show_rx_ack_with_err(err); 1887 dsi_show_rx_ack_with_err(err);
1862 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 1888 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
1863 DSSDBG("\tDCS short response, 1 byte: %#x\n", 1889 DSSERR("\tDCS short response, 1 byte: %#x\n",
1864 FLD_GET(val, 23, 8)); 1890 FLD_GET(val, 23, 8));
1865 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 1891 } else if (dt == DSI_DT_RX_SHORT_READ_2) {
1866 DSSDBG("\tDCS short response, 2 byte: %#x\n", 1892 DSSERR("\tDCS short response, 2 byte: %#x\n",
1867 FLD_GET(val, 23, 8)); 1893 FLD_GET(val, 23, 8));
1868 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 1894 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
1869 DSSDBG("\tDCS long response, len %d\n", 1895 DSSERR("\tDCS long response, len %d\n",
1870 FLD_GET(val, 23, 8)); 1896 FLD_GET(val, 23, 8));
1871 dsi_vc_flush_long_data(channel); 1897 dsi_vc_flush_long_data(channel);
1872 } else { 1898 } else {
@@ -2087,6 +2113,13 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len)
2087 if (r) 2113 if (r)
2088 goto err; 2114 goto err;
2089 2115
2116 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
2117 DSSERR("rx fifo not empty after write, dumping data:\n");
2118 dsi_vc_flush_receive_data(channel);
2119 r = -EIO;
2120 goto err;
2121 }
2122
2090 return 0; 2123 return 0;
2091err: 2124err:
2092 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n", 2125 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
@@ -2233,11 +2266,12 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2233} 2266}
2234EXPORT_SYMBOL(dsi_vc_dcs_read_1); 2267EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2235 2268
2236int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data) 2269int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
2237{ 2270{
2271 u8 buf[2];
2238 int r; 2272 int r;
2239 2273
2240 r = dsi_vc_dcs_read(channel, dcs_cmd, (u8 *)data, 2); 2274 r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2);
2241 2275
2242 if (r < 0) 2276 if (r < 0)
2243 return r; 2277 return r;
@@ -2245,231 +2279,122 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data)
2245 if (r != 2) 2279 if (r != 2)
2246 return -EIO; 2280 return -EIO;
2247 2281
2282 *data1 = buf[0];
2283 *data2 = buf[1];
2284
2248 return 0; 2285 return 0;
2249} 2286}
2250EXPORT_SYMBOL(dsi_vc_dcs_read_2); 2287EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2251 2288
2252int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 2289int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
2253{ 2290{
2254 int r; 2291 return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2255 r = dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2256 len, 0); 2292 len, 0);
2257
2258 if (r)
2259 return r;
2260
2261 r = dsi_vc_send_bta_sync(channel);
2262
2263 return r;
2264} 2293}
2265EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); 2294EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
2266 2295
2267static void dsi_set_lp_rx_timeout(unsigned long ns) 2296static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2268{ 2297{
2269 u32 r;
2270 unsigned x4, x16;
2271 unsigned long fck; 2298 unsigned long fck;
2272 unsigned long ticks; 2299 unsigned long total_ticks;
2300 u32 r;
2273 2301
2274 /* ticks in DSI_FCK */ 2302 BUG_ON(ticks > 0x1fff);
2275 2303
2304 /* ticks in DSI_FCK */
2276 fck = dsi_fclk_rate(); 2305 fck = dsi_fclk_rate();
2277 ticks = (fck / 1000 / 1000) * ns / 1000;
2278 x4 = 0;
2279 x16 = 0;
2280
2281 if (ticks > 0x1fff) {
2282 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2283 x4 = 1;
2284 x16 = 0;
2285 }
2286
2287 if (ticks > 0x1fff) {
2288 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2289 x4 = 0;
2290 x16 = 1;
2291 }
2292
2293 if (ticks > 0x1fff) {
2294 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2295 x4 = 1;
2296 x16 = 1;
2297 }
2298
2299 if (ticks > 0x1fff) {
2300 DSSWARN("LP_TX_TO over limit, setting it to max\n");
2301 ticks = 0x1fff;
2302 x4 = 1;
2303 x16 = 1;
2304 }
2305 2306
2306 r = dsi_read_reg(DSI_TIMING2); 2307 r = dsi_read_reg(DSI_TIMING2);
2307 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ 2308 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
2308 r = FLD_MOD(r, x16, 14, 14); /* LP_RX_TO_X16 */ 2309 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */
2309 r = FLD_MOD(r, x4, 13, 13); /* LP_RX_TO_X4 */ 2310 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */
2310 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ 2311 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
2311 dsi_write_reg(DSI_TIMING2, r); 2312 dsi_write_reg(DSI_TIMING2, r);
2312 2313
2313 DSSDBG("LP_RX_TO %lu ns (%#lx ticks%s%s)\n", 2314 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2314 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2315
2315 (fck / 1000 / 1000), 2316 DSSDBG("LP_RX_TO %lu ticks (%#x%s%s) = %lu ns\n",
2316 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2317 total_ticks,
2318 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2319 (total_ticks * 1000) / (fck / 1000 / 1000));
2317} 2320}
2318 2321
2319static void dsi_set_ta_timeout(unsigned long ns) 2322static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2320{ 2323{
2321 u32 r;
2322 unsigned x8, x16;
2323 unsigned long fck; 2324 unsigned long fck;
2324 unsigned long ticks; 2325 unsigned long total_ticks;
2326 u32 r;
2327
2328 BUG_ON(ticks > 0x1fff);
2325 2329
2326 /* ticks in DSI_FCK */ 2330 /* ticks in DSI_FCK */
2327 fck = dsi_fclk_rate(); 2331 fck = dsi_fclk_rate();
2328 ticks = (fck / 1000 / 1000) * ns / 1000;
2329 x8 = 0;
2330 x16 = 0;
2331
2332 if (ticks > 0x1fff) {
2333 ticks = (fck / 1000 / 1000) * ns / 1000 / 8;
2334 x8 = 1;
2335 x16 = 0;
2336 }
2337
2338 if (ticks > 0x1fff) {
2339 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2340 x8 = 0;
2341 x16 = 1;
2342 }
2343
2344 if (ticks > 0x1fff) {
2345 ticks = (fck / 1000 / 1000) * ns / 1000 / (8 * 16);
2346 x8 = 1;
2347 x16 = 1;
2348 }
2349
2350 if (ticks > 0x1fff) {
2351 DSSWARN("TA_TO over limit, setting it to max\n");
2352 ticks = 0x1fff;
2353 x8 = 1;
2354 x16 = 1;
2355 }
2356 2332
2357 r = dsi_read_reg(DSI_TIMING1); 2333 r = dsi_read_reg(DSI_TIMING1);
2358 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ 2334 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
2359 r = FLD_MOD(r, x16, 30, 30); /* TA_TO_X16 */ 2335 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
2360 r = FLD_MOD(r, x8, 29, 29); /* TA_TO_X8 */ 2336 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
2361 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ 2337 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
2362 dsi_write_reg(DSI_TIMING1, r); 2338 dsi_write_reg(DSI_TIMING1, r);
2363 2339
2364 DSSDBG("TA_TO %lu ns (%#lx ticks%s%s)\n", 2340 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1);
2365 (ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1) * 1000) / 2341
2366 (fck / 1000 / 1000), 2342 DSSDBG("TA_TO %lu ticks (%#x%s%s) = %lu ns\n",
2367 ticks, x8 ? " x8" : "", x16 ? " x16" : ""); 2343 total_ticks,
2344 ticks, x8 ? " x8" : "", x16 ? " x16" : "",
2345 (total_ticks * 1000) / (fck / 1000 / 1000));
2368} 2346}
2369 2347
2370static void dsi_set_stop_state_counter(unsigned long ns) 2348static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2371{ 2349{
2372 u32 r;
2373 unsigned x4, x16;
2374 unsigned long fck; 2350 unsigned long fck;
2375 unsigned long ticks; 2351 unsigned long total_ticks;
2352 u32 r;
2376 2353
2377 /* ticks in DSI_FCK */ 2354 BUG_ON(ticks > 0x1fff);
2378 2355
2356 /* ticks in DSI_FCK */
2379 fck = dsi_fclk_rate(); 2357 fck = dsi_fclk_rate();
2380 ticks = (fck / 1000 / 1000) * ns / 1000;
2381 x4 = 0;
2382 x16 = 0;
2383
2384 if (ticks > 0x1fff) {
2385 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2386 x4 = 1;
2387 x16 = 0;
2388 }
2389
2390 if (ticks > 0x1fff) {
2391 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2392 x4 = 0;
2393 x16 = 1;
2394 }
2395
2396 if (ticks > 0x1fff) {
2397 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2398 x4 = 1;
2399 x16 = 1;
2400 }
2401
2402 if (ticks > 0x1fff) {
2403 DSSWARN("STOP_STATE_COUNTER_IO over limit, "
2404 "setting it to max\n");
2405 ticks = 0x1fff;
2406 x4 = 1;
2407 x16 = 1;
2408 }
2409 2358
2410 r = dsi_read_reg(DSI_TIMING1); 2359 r = dsi_read_reg(DSI_TIMING1);
2411 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 2360 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2412 r = FLD_MOD(r, x16, 14, 14); /* STOP_STATE_X16_IO */ 2361 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */
2413 r = FLD_MOD(r, x4, 13, 13); /* STOP_STATE_X4_IO */ 2362 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */
2414 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ 2363 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
2415 dsi_write_reg(DSI_TIMING1, r); 2364 dsi_write_reg(DSI_TIMING1, r);
2416 2365
2417 DSSDBG("STOP_STATE_COUNTER %lu ns (%#lx ticks%s%s)\n", 2366 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2418 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2367
2419 (fck / 1000 / 1000), 2368 DSSDBG("STOP_STATE_COUNTER %lu ticks (%#x%s%s) = %lu ns\n",
2420 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2369 total_ticks,
2370 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2371 (total_ticks * 1000) / (fck / 1000 / 1000));
2421} 2372}
2422 2373
2423static void dsi_set_hs_tx_timeout(unsigned long ns) 2374static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2424{ 2375{
2425 u32 r;
2426 unsigned x4, x16;
2427 unsigned long fck; 2376 unsigned long fck;
2428 unsigned long ticks; 2377 unsigned long total_ticks;
2378 u32 r;
2429 2379
2430 /* ticks in TxByteClkHS */ 2380 BUG_ON(ticks > 0x1fff);
2431 2381
2382 /* ticks in TxByteClkHS */
2432 fck = dsi_get_txbyteclkhs(); 2383 fck = dsi_get_txbyteclkhs();
2433 ticks = (fck / 1000 / 1000) * ns / 1000;
2434 x4 = 0;
2435 x16 = 0;
2436
2437 if (ticks > 0x1fff) {
2438 ticks = (fck / 1000 / 1000) * ns / 1000 / 4;
2439 x4 = 1;
2440 x16 = 0;
2441 }
2442
2443 if (ticks > 0x1fff) {
2444 ticks = (fck / 1000 / 1000) * ns / 1000 / 16;
2445 x4 = 0;
2446 x16 = 1;
2447 }
2448
2449 if (ticks > 0x1fff) {
2450 ticks = (fck / 1000 / 1000) * ns / 1000 / (4 * 16);
2451 x4 = 1;
2452 x16 = 1;
2453 }
2454
2455 if (ticks > 0x1fff) {
2456 DSSWARN("HS_TX_TO over limit, setting it to max\n");
2457 ticks = 0x1fff;
2458 x4 = 1;
2459 x16 = 1;
2460 }
2461 2384
2462 r = dsi_read_reg(DSI_TIMING2); 2385 r = dsi_read_reg(DSI_TIMING2);
2463 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ 2386 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
2464 r = FLD_MOD(r, x16, 30, 30); /* HS_TX_TO_X16 */ 2387 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */
2465 r = FLD_MOD(r, x4, 29, 29); /* HS_TX_TO_X8 (4 really) */ 2388 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */
2466 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ 2389 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
2467 dsi_write_reg(DSI_TIMING2, r); 2390 dsi_write_reg(DSI_TIMING2, r);
2468 2391
2469 DSSDBG("HS_TX_TO %lu ns (%#lx ticks%s%s)\n", 2392 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2470 (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / 2393
2471 (fck / 1000 / 1000), 2394 DSSDBG("HS_TX_TO %lu ticks (%#x%s%s) = %lu ns\n",
2472 ticks, x4 ? " x4" : "", x16 ? " x16" : ""); 2395 total_ticks,
2396 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
2397 (total_ticks * 1000) / (fck / 1000 / 1000));
2473} 2398}
2474static int dsi_proto_config(struct omap_dss_device *dssdev) 2399static int dsi_proto_config(struct omap_dss_device *dssdev)
2475{ 2400{
@@ -2487,10 +2412,10 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2487 DSI_FIFO_SIZE_32); 2412 DSI_FIFO_SIZE_32);
2488 2413
2489 /* XXX what values for the timeouts? */ 2414 /* XXX what values for the timeouts? */
2490 dsi_set_stop_state_counter(1000); 2415 dsi_set_stop_state_counter(0x1000, false, false);
2491 dsi_set_ta_timeout(6400000); 2416 dsi_set_ta_timeout(0x1fff, true, true);
2492 dsi_set_lp_rx_timeout(48000); 2417 dsi_set_lp_rx_timeout(0x1fff, true, true);
2493 dsi_set_hs_tx_timeout(1000000); 2418 dsi_set_hs_tx_timeout(0x1fff, true, true);
2494 2419
2495 switch (dssdev->ctrl.pixel_size) { 2420 switch (dssdev->ctrl.pixel_size) {
2496 case 16: 2421 case 16:
@@ -2759,6 +2684,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2759 unsigned packet_payload; 2684 unsigned packet_payload;
2760 unsigned packet_len; 2685 unsigned packet_len;
2761 u32 l; 2686 u32 l;
2687 int r;
2762 const unsigned channel = dsi.update_channel; 2688 const unsigned channel = dsi.update_channel;
2763 /* line buffer is 1024 x 24bits */ 2689 /* line buffer is 1024 x 24bits */
2764 /* XXX: for some reason using full buffer size causes considerable TX 2690 /* XXX: for some reason using full buffer size causes considerable TX
@@ -2809,8 +2735,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
2809 2735
2810 dsi_perf_mark_start(); 2736 dsi_perf_mark_start();
2811 2737
2812 schedule_delayed_work(&dsi.framedone_timeout_work, 2738 r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work,
2813 msecs_to_jiffies(250)); 2739 msecs_to_jiffies(250));
2740 BUG_ON(r == 0);
2814 2741
2815 dss_start_update(dssdev); 2742 dss_start_update(dssdev);
2816 2743
@@ -2834,62 +2761,70 @@ static void dsi_te_timeout(unsigned long arg)
2834} 2761}
2835#endif 2762#endif
2836 2763
2837static void dsi_framedone_timeout_work_callback(struct work_struct *work) 2764static void dsi_handle_framedone(int error)
2838{ 2765{
2839 int r;
2840 const int channel = dsi.update_channel; 2766 const int channel = dsi.update_channel;
2841 2767
2842 DSSERR("Framedone not received for 250ms!\n"); 2768 cancel_delayed_work(&dsi.framedone_timeout_work);
2769
2770 dsi_vc_disable_bta_irq(channel);
2843 2771
2844 /* SIDLEMODE back to smart-idle */ 2772 /* SIDLEMODE back to smart-idle */
2845 dispc_enable_sidle(); 2773 dispc_enable_sidle();
2846 2774
2775 dsi.bta_callback = NULL;
2776
2847 if (dsi.te_enabled) { 2777 if (dsi.te_enabled) {
2848 /* enable LP_RX_TO again after the TE */ 2778 /* enable LP_RX_TO again after the TE */
2849 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 2779 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
2850 } 2780 }
2851 2781
2852 /* Send BTA after the frame. We need this for the TE to work, as TE
2853 * trigger is only sent for BTAs without preceding packet. Thus we need
2854 * to BTA after the pixel packets so that next BTA will cause TE
2855 * trigger.
2856 *
2857 * This is not needed when TE is not in use, but we do it anyway to
2858 * make sure that the transfer has been completed. It would be more
2859 * optimal, but more complex, to wait only just before starting next
2860 * transfer. */
2861 r = dsi_vc_send_bta_sync(channel);
2862 if (r)
2863 DSSERR("BTA after framedone failed\n");
2864
2865 /* RX_FIFO_NOT_EMPTY */ 2782 /* RX_FIFO_NOT_EMPTY */
2866 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2783 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
2867 DSSERR("Received error during frame transfer:\n"); 2784 DSSERR("Received error during frame transfer:\n");
2868 dsi_vc_flush_receive_data(channel); 2785 dsi_vc_flush_receive_data(channel);
2786 if (!error)
2787 error = -EIO;
2869 } 2788 }
2870 2789
2871 dsi.framedone_callback(-ETIMEDOUT, dsi.framedone_data); 2790 dsi.framedone_callback(error, dsi.framedone_data);
2791
2792 if (!error)
2793 dsi_perf_show("DISPC");
2872} 2794}
2873 2795
2874static void dsi_framedone_irq_callback(void *data, u32 mask) 2796static void dsi_framedone_timeout_work_callback(struct work_struct *work)
2875{ 2797{
2876 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 2798 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
2877 * turns itself off. However, DSI still has the pixels in its buffers, 2799 * 250ms which would conflict with this timeout work. What should be
2878 * and is sending the data. 2800 * done is first cancel the transfer on the HW, and then cancel the
2879 */ 2801 * possibly scheduled framedone work. However, cancelling the transfer
2802 * on the HW is buggy, and would probably require resetting the whole
2803 * DSI */
2880 2804
2881 /* SIDLEMODE back to smart-idle */ 2805 DSSERR("Framedone not received for 250ms!\n");
2882 dispc_enable_sidle();
2883 2806
2884 schedule_work(&dsi.framedone_work); 2807 dsi_handle_framedone(-ETIMEDOUT);
2885} 2808}
2886 2809
2887static void dsi_handle_framedone(void) 2810static void dsi_framedone_bta_callback(void)
2811{
2812 dsi_handle_framedone(0);
2813
2814#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2815 dispc_fake_vsync_irq();
2816#endif
2817}
2818
2819static void dsi_framedone_irq_callback(void *data, u32 mask)
2888{ 2820{
2889 int r;
2890 const int channel = dsi.update_channel; 2821 const int channel = dsi.update_channel;
2822 int r;
2891 2823
2892 DSSDBG("FRAMEDONE\n"); 2824 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
2825 * turns itself off. However, DSI still has the pixels in its buffers,
2826 * and is sending the data.
2827 */
2893 2828
2894 if (dsi.te_enabled) { 2829 if (dsi.te_enabled) {
2895 /* enable LP_RX_TO again after the TE */ 2830 /* enable LP_RX_TO again after the TE */
@@ -2904,37 +2839,30 @@ static void dsi_handle_framedone(void)
2904 * This is not needed when TE is not in use, but we do it anyway to 2839 * This is not needed when TE is not in use, but we do it anyway to
2905 * make sure that the transfer has been completed. It would be more 2840 * make sure that the transfer has been completed. It would be more
2906 * optimal, but more complex, to wait only just before starting next 2841 * optimal, but more complex, to wait only just before starting next
2907 * transfer. */ 2842 * transfer.
2908 r = dsi_vc_send_bta_sync(channel); 2843 *
2909 if (r) 2844 * Also, as there's no interrupt telling when the transfer has been
2910 DSSERR("BTA after framedone failed\n"); 2845 * done and the channel could be reconfigured, the only way is to
2911 2846 * busyloop until TE_SIZE is zero. With BTA we can do this
2912 /* RX_FIFO_NOT_EMPTY */ 2847 * asynchronously.
2913 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2848 * */
2914 DSSERR("Received error during frame transfer:\n");
2915 dsi_vc_flush_receive_data(channel);
2916 }
2917
2918#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
2919 dispc_fake_vsync_irq();
2920#endif
2921}
2922
2923static void dsi_framedone_work_callback(struct work_struct *work)
2924{
2925 DSSDBGF();
2926 2849
2927 cancel_delayed_work_sync(&dsi.framedone_timeout_work); 2850 dsi.bta_callback = dsi_framedone_bta_callback;
2928 2851
2929 dsi_handle_framedone(); 2852 barrier();
2930 2853
2931 dsi_perf_show("DISPC"); 2854 dsi_vc_enable_bta_irq(channel);
2932 2855
2933 dsi.framedone_callback(0, dsi.framedone_data); 2856 r = dsi_vc_send_bta(channel);
2857 if (r) {
2858 DSSERR("BTA after framedone failed\n");
2859 dsi_handle_framedone(-EIO);
2860 }
2934} 2861}
2935 2862
2936int omap_dsi_prepare_update(struct omap_dss_device *dssdev, 2863int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2937 u16 *x, u16 *y, u16 *w, u16 *h) 2864 u16 *x, u16 *y, u16 *w, u16 *h,
2865 bool enlarge_update_area)
2938{ 2866{
2939 u16 dw, dh; 2867 u16 dw, dh;
2940 2868
@@ -2958,7 +2886,8 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2958 dsi_perf_mark_setup(); 2886 dsi_perf_mark_setup();
2959 2887
2960 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2961 dss_setup_partial_planes(dssdev, x, y, w, h); 2889 dss_setup_partial_planes(dssdev, x, y, w, h,
2890 enlarge_update_area);
2962 dispc_set_lcd_size(*w, *h); 2891 dispc_set_lcd_size(*w, *h);
2963 } 2892 }
2964 2893
@@ -2973,6 +2902,12 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2973{ 2902{
2974 dsi.update_channel = channel; 2903 dsi.update_channel = channel;
2975 2904
2905 /* OMAP DSS cannot send updates of odd widths.
2906 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
2907 * here to make sure we catch erroneous updates. Otherwise we'll only
2908 * see rather obscure HW error happening, as DSS halts. */
2909 BUG_ON(x % 2 == 1);
2910
2976 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2911 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2977 dsi.framedone_callback = callback; 2912 dsi.framedone_callback = callback;
2978 dsi.framedone_data = data; 2913 dsi.framedone_data = data;
@@ -2985,7 +2920,12 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
2985 2920
2986 dsi_update_screen_dispc(dssdev, x, y, w, h); 2921 dsi_update_screen_dispc(dssdev, x, y, w, h);
2987 } else { 2922 } else {
2988 dsi_update_screen_l4(dssdev, x, y, w, h); 2923 int r;
2924
2925 r = dsi_update_screen_l4(dssdev, x, y, w, h);
2926 if (r)
2927 return r;
2928
2989 dsi_perf_show("L4"); 2929 dsi_perf_show("L4");
2990 callback(0, data); 2930 callback(0, data);
2991 } 2931 }
@@ -3048,8 +2988,10 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
3048 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 2988 cinfo.regm3 = dssdev->phy.dsi.div.regm3;
3049 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 2989 cinfo.regm4 = dssdev->phy.dsi.div.regm4;
3050 r = dsi_calc_clock_rates(&cinfo); 2990 r = dsi_calc_clock_rates(&cinfo);
3051 if (r) 2991 if (r) {
2992 DSSERR("Failed to calc dsi clocks\n");
3052 return r; 2993 return r;
2994 }
3053 2995
3054 r = dsi_pll_set_clock_div(&cinfo); 2996 r = dsi_pll_set_clock_div(&cinfo);
3055 if (r) { 2997 if (r) {
@@ -3147,6 +3089,13 @@ err0:
3147 3089
3148static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3090static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3149{ 3091{
3092 /* disable interface */
3093 dsi_if_enable(0);
3094 dsi_vc_enable(0, 0);
3095 dsi_vc_enable(1, 0);
3096 dsi_vc_enable(2, 0);
3097 dsi_vc_enable(3, 0);
3098
3150 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3099 dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3151 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); 3100 dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
3152 dsi_complexio_uninit(); 3101 dsi_complexio_uninit();
@@ -3257,7 +3206,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3257 burst_size_bytes = 16 * 32 / 8; 3206 burst_size_bytes = 16 * 32 / 8;
3258 3207
3259 *fifo_high = fifo_size - burst_size_bytes; 3208 *fifo_high = fifo_size - burst_size_bytes;
3260 *fifo_low = fifo_size - burst_size_bytes * 8; 3209 *fifo_low = fifo_size - burst_size_bytes * 2;
3261} 3210}
3262 3211
3263int dsi_init_display(struct omap_dss_device *dssdev) 3212int dsi_init_display(struct omap_dss_device *dssdev)
@@ -3274,6 +3223,18 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3274 return 0; 3223 return 0;
3275} 3224}
3276 3225
3226void dsi_wait_dsi1_pll_active(void)
3227{
3228 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
3229 DSSERR("DSI1 PLL clock not active\n");
3230}
3231
3232void dsi_wait_dsi2_pll_active(void)
3233{
3234 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
3235 DSSERR("DSI2 PLL clock not active\n");
3236}
3237
3277int dsi_init(struct platform_device *pdev) 3238int dsi_init(struct platform_device *pdev)
3278{ 3239{
3279 u32 rev; 3240 u32 rev;
@@ -3292,7 +3253,10 @@ int dsi_init(struct platform_device *pdev)
3292 mutex_init(&dsi.lock); 3253 mutex_init(&dsi.lock);
3293 sema_init(&dsi.bus_lock, 1); 3254 sema_init(&dsi.bus_lock, 1);
3294 3255
3295 INIT_WORK(&dsi.framedone_work, dsi_framedone_work_callback); 3256 dsi.workqueue = create_singlethread_workqueue("dsi");
3257 if (dsi.workqueue == NULL)
3258 return -ENOMEM;
3259
3296 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, 3260 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3297 dsi_framedone_timeout_work_callback); 3261 dsi_framedone_timeout_work_callback);
3298 3262
@@ -3328,6 +3292,7 @@ int dsi_init(struct platform_device *pdev)
3328err2: 3292err2:
3329 iounmap(dsi.base); 3293 iounmap(dsi.base);
3330err1: 3294err1:
3295 destroy_workqueue(dsi.workqueue);
3331 return r; 3296 return r;
3332} 3297}
3333 3298
@@ -3335,6 +3300,8 @@ void dsi_exit(void)
3335{ 3300{
3336 iounmap(dsi.base); 3301 iounmap(dsi.base);
3337 3302
3303 destroy_workqueue(dsi.workqueue);
3304
3338 DSSDBG("omap_dsi_exit\n"); 3305 DSSDBG("omap_dsi_exit\n");
3339} 3306}
3340 3307
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 24b18258654f..77c3621c9171 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -265,6 +265,9 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
265 265
266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 266 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
267 267
268 if (clk_src == DSS_SRC_DSI1_PLL_FCLK)
269 dsi_wait_dsi1_pll_active();
270
268 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ 271 REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */
269 272
270 dss.dispc_clk_source = clk_src; 273 dss.dispc_clk_source = clk_src;
@@ -279,6 +282,9 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
279 282
280 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; 283 b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1;
281 284
285 if (clk_src == DSS_SRC_DSI2_PLL_FCLK)
286 dsi_wait_dsi2_pll_active();
287
282 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 288 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
283 289
284 dss.dsi_clk_source = clk_src; 290 dss.dsi_clk_source = clk_src;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 786f433fd571..5c7940d5f282 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -199,7 +199,8 @@ int dss_init_overlay_managers(struct platform_device *pdev);
199void dss_uninit_overlay_managers(struct platform_device *pdev); 199void dss_uninit_overlay_managers(struct platform_device *pdev);
200int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); 200int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
201void dss_setup_partial_planes(struct omap_dss_device *dssdev, 201void dss_setup_partial_planes(struct omap_dss_device *dssdev,
202 u16 *x, u16 *y, u16 *w, u16 *h); 202 u16 *x, u16 *y, u16 *w, u16 *h,
203 bool enlarge_update_area);
203void dss_start_update(struct omap_dss_device *dssdev); 204void dss_start_update(struct omap_dss_device *dssdev);
204 205
205/* overlay */ 206/* overlay */
@@ -281,6 +282,8 @@ void dsi_pll_uninit(void);
281void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 282void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
282 u32 fifo_size, enum omap_burst_size *burst_size, 283 u32 fifo_size, enum omap_burst_size *burst_size,
283 u32 *fifo_low, u32 *fifo_high); 284 u32 *fifo_low, u32 *fifo_high);
285void dsi_wait_dsi1_pll_active(void);
286void dsi_wait_dsi2_pll_active(void);
284#else 287#else
285static inline int dsi_init(struct platform_device *pdev) 288static inline int dsi_init(struct platform_device *pdev)
286{ 289{
@@ -289,6 +292,12 @@ static inline int dsi_init(struct platform_device *pdev)
289static inline void dsi_exit(void) 292static inline void dsi_exit(void)
290{ 293{
291} 294}
295static inline void dsi_wait_dsi1_pll_active(void)
296{
297}
298static inline void dsi_wait_dsi2_pll_active(void)
299{
300}
292#endif 301#endif
293 302
294/* DPI */ 303/* DPI */
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 9e1fbe531bf0..6a649ab5539e 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -440,6 +440,10 @@ struct manager_cache_data {
440 440
441 /* manual update region */ 441 /* manual update region */
442 u16 x, y, w, h; 442 u16 x, y, w, h;
443
444 /* enlarge the update area if the update area contains scaled
445 * overlays */
446 bool enlarge_update_area;
443}; 447};
444 448
445static struct { 449static struct {
@@ -525,7 +529,7 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
525 int i; 529 int i;
526 struct omap_dss_device *dssdev = mgr->device; 530 struct omap_dss_device *dssdev = mgr->device;
527 531
528 if (!dssdev) 532 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
529 return 0; 533 return 0;
530 534
531 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 535 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
@@ -596,11 +600,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
596 int r; 600 int r;
597 int i; 601 int i;
598 602
599 if (!ovl->manager || !ovl->manager->device) 603 if (!ovl->manager)
600 return 0; 604 return 0;
601 605
602 dssdev = ovl->manager->device; 606 dssdev = ovl->manager->device;
603 607
608 if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
609 return 0;
610
604 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 611 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
605 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 612 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
606 channel = OMAP_DSS_CHANNEL_DIGIT; 613 channel = OMAP_DSS_CHANNEL_DIGIT;
@@ -718,6 +725,7 @@ static int configure_overlay(enum omap_plane plane)
718 u16 x, y, w, h; 725 u16 x, y, w, h;
719 u32 paddr; 726 u32 paddr;
720 int r; 727 int r;
728 u16 orig_w, orig_h, orig_outw, orig_outh;
721 729
722 DSSDBGF("%d", plane); 730 DSSDBGF("%d", plane);
723 731
@@ -738,8 +746,16 @@ static int configure_overlay(enum omap_plane plane)
738 outh = c->out_height == 0 ? c->height : c->out_height; 746 outh = c->out_height == 0 ? c->height : c->out_height;
739 paddr = c->paddr; 747 paddr = c->paddr;
740 748
749 orig_w = w;
750 orig_h = h;
751 orig_outw = outw;
752 orig_outh = outh;
753
741 if (c->manual_update && mc->do_manual_update) { 754 if (c->manual_update && mc->do_manual_update) {
742 unsigned bpp; 755 unsigned bpp;
756 unsigned scale_x_m = w, scale_x_d = outw;
757 unsigned scale_y_m = h, scale_y_d = outh;
758
743 /* If the overlay is outside the update region, disable it */ 759 /* If the overlay is outside the update region, disable it */
744 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h, 760 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
745 x, y, outw, outh)) { 761 x, y, outw, outh)) {
@@ -770,38 +786,47 @@ static int configure_overlay(enum omap_plane plane)
770 BUG(); 786 BUG();
771 } 787 }
772 788
773 if (dispc_is_overlay_scaled(c)) { 789 if (mc->x > c->pos_x) {
774 /* If the overlay is scaled, the update area has 790 x = 0;
775 * already been enlarged to cover the whole overlay. We 791 outw -= (mc->x - c->pos_x);
776 * only need to adjust x/y here */ 792 paddr += (mc->x - c->pos_x) *
777 x = c->pos_x - mc->x; 793 scale_x_m / scale_x_d * bpp / 8;
778 y = c->pos_y - mc->y;
779 } else { 794 } else {
780 if (mc->x > c->pos_x) { 795 x = c->pos_x - mc->x;
781 x = 0; 796 }
782 w -= (mc->x - c->pos_x);
783 paddr += (mc->x - c->pos_x) * bpp / 8;
784 } else {
785 x = c->pos_x - mc->x;
786 }
787
788 if (mc->y > c->pos_y) {
789 y = 0;
790 h -= (mc->y - c->pos_y);
791 paddr += (mc->y - c->pos_y) * c->screen_width *
792 bpp / 8;
793 } else {
794 y = c->pos_y - mc->y;
795 }
796
797 if (mc->w < (x+w))
798 w -= (x+w) - (mc->w);
799 797
800 if (mc->h < (y+h)) 798 if (mc->y > c->pos_y) {
801 h -= (y+h) - (mc->h); 799 y = 0;
800 outh -= (mc->y - c->pos_y);
801 paddr += (mc->y - c->pos_y) *
802 scale_y_m / scale_y_d *
803 c->screen_width * bpp / 8;
804 } else {
805 y = c->pos_y - mc->y;
806 }
802 807
803 outw = w; 808 if (mc->w < (x + outw))
804 outh = h; 809 outw -= (x + outw) - (mc->w);
810
811 if (mc->h < (y + outh))
812 outh -= (y + outh) - (mc->h);
813
814 w = w * outw / orig_outw;
815 h = h * outh / orig_outh;
816
817 /* YUV mode overlay's input width has to be even and the
818 * algorithm above may adjust the width to be odd.
819 *
820 * Here we adjust the width if needed, preferring to increase
821 * the width if the original width was bigger.
822 */
823 if ((w & 1) &&
824 (c->color_mode == OMAP_DSS_COLOR_YUV2 ||
825 c->color_mode == OMAP_DSS_COLOR_UYVY)) {
826 if (orig_w > w)
827 w += 1;
828 else
829 w -= 1;
805 } 830 }
806 } 831 }
807 832
@@ -960,7 +985,7 @@ static void make_even(u16 *x, u16 *w)
960/* Configure dispc for partial update. Return possibly modified update 985/* Configure dispc for partial update. Return possibly modified update
961 * area */ 986 * area */
962void dss_setup_partial_planes(struct omap_dss_device *dssdev, 987void dss_setup_partial_planes(struct omap_dss_device *dssdev,
963 u16 *xi, u16 *yi, u16 *wi, u16 *hi) 988 u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
964{ 989{
965 struct overlay_cache_data *oc; 990 struct overlay_cache_data *oc;
966 struct manager_cache_data *mc; 991 struct manager_cache_data *mc;
@@ -969,6 +994,7 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
969 int i; 994 int i;
970 u16 x, y, w, h; 995 u16 x, y, w, h;
971 unsigned long flags; 996 unsigned long flags;
997 bool area_changed;
972 998
973 x = *xi; 999 x = *xi;
974 y = *yi; 1000 y = *yi;
@@ -989,73 +1015,91 @@ void dss_setup_partial_planes(struct omap_dss_device *dssdev,
989 1015
990 spin_lock_irqsave(&dss_cache.lock, flags); 1016 spin_lock_irqsave(&dss_cache.lock, flags);
991 1017
992 /* We need to show the whole overlay if it is scaled. So look for 1018 /*
993 * those, and make the update area larger if found. 1019 * Execute the outer loop until the inner loop has completed
994 * Also mark the overlay cache dirty */ 1020 * once without increasing the update area. This will ensure that
995 for (i = 0; i < num_ovls; ++i) { 1021 * all scaled overlays end up completely within the update area.
996 unsigned x1, y1, x2, y2; 1022 */
997 unsigned outw, outh; 1023 do {
1024 area_changed = false;
998 1025
999 oc = &dss_cache.overlay_cache[i]; 1026 /* We need to show the whole overlay if it is scaled. So look
1027 * for those, and make the update area larger if found.
1028 * Also mark the overlay cache dirty */
1029 for (i = 0; i < num_ovls; ++i) {
1030 unsigned x1, y1, x2, y2;
1031 unsigned outw, outh;
1000 1032
1001 if (oc->channel != mgr->id) 1033 oc = &dss_cache.overlay_cache[i];
1002 continue;
1003 1034
1004 oc->dirty = true; 1035 if (oc->channel != mgr->id)
1036 continue;
1005 1037
1006 if (!oc->enabled) 1038 oc->dirty = true;
1007 continue;
1008 1039
1009 if (!dispc_is_overlay_scaled(oc)) 1040 if (!enlarge_update_area)
1010 continue; 1041 continue;
1011 1042
1012 outw = oc->out_width == 0 ? oc->width : oc->out_width; 1043 if (!oc->enabled)
1013 outh = oc->out_height == 0 ? oc->height : oc->out_height; 1044 continue;
1014 1045
1015 /* is the overlay outside the update region? */ 1046 if (!dispc_is_overlay_scaled(oc))
1016 if (!rectangle_intersects(x, y, w, h, 1047 continue;
1017 oc->pos_x, oc->pos_y,
1018 outw, outh))
1019 continue;
1020 1048
1021 /* if the overlay totally inside the update region? */ 1049 outw = oc->out_width == 0 ?
1022 if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh, 1050 oc->width : oc->out_width;
1023 x, y, w, h)) 1051 outh = oc->out_height == 0 ?
1024 continue; 1052 oc->height : oc->out_height;
1053
1054 /* is the overlay outside the update region? */
1055 if (!rectangle_intersects(x, y, w, h,
1056 oc->pos_x, oc->pos_y,
1057 outw, outh))
1058 continue;
1025 1059
1026 if (x > oc->pos_x) 1060 /* if the overlay totally inside the update region? */
1027 x1 = oc->pos_x; 1061 if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh,
1028 else 1062 x, y, w, h))
1029 x1 = x; 1063 continue;
1030 1064
1031 if (y > oc->pos_y) 1065 if (x > oc->pos_x)
1032 y1 = oc->pos_y; 1066 x1 = oc->pos_x;
1033 else 1067 else
1034 y1 = y; 1068 x1 = x;
1035 1069
1036 if ((x + w) < (oc->pos_x + outw)) 1070 if (y > oc->pos_y)
1037 x2 = oc->pos_x + outw; 1071 y1 = oc->pos_y;
1038 else 1072 else
1039 x2 = x + w; 1073 y1 = y;
1040 1074
1041 if ((y + h) < (oc->pos_y + outh)) 1075 if ((x + w) < (oc->pos_x + outw))
1042 y2 = oc->pos_y + outh; 1076 x2 = oc->pos_x + outw;
1043 else 1077 else
1044 y2 = y + h; 1078 x2 = x + w;
1045 1079
1046 x = x1; 1080 if ((y + h) < (oc->pos_y + outh))
1047 y = y1; 1081 y2 = oc->pos_y + outh;
1048 w = x2 - x1; 1082 else
1049 h = y2 - y1; 1083 y2 = y + h;
1050 1084
1051 make_even(&x, &w); 1085 x = x1;
1086 y = y1;
1087 w = x2 - x1;
1088 h = y2 - y1;
1052 1089
1053 DSSDBG("changing upd area due to ovl(%d) scaling %d,%d %dx%d\n", 1090 make_even(&x, &w);
1091
1092 DSSDBG("changing upd area due to ovl(%d) "
1093 "scaling %d,%d %dx%d\n",
1054 i, x, y, w, h); 1094 i, x, y, w, h);
1055 } 1095
1096 area_changed = true;
1097 }
1098 } while (area_changed);
1056 1099
1057 mc = &dss_cache.manager_cache[mgr->id]; 1100 mc = &dss_cache.manager_cache[mgr->id];
1058 mc->do_manual_update = true; 1101 mc->do_manual_update = true;
1102 mc->enlarge_update_area = enlarge_update_area;
1059 mc->x = x; 1103 mc->x = x;
1060 mc->y = y; 1104 mc->y = y;
1061 mc->w = w; 1105 mc->w = w;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 82336583adef..244dca81a399 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -65,7 +65,7 @@ static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
65 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 65 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
66 mgr = omap_dss_get_overlay_manager(i); 66 mgr = omap_dss_get_overlay_manager(i);
67 67
68 if (strncmp(buf, mgr->name, len) == 0) 68 if (sysfs_streq(buf, mgr->name))
69 break; 69 break;
70 70
71 mgr = NULL; 71 mgr = NULL;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index cc23f53cc62d..bbe62464e92d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -886,7 +886,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
886 return -EINVAL; 886 return -EINVAL;
887 887
888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
889 dss_setup_partial_planes(dssdev, x, y, w, h); 889 dss_setup_partial_planes(dssdev, x, y, w, h, true);
890 dispc_set_lcd_size(*w, *h); 890 dispc_set_lcd_size(*w, *h);
891 } 891 }
892 892
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 9c7361871d78..6f435450987e 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -34,12 +34,37 @@
34 34
35#include "omapfb.h" 35#include "omapfb.h"
36 36
37static u8 get_mem_idx(struct omapfb_info *ofbi)
38{
39 if (ofbi->id == ofbi->region->id)
40 return 0;
41
42 return OMAPFB_MEM_IDX_ENABLED | ofbi->region->id;
43}
44
45static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi,
46 u8 mem_idx)
47{
48 struct omapfb2_device *fbdev = ofbi->fbdev;
49
50 if (mem_idx & OMAPFB_MEM_IDX_ENABLED)
51 mem_idx &= OMAPFB_MEM_IDX_MASK;
52 else
53 mem_idx = ofbi->id;
54
55 if (mem_idx >= fbdev->num_fbs)
56 return NULL;
57
58 return &fbdev->regions[mem_idx];
59}
60
37static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) 61static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
38{ 62{
39 struct omapfb_info *ofbi = FB2OFB(fbi); 63 struct omapfb_info *ofbi = FB2OFB(fbi);
40 struct omapfb2_device *fbdev = ofbi->fbdev; 64 struct omapfb2_device *fbdev = ofbi->fbdev;
41 struct omap_overlay *ovl; 65 struct omap_overlay *ovl;
42 struct omap_overlay_info info; 66 struct omap_overlay_info old_info;
67 struct omapfb2_mem_region *old_rg, *new_rg;
43 int r = 0; 68 int r = 0;
44 69
45 DBG("omapfb_setup_plane\n"); 70 DBG("omapfb_setup_plane\n");
@@ -52,36 +77,106 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
52 /* XXX uses only the first overlay */ 77 /* XXX uses only the first overlay */
53 ovl = ofbi->overlays[0]; 78 ovl = ofbi->overlays[0];
54 79
55 if (pi->enabled && !ofbi->region.size) { 80 old_rg = ofbi->region;
81 new_rg = get_mem_region(ofbi, pi->mem_idx);
82 if (!new_rg) {
83 r = -EINVAL;
84 goto out;
85 }
86
87 /* Take the locks in a specific order to keep lockdep happy */
88 if (old_rg->id < new_rg->id) {
89 omapfb_get_mem_region(old_rg);
90 omapfb_get_mem_region(new_rg);
91 } else if (new_rg->id < old_rg->id) {
92 omapfb_get_mem_region(new_rg);
93 omapfb_get_mem_region(old_rg);
94 } else
95 omapfb_get_mem_region(old_rg);
96
97 if (pi->enabled && !new_rg->size) {
56 /* 98 /*
57 * This plane's memory was freed, can't enable it 99 * This plane's memory was freed, can't enable it
58 * until it's reallocated. 100 * until it's reallocated.
59 */ 101 */
60 r = -EINVAL; 102 r = -EINVAL;
61 goto out; 103 goto put_mem;
62 } 104 }
63 105
64 ovl->get_overlay_info(ovl, &info); 106 ovl->get_overlay_info(ovl, &old_info);
65 107
66 info.pos_x = pi->pos_x; 108 if (old_rg != new_rg) {
67 info.pos_y = pi->pos_y; 109 ofbi->region = new_rg;
68 info.out_width = pi->out_width; 110 set_fb_fix(fbi);
69 info.out_height = pi->out_height; 111 }
70 info.enabled = pi->enabled;
71 112
72 r = ovl->set_overlay_info(ovl, &info); 113 if (pi->enabled) {
73 if (r) 114 struct omap_overlay_info info;
74 goto out;
75 115
76 if (ovl->manager) { 116 r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
77 r = ovl->manager->apply(ovl->manager); 117 pi->out_width, pi->out_height);
78 if (r) 118 if (r)
79 goto out; 119 goto undo;
120
121 ovl->get_overlay_info(ovl, &info);
122
123 if (!info.enabled) {
124 info.enabled = pi->enabled;
125 r = ovl->set_overlay_info(ovl, &info);
126 if (r)
127 goto undo;
128 }
129 } else {
130 struct omap_overlay_info info;
131
132 ovl->get_overlay_info(ovl, &info);
133
134 info.enabled = pi->enabled;
135 info.pos_x = pi->pos_x;
136 info.pos_y = pi->pos_y;
137 info.out_width = pi->out_width;
138 info.out_height = pi->out_height;
139
140 r = ovl->set_overlay_info(ovl, &info);
141 if (r)
142 goto undo;
80 } 143 }
81 144
82out: 145 if (ovl->manager)
83 if (r) 146 ovl->manager->apply(ovl->manager);
84 dev_err(fbdev->dev, "setup_plane failed\n"); 147
148 /* Release the locks in a specific order to keep lockdep happy */
149 if (old_rg->id > new_rg->id) {
150 omapfb_put_mem_region(old_rg);
151 omapfb_put_mem_region(new_rg);
152 } else if (new_rg->id > old_rg->id) {
153 omapfb_put_mem_region(new_rg);
154 omapfb_put_mem_region(old_rg);
155 } else
156 omapfb_put_mem_region(old_rg);
157
158 return 0;
159
160 undo:
161 if (old_rg != new_rg) {
162 ofbi->region = old_rg;
163 set_fb_fix(fbi);
164 }
165
166 ovl->set_overlay_info(ovl, &old_info);
167 put_mem:
168 /* Release the locks in a specific order to keep lockdep happy */
169 if (old_rg->id > new_rg->id) {
170 omapfb_put_mem_region(old_rg);
171 omapfb_put_mem_region(new_rg);
172 } else if (new_rg->id > old_rg->id) {
173 omapfb_put_mem_region(new_rg);
174 omapfb_put_mem_region(old_rg);
175 } else
176 omapfb_put_mem_region(old_rg);
177 out:
178 dev_err(fbdev->dev, "setup_plane failed\n");
179
85 return r; 180 return r;
86} 181}
87 182
@@ -92,8 +187,8 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
92 if (ofbi->num_overlays != 1) { 187 if (ofbi->num_overlays != 1) {
93 memset(pi, 0, sizeof(*pi)); 188 memset(pi, 0, sizeof(*pi));
94 } else { 189 } else {
95 struct omap_overlay_info *ovli;
96 struct omap_overlay *ovl; 190 struct omap_overlay *ovl;
191 struct omap_overlay_info *ovli;
97 192
98 ovl = ofbi->overlays[0]; 193 ovl = ofbi->overlays[0];
99 ovli = &ovl->info; 194 ovli = &ovl->info;
@@ -103,6 +198,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
103 pi->enabled = ovli->enabled; 198 pi->enabled = ovli->enabled;
104 pi->channel_out = 0; /* xxx */ 199 pi->channel_out = 0; /* xxx */
105 pi->mirror = 0; 200 pi->mirror = 0;
201 pi->mem_idx = get_mem_idx(ofbi);
106 pi->out_width = ovli->out_width; 202 pi->out_width = ovli->out_width;
107 pi->out_height = ovli->out_height; 203 pi->out_height = ovli->out_height;
108 } 204 }
@@ -115,7 +211,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
115 struct omapfb_info *ofbi = FB2OFB(fbi); 211 struct omapfb_info *ofbi = FB2OFB(fbi);
116 struct omapfb2_device *fbdev = ofbi->fbdev; 212 struct omapfb2_device *fbdev = ofbi->fbdev;
117 struct omapfb2_mem_region *rg; 213 struct omapfb2_mem_region *rg;
118 int r, i; 214 int r = 0, i;
119 size_t size; 215 size_t size;
120 216
121 if (mi->type > OMAPFB_MEMTYPE_MAX) 217 if (mi->type > OMAPFB_MEMTYPE_MAX)
@@ -123,22 +219,44 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
123 219
124 size = PAGE_ALIGN(mi->size); 220 size = PAGE_ALIGN(mi->size);
125 221
126 rg = &ofbi->region; 222 rg = ofbi->region;
127 223
128 for (i = 0; i < ofbi->num_overlays; i++) { 224 down_write_nested(&rg->lock, rg->id);
129 if (ofbi->overlays[i]->info.enabled) 225 atomic_inc(&rg->lock_count);
130 return -EBUSY; 226
227 if (atomic_read(&rg->map_count)) {
228 r = -EBUSY;
229 goto out;
230 }
231
232 for (i = 0; i < fbdev->num_fbs; i++) {
233 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
234 int j;
235
236 if (ofbi2->region != rg)
237 continue;
238
239 for (j = 0; j < ofbi2->num_overlays; j++) {
240 if (ofbi2->overlays[j]->info.enabled) {
241 r = -EBUSY;
242 goto out;
243 }
244 }
131 } 245 }
132 246
133 if (rg->size != size || rg->type != mi->type) { 247 if (rg->size != size || rg->type != mi->type) {
134 r = omapfb_realloc_fbmem(fbi, size, mi->type); 248 r = omapfb_realloc_fbmem(fbi, size, mi->type);
135 if (r) { 249 if (r) {
136 dev_err(fbdev->dev, "realloc fbmem failed\n"); 250 dev_err(fbdev->dev, "realloc fbmem failed\n");
137 return r; 251 goto out;
138 } 252 }
139 } 253 }
140 254
141 return 0; 255 out:
256 atomic_dec(&rg->lock_count);
257 up_write(&rg->lock);
258
259 return r;
142} 260}
143 261
144static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) 262static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
@@ -146,12 +264,14 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
146 struct omapfb_info *ofbi = FB2OFB(fbi); 264 struct omapfb_info *ofbi = FB2OFB(fbi);
147 struct omapfb2_mem_region *rg; 265 struct omapfb2_mem_region *rg;
148 266
149 rg = &ofbi->region; 267 rg = omapfb_get_mem_region(ofbi->region);
150 memset(mi, 0, sizeof(*mi)); 268 memset(mi, 0, sizeof(*mi));
151 269
152 mi->size = rg->size; 270 mi->size = rg->size;
153 mi->type = rg->type; 271 mi->type = rg->type;
154 272
273 omapfb_put_mem_region(rg);
274
155 return 0; 275 return 0;
156} 276}
157 277
@@ -490,6 +610,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
490 struct omapfb_vram_info vram_info; 610 struct omapfb_vram_info vram_info;
491 struct omapfb_tearsync_info tearsync_info; 611 struct omapfb_tearsync_info tearsync_info;
492 struct omapfb_display_info display_info; 612 struct omapfb_display_info display_info;
613 u32 crt;
493 } p; 614 } p;
494 615
495 int r = 0; 616 int r = 0;
@@ -648,6 +769,17 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
648 r = -EFAULT; 769 r = -EFAULT;
649 break; 770 break;
650 771
772 case FBIO_WAITFORVSYNC:
773 if (get_user(p.crt, (__u32 __user *)arg)) {
774 r = -EFAULT;
775 break;
776 }
777 if (p.crt != 0) {
778 r = -ENODEV;
779 break;
780 }
781 /* FALLTHROUGH */
782
651 case OMAPFB_WAITFORVSYNC: 783 case OMAPFB_WAITFORVSYNC:
652 DBG("ioctl WAITFORVSYNC\n"); 784 DBG("ioctl WAITFORVSYNC\n");
653 if (!display) { 785 if (!display) {
@@ -738,7 +870,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
738 break; 870 break;
739 } 871 }
740 872
741 if (!display->driver->enable_te) { 873 if (!display || !display->driver->enable_te) {
742 r = -ENODEV; 874 r = -ENODEV;
743 break; 875 break;
744 } 876 }
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4b4506da96da..04034d410d6d 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -157,7 +157,7 @@ static void fill_fb(struct fb_info *fbi)
157 157
158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) 158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
159{ 159{
160 const struct vrfb *vrfb = &ofbi->region.vrfb; 160 const struct vrfb *vrfb = &ofbi->region->vrfb;
161 unsigned offset; 161 unsigned offset;
162 162
163 switch (rot) { 163 switch (rot) {
@@ -185,27 +185,27 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) 185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
186{ 186{
187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
188 return ofbi->region.vrfb.paddr[rot] 188 return ofbi->region->vrfb.paddr[rot]
189 + omapfb_get_vrfb_offset(ofbi, rot); 189 + omapfb_get_vrfb_offset(ofbi, rot);
190 } else { 190 } else {
191 return ofbi->region.paddr; 191 return ofbi->region->paddr;
192 } 192 }
193} 193}
194 194
195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) 195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
196{ 196{
197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
198 return ofbi->region.vrfb.paddr[0]; 198 return ofbi->region->vrfb.paddr[0];
199 else 199 else
200 return ofbi->region.paddr; 200 return ofbi->region->paddr;
201} 201}
202 202
203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) 203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
204{ 204{
205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
206 return ofbi->region.vrfb.vaddr[0]; 206 return ofbi->region->vrfb.vaddr[0];
207 else 207 else
208 return ofbi->region.vaddr; 208 return ofbi->region->vaddr;
209} 209}
210 210
211static struct omapfb_colormode omapfb_colormodes[] = { 211static struct omapfb_colormode omapfb_colormodes[] = {
@@ -450,7 +450,7 @@ static int check_vrfb_fb_size(unsigned long region_size,
450static int check_fb_size(const struct omapfb_info *ofbi, 450static int check_fb_size(const struct omapfb_info *ofbi,
451 struct fb_var_screeninfo *var) 451 struct fb_var_screeninfo *var)
452{ 452{
453 unsigned long max_frame_size = ofbi->region.size; 453 unsigned long max_frame_size = ofbi->region->size;
454 int bytespp = var->bits_per_pixel >> 3; 454 int bytespp = var->bits_per_pixel >> 3;
455 unsigned long line_size = var->xres_virtual * bytespp; 455 unsigned long line_size = var->xres_virtual * bytespp;
456 456
@@ -497,7 +497,7 @@ static int check_fb_size(const struct omapfb_info *ofbi,
497static int setup_vrfb_rotation(struct fb_info *fbi) 497static int setup_vrfb_rotation(struct fb_info *fbi)
498{ 498{
499 struct omapfb_info *ofbi = FB2OFB(fbi); 499 struct omapfb_info *ofbi = FB2OFB(fbi);
500 struct omapfb2_mem_region *rg = &ofbi->region; 500 struct omapfb2_mem_region *rg = ofbi->region;
501 struct vrfb *vrfb = &rg->vrfb; 501 struct vrfb *vrfb = &rg->vrfb;
502 struct fb_var_screeninfo *var = &fbi->var; 502 struct fb_var_screeninfo *var = &fbi->var;
503 struct fb_fix_screeninfo *fix = &fbi->fix; 503 struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -558,9 +558,9 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
558 return r; 558 return r;
559 559
560 /* used by open/write in fbmem.c */ 560 /* used by open/write in fbmem.c */
561 fbi->screen_base = ofbi->region.vrfb.vaddr[0]; 561 fbi->screen_base = ofbi->region->vrfb.vaddr[0];
562 562
563 fix->smem_start = ofbi->region.vrfb.paddr[0]; 563 fix->smem_start = ofbi->region->vrfb.paddr[0];
564 564
565 switch (var->nonstd) { 565 switch (var->nonstd) {
566 case OMAPFB_COLOR_YUV422: 566 case OMAPFB_COLOR_YUV422:
@@ -599,7 +599,7 @@ void set_fb_fix(struct fb_info *fbi)
599 struct fb_fix_screeninfo *fix = &fbi->fix; 599 struct fb_fix_screeninfo *fix = &fbi->fix;
600 struct fb_var_screeninfo *var = &fbi->var; 600 struct fb_var_screeninfo *var = &fbi->var;
601 struct omapfb_info *ofbi = FB2OFB(fbi); 601 struct omapfb_info *ofbi = FB2OFB(fbi);
602 struct omapfb2_mem_region *rg = &ofbi->region; 602 struct omapfb2_mem_region *rg = ofbi->region;
603 603
604 DBG("set_fb_fix\n"); 604 DBG("set_fb_fix\n");
605 605
@@ -668,8 +668,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
668 668
669 DBG("check_fb_var %d\n", ofbi->id); 669 DBG("check_fb_var %d\n", ofbi->id);
670 670
671 if (ofbi->region.size == 0) 671 WARN_ON(!atomic_read(&ofbi->region->lock_count));
672 return 0;
673 672
674 r = fb_mode_to_dss_mode(var, &mode); 673 r = fb_mode_to_dss_mode(var, &mode);
675 if (r) { 674 if (r) {
@@ -684,13 +683,14 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
684 } 683 }
685 } 684 }
686 685
687 if (var->rotate < 0 || var->rotate > 3) 686 if (var->rotate > 3)
688 return -EINVAL; 687 return -EINVAL;
689 688
690 if (check_fb_res_bounds(var)) 689 if (check_fb_res_bounds(var))
691 return -EINVAL; 690 return -EINVAL;
692 691
693 if (check_fb_size(ofbi, var)) 692 /* When no memory is allocated ignore the size check */
693 if (ofbi->region->size != 0 && check_fb_size(ofbi, var))
694 return -EINVAL; 694 return -EINVAL;
695 695
696 if (var->xres + var->xoffset > var->xres_virtual) 696 if (var->xres + var->xoffset > var->xres_virtual)
@@ -822,9 +822,43 @@ static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
822 return offset; 822 return offset;
823} 823}
824 824
825static void omapfb_calc_addr(const struct omapfb_info *ofbi,
826 const struct fb_var_screeninfo *var,
827 const struct fb_fix_screeninfo *fix,
828 int rotation, u32 *paddr, void __iomem **vaddr)
829{
830 u32 data_start_p;
831 void __iomem *data_start_v;
832 int offset;
833
834 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
835 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
836 data_start_v = NULL;
837 } else {
838 data_start_p = omapfb_get_region_paddr(ofbi);
839 data_start_v = omapfb_get_region_vaddr(ofbi);
840 }
841
842 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
843 offset = calc_rotation_offset_vrfb(var, fix, rotation);
844 else
845 offset = calc_rotation_offset_dma(var, fix, rotation);
846
847 data_start_p += offset;
848 data_start_v += offset;
849
850 if (offset)
851 DBG("offset %d, %d = %d\n",
852 var->xoffset, var->yoffset, offset);
853
854 DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
855
856 *paddr = data_start_p;
857 *vaddr = data_start_v;
858}
825 859
826/* setup overlay according to the fb */ 860/* setup overlay according to the fb */
827static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 861int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
828 u16 posx, u16 posy, u16 outw, u16 outh) 862 u16 posx, u16 posy, u16 outw, u16 outh)
829{ 863{
830 int r = 0; 864 int r = 0;
@@ -832,9 +866,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
832 struct fb_var_screeninfo *var = &fbi->var; 866 struct fb_var_screeninfo *var = &fbi->var;
833 struct fb_fix_screeninfo *fix = &fbi->fix; 867 struct fb_fix_screeninfo *fix = &fbi->fix;
834 enum omap_color_mode mode = 0; 868 enum omap_color_mode mode = 0;
835 int offset; 869 u32 data_start_p = 0;
836 u32 data_start_p; 870 void __iomem *data_start_v = NULL;
837 void __iomem *data_start_v;
838 struct omap_overlay_info info; 871 struct omap_overlay_info info;
839 int xres, yres; 872 int xres, yres;
840 int screen_width; 873 int screen_width;
@@ -842,6 +875,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
842 int rotation = var->rotate; 875 int rotation = var->rotate;
843 int i; 876 int i;
844 877
878 WARN_ON(!atomic_read(&ofbi->region->lock_count));
879
845 for (i = 0; i < ofbi->num_overlays; i++) { 880 for (i = 0; i < ofbi->num_overlays; i++) {
846 if (ovl != ofbi->overlays[i]) 881 if (ovl != ofbi->overlays[i])
847 continue; 882 continue;
@@ -861,28 +896,9 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
861 yres = var->yres; 896 yres = var->yres;
862 } 897 }
863 898
864 899 if (ofbi->region->size)
865 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 900 omapfb_calc_addr(ofbi, var, fix, rotation,
866 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); 901 &data_start_p, &data_start_v);
867 data_start_v = NULL;
868 } else {
869 data_start_p = omapfb_get_region_paddr(ofbi);
870 data_start_v = omapfb_get_region_vaddr(ofbi);
871 }
872
873 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
874 offset = calc_rotation_offset_vrfb(var, fix, rotation);
875 else
876 offset = calc_rotation_offset_dma(var, fix, rotation);
877
878 data_start_p += offset;
879 data_start_v += offset;
880
881 if (offset)
882 DBG("offset %d, %d = %d\n",
883 var->xoffset, var->yoffset, offset);
884
885 DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v);
886 902
887 r = fb_mode_to_dss_mode(var, &mode); 903 r = fb_mode_to_dss_mode(var, &mode);
888 if (r) { 904 if (r) {
@@ -954,12 +970,14 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
954 fill_fb(fbi); 970 fill_fb(fbi);
955#endif 971#endif
956 972
973 WARN_ON(!atomic_read(&ofbi->region->lock_count));
974
957 for (i = 0; i < ofbi->num_overlays; i++) { 975 for (i = 0; i < ofbi->num_overlays; i++) {
958 ovl = ofbi->overlays[i]; 976 ovl = ofbi->overlays[i];
959 977
960 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); 978 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
961 979
962 if (ofbi->region.size == 0) { 980 if (ofbi->region->size == 0) {
963 /* the fb is not available. disable the overlay */ 981 /* the fb is not available. disable the overlay */
964 omapfb_overlay_enable(ovl, 0); 982 omapfb_overlay_enable(ovl, 0);
965 if (!init && ovl->manager) 983 if (!init && ovl->manager)
@@ -1007,36 +1025,48 @@ err:
1007 * DO NOT MODIFY PAR */ 1025 * DO NOT MODIFY PAR */
1008static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 1026static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1009{ 1027{
1028 struct omapfb_info *ofbi = FB2OFB(fbi);
1010 int r; 1029 int r;
1011 1030
1012 DBG("check_var(%d)\n", FB2OFB(fbi)->id); 1031 DBG("check_var(%d)\n", FB2OFB(fbi)->id);
1013 1032
1033 omapfb_get_mem_region(ofbi->region);
1034
1014 r = check_fb_var(fbi, var); 1035 r = check_fb_var(fbi, var);
1015 1036
1037 omapfb_put_mem_region(ofbi->region);
1038
1016 return r; 1039 return r;
1017} 1040}
1018 1041
1019/* set the video mode according to info->var */ 1042/* set the video mode according to info->var */
1020static int omapfb_set_par(struct fb_info *fbi) 1043static int omapfb_set_par(struct fb_info *fbi)
1021{ 1044{
1045 struct omapfb_info *ofbi = FB2OFB(fbi);
1022 int r; 1046 int r;
1023 1047
1024 DBG("set_par(%d)\n", FB2OFB(fbi)->id); 1048 DBG("set_par(%d)\n", FB2OFB(fbi)->id);
1025 1049
1050 omapfb_get_mem_region(ofbi->region);
1051
1026 set_fb_fix(fbi); 1052 set_fb_fix(fbi);
1027 1053
1028 r = setup_vrfb_rotation(fbi); 1054 r = setup_vrfb_rotation(fbi);
1029 if (r) 1055 if (r)
1030 return r; 1056 goto out;
1031 1057
1032 r = omapfb_apply_changes(fbi, 0); 1058 r = omapfb_apply_changes(fbi, 0);
1033 1059
1060 out:
1061 omapfb_put_mem_region(ofbi->region);
1062
1034 return r; 1063 return r;
1035} 1064}
1036 1065
1037static int omapfb_pan_display(struct fb_var_screeninfo *var, 1066static int omapfb_pan_display(struct fb_var_screeninfo *var,
1038 struct fb_info *fbi) 1067 struct fb_info *fbi)
1039{ 1068{
1069 struct omapfb_info *ofbi = FB2OFB(fbi);
1040 struct fb_var_screeninfo new_var; 1070 struct fb_var_screeninfo new_var;
1041 int r; 1071 int r;
1042 1072
@@ -1052,23 +1082,31 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1052 1082
1053 fbi->var = new_var; 1083 fbi->var = new_var;
1054 1084
1085 omapfb_get_mem_region(ofbi->region);
1086
1055 r = omapfb_apply_changes(fbi, 0); 1087 r = omapfb_apply_changes(fbi, 0);
1056 1088
1089 omapfb_put_mem_region(ofbi->region);
1090
1057 return r; 1091 return r;
1058} 1092}
1059 1093
1060static void mmap_user_open(struct vm_area_struct *vma) 1094static void mmap_user_open(struct vm_area_struct *vma)
1061{ 1095{
1062 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1096 struct omapfb2_mem_region *rg = vma->vm_private_data;
1063 1097
1064 atomic_inc(&ofbi->map_count); 1098 omapfb_get_mem_region(rg);
1099 atomic_inc(&rg->map_count);
1100 omapfb_put_mem_region(rg);
1065} 1101}
1066 1102
1067static void mmap_user_close(struct vm_area_struct *vma) 1103static void mmap_user_close(struct vm_area_struct *vma)
1068{ 1104{
1069 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1105 struct omapfb2_mem_region *rg = vma->vm_private_data;
1070 1106
1071 atomic_dec(&ofbi->map_count); 1107 omapfb_get_mem_region(rg);
1108 atomic_dec(&rg->map_count);
1109 omapfb_put_mem_region(rg);
1072} 1110}
1073 1111
1074static struct vm_operations_struct mmap_user_ops = { 1112static struct vm_operations_struct mmap_user_ops = {
@@ -1080,9 +1118,11 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1080{ 1118{
1081 struct omapfb_info *ofbi = FB2OFB(fbi); 1119 struct omapfb_info *ofbi = FB2OFB(fbi);
1082 struct fb_fix_screeninfo *fix = &fbi->fix; 1120 struct fb_fix_screeninfo *fix = &fbi->fix;
1121 struct omapfb2_mem_region *rg;
1083 unsigned long off; 1122 unsigned long off;
1084 unsigned long start; 1123 unsigned long start;
1085 u32 len; 1124 u32 len;
1125 int r = -EINVAL;
1086 1126
1087 if (vma->vm_end - vma->vm_start == 0) 1127 if (vma->vm_end - vma->vm_start == 0)
1088 return 0; 1128 return 0;
@@ -1090,12 +1130,14 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1090 return -EINVAL; 1130 return -EINVAL;
1091 off = vma->vm_pgoff << PAGE_SHIFT; 1131 off = vma->vm_pgoff << PAGE_SHIFT;
1092 1132
1133 rg = omapfb_get_mem_region(ofbi->region);
1134
1093 start = omapfb_get_region_paddr(ofbi); 1135 start = omapfb_get_region_paddr(ofbi);
1094 len = fix->smem_len; 1136 len = fix->smem_len;
1095 if (off >= len) 1137 if (off >= len)
1096 return -EINVAL; 1138 goto error;
1097 if ((vma->vm_end - vma->vm_start + off) > len) 1139 if ((vma->vm_end - vma->vm_start + off) > len)
1098 return -EINVAL; 1140 goto error;
1099 1141
1100 off += start; 1142 off += start;
1101 1143
@@ -1105,13 +1147,25 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1105 vma->vm_flags |= VM_IO | VM_RESERVED; 1147 vma->vm_flags |= VM_IO | VM_RESERVED;
1106 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 1148 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1107 vma->vm_ops = &mmap_user_ops; 1149 vma->vm_ops = &mmap_user_ops;
1108 vma->vm_private_data = ofbi; 1150 vma->vm_private_data = rg;
1109 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1151 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1110 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 1152 vma->vm_end - vma->vm_start,
1111 return -EAGAIN; 1153 vma->vm_page_prot)) {
1154 r = -EAGAIN;
1155 goto error;
1156 }
1157
1112 /* vm_ops.open won't be called for mmap itself. */ 1158 /* vm_ops.open won't be called for mmap itself. */
1113 atomic_inc(&ofbi->map_count); 1159 atomic_inc(&rg->map_count);
1160
1161 omapfb_put_mem_region(rg);
1162
1114 return 0; 1163 return 0;
1164
1165 error:
1166 omapfb_put_mem_region(ofbi->region);
1167
1168 return r;
1115} 1169}
1116 1170
1117/* Store a single color palette entry into a pseudo palette or the hardware 1171/* Store a single color palette entry into a pseudo palette or the hardware
@@ -1154,11 +1208,6 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
1154 if (r != 0) 1208 if (r != 0)
1155 break; 1209 break;
1156 1210
1157 if (regno < 0) {
1158 r = -EINVAL;
1159 break;
1160 }
1161
1162 if (regno < 16) { 1211 if (regno < 16) {
1163 u16 pal; 1212 u16 pal;
1164 pal = ((red >> (16 - var->red.length)) << 1213 pal = ((red >> (16 - var->red.length)) <<
@@ -1217,6 +1266,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1217 int do_update = 0; 1266 int do_update = 0;
1218 int r = 0; 1267 int r = 0;
1219 1268
1269 if (!display)
1270 return -EINVAL;
1271
1220 omapfb_lock(fbdev); 1272 omapfb_lock(fbdev);
1221 1273
1222 switch (blank) { 1274 switch (blank) {
@@ -1300,7 +1352,9 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1300 struct omapfb2_device *fbdev = ofbi->fbdev; 1352 struct omapfb2_device *fbdev = ofbi->fbdev;
1301 struct omapfb2_mem_region *rg; 1353 struct omapfb2_mem_region *rg;
1302 1354
1303 rg = &ofbi->region; 1355 rg = ofbi->region;
1356
1357 WARN_ON(atomic_read(&rg->map_count));
1304 1358
1305 if (rg->paddr) 1359 if (rg->paddr)
1306 if (omap_vram_free(rg->paddr, rg->size)) 1360 if (omap_vram_free(rg->paddr, rg->size))
@@ -1355,8 +1409,15 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1355 void __iomem *vaddr; 1409 void __iomem *vaddr;
1356 int r; 1410 int r;
1357 1411
1358 rg = &ofbi->region; 1412 rg = ofbi->region;
1359 memset(rg, 0, sizeof(*rg)); 1413
1414 rg->paddr = 0;
1415 rg->vaddr = NULL;
1416 memset(&rg->vrfb, 0, sizeof rg->vrfb);
1417 rg->size = 0;
1418 rg->type = 0;
1419 rg->alloc = false;
1420 rg->map = false;
1360 1421
1361 size = PAGE_ALIGN(size); 1422 size = PAGE_ALIGN(size);
1362 1423
@@ -1609,7 +1670,7 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1609 for (i = 0; i < fbdev->num_fbs; i++) { 1670 for (i = 0; i < fbdev->num_fbs; i++) {
1610 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1671 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
1611 struct omapfb2_mem_region *rg; 1672 struct omapfb2_mem_region *rg;
1612 rg = &ofbi->region; 1673 rg = ofbi->region;
1613 1674
1614 DBG("region%d phys %08x virt %p size=%lu\n", 1675 DBG("region%d phys %08x virt %p size=%lu\n",
1615 i, 1676 i,
@@ -1626,7 +1687,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1626 struct omapfb_info *ofbi = FB2OFB(fbi); 1687 struct omapfb_info *ofbi = FB2OFB(fbi);
1627 struct omapfb2_device *fbdev = ofbi->fbdev; 1688 struct omapfb2_device *fbdev = ofbi->fbdev;
1628 struct omap_dss_device *display = fb2display(fbi); 1689 struct omap_dss_device *display = fb2display(fbi);
1629 struct omapfb2_mem_region *rg = &ofbi->region; 1690 struct omapfb2_mem_region *rg = ofbi->region;
1630 unsigned long old_size = rg->size; 1691 unsigned long old_size = rg->size;
1631 unsigned long old_paddr = rg->paddr; 1692 unsigned long old_paddr = rg->paddr;
1632 int old_type = rg->type; 1693 int old_type = rg->type;
@@ -1709,7 +1770,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1709 fbi->flags = FBINFO_FLAG_DEFAULT; 1770 fbi->flags = FBINFO_FLAG_DEFAULT;
1710 fbi->pseudo_palette = fbdev->pseudo_palette; 1771 fbi->pseudo_palette = fbdev->pseudo_palette;
1711 1772
1712 if (ofbi->region.size == 0) { 1773 if (ofbi->region->size == 0) {
1713 clear_fb_info(fbi); 1774 clear_fb_info(fbi);
1714 return 0; 1775 return 0;
1715 } 1776 }
@@ -1871,6 +1932,10 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1871 ofbi->fbdev = fbdev; 1932 ofbi->fbdev = fbdev;
1872 ofbi->id = i; 1933 ofbi->id = i;
1873 1934
1935 ofbi->region = &fbdev->regions[i];
1936 ofbi->region->id = i;
1937 init_rwsem(&ofbi->region->lock);
1938
1874 /* assign these early, so that fb alloc can use them */ 1939 /* assign these early, so that fb alloc can use them */
1875 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1940 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
1876 OMAP_DSS_ROT_DMA; 1941 OMAP_DSS_ROT_DMA;
@@ -1900,7 +1965,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1900 1965
1901 /* setup fb_infos */ 1966 /* setup fb_infos */
1902 for (i = 0; i < fbdev->num_fbs; i++) { 1967 for (i = 0; i < fbdev->num_fbs; i++) {
1903 r = omapfb_fb_init(fbdev, fbdev->fbs[i]); 1968 struct fb_info *fbi = fbdev->fbs[i];
1969 struct omapfb_info *ofbi = FB2OFB(fbi);
1970
1971 omapfb_get_mem_region(ofbi->region);
1972 r = omapfb_fb_init(fbdev, fbi);
1973 omapfb_put_mem_region(ofbi->region);
1974
1904 if (r) { 1975 if (r) {
1905 dev_err(fbdev->dev, "failed to setup fb_info\n"); 1976 dev_err(fbdev->dev, "failed to setup fb_info\n");
1906 return r; 1977 return r;
@@ -1921,20 +1992,19 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1921 DBG("framebuffers registered\n"); 1992 DBG("framebuffers registered\n");
1922 1993
1923 for (i = 0; i < fbdev->num_fbs; i++) { 1994 for (i = 0; i < fbdev->num_fbs; i++) {
1924 r = omapfb_apply_changes(fbdev->fbs[i], 1); 1995 struct fb_info *fbi = fbdev->fbs[i];
1996 struct omapfb_info *ofbi = FB2OFB(fbi);
1997
1998 omapfb_get_mem_region(ofbi->region);
1999 r = omapfb_apply_changes(fbi, 1);
2000 omapfb_put_mem_region(ofbi->region);
2001
1925 if (r) { 2002 if (r) {
1926 dev_err(fbdev->dev, "failed to change mode\n"); 2003 dev_err(fbdev->dev, "failed to change mode\n");
1927 return r; 2004 return r;
1928 } 2005 }
1929 } 2006 }
1930 2007
1931 DBG("create sysfs for fbs\n");
1932 r = omapfb_create_sysfs(fbdev);
1933 if (r) {
1934 dev_err(fbdev->dev, "failed to create sysfs entries\n");
1935 return r;
1936 }
1937
1938 /* Enable fb0 */ 2008 /* Enable fb0 */
1939 if (fbdev->num_fbs > 0) { 2009 if (fbdev->num_fbs > 0) {
1940 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]); 2010 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
@@ -1968,11 +2038,11 @@ static int omapfb_mode_to_timings(const char *mode_str,
1968#ifdef CONFIG_OMAP2_DSS_VENC 2038#ifdef CONFIG_OMAP2_DSS_VENC
1969 if (strcmp(mode_str, "pal") == 0) { 2039 if (strcmp(mode_str, "pal") == 0) {
1970 *timings = omap_dss_pal_timings; 2040 *timings = omap_dss_pal_timings;
1971 *bpp = 0; 2041 *bpp = 24;
1972 return 0; 2042 return 0;
1973 } else if (strcmp(mode_str, "ntsc") == 0) { 2043 } else if (strcmp(mode_str, "ntsc") == 0) {
1974 *timings = omap_dss_ntsc_timings; 2044 *timings = omap_dss_ntsc_timings;
1975 *bpp = 0; 2045 *bpp = 24;
1976 return 0; 2046 return 0;
1977 } 2047 }
1978#endif 2048#endif
@@ -2220,6 +2290,13 @@ static int omapfb_probe(struct platform_device *pdev)
2220 } 2290 }
2221 } 2291 }
2222 2292
2293 DBG("create sysfs for fbs\n");
2294 r = omapfb_create_sysfs(fbdev);
2295 if (r) {
2296 dev_err(fbdev->dev, "failed to create sysfs entries\n");
2297 goto cleanup;
2298 }
2299
2223 return 0; 2300 return 0;
2224 2301
2225cleanup: 2302cleanup:
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 5179219128bd..6f9c72cd6bb0 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -49,6 +49,7 @@ static ssize_t store_rotate_type(struct device *dev,
49{ 49{
50 struct fb_info *fbi = dev_get_drvdata(dev); 50 struct fb_info *fbi = dev_get_drvdata(dev);
51 struct omapfb_info *ofbi = FB2OFB(fbi); 51 struct omapfb_info *ofbi = FB2OFB(fbi);
52 struct omapfb2_mem_region *rg;
52 enum omap_dss_rotation_type rot_type; 53 enum omap_dss_rotation_type rot_type;
53 int r; 54 int r;
54 55
@@ -64,9 +65,11 @@ static ssize_t store_rotate_type(struct device *dev,
64 if (rot_type == ofbi->rotation_type) 65 if (rot_type == ofbi->rotation_type)
65 goto out; 66 goto out;
66 67
67 if (ofbi->region.size) { 68 rg = omapfb_get_mem_region(ofbi->region);
69
70 if (rg->size) {
68 r = -EBUSY; 71 r = -EBUSY;
69 goto out; 72 goto put_region;
70 } 73 }
71 74
72 ofbi->rotation_type = rot_type; 75 ofbi->rotation_type = rot_type;
@@ -75,6 +78,8 @@ static ssize_t store_rotate_type(struct device *dev,
75 * Since the VRAM for this FB is not allocated at the moment we don't 78 * Since the VRAM for this FB is not allocated at the moment we don't
76 * need to do any further parameter checking at this point. 79 * need to do any further parameter checking at this point.
77 */ 80 */
81put_region:
82 omapfb_put_mem_region(rg);
78out: 83out:
79 unlock_fb_info(fbi); 84 unlock_fb_info(fbi);
80 85
@@ -97,7 +102,7 @@ static ssize_t store_mirror(struct device *dev,
97{ 102{
98 struct fb_info *fbi = dev_get_drvdata(dev); 103 struct fb_info *fbi = dev_get_drvdata(dev);
99 struct omapfb_info *ofbi = FB2OFB(fbi); 104 struct omapfb_info *ofbi = FB2OFB(fbi);
100 bool mirror; 105 unsigned long mirror;
101 int r; 106 int r;
102 struct fb_var_screeninfo new_var; 107 struct fb_var_screeninfo new_var;
103 108
@@ -111,6 +116,8 @@ static ssize_t store_mirror(struct device *dev,
111 116
112 ofbi->mirror = mirror; 117 ofbi->mirror = mirror;
113 118
119 omapfb_get_mem_region(ofbi->region);
120
114 memcpy(&new_var, &fbi->var, sizeof(new_var)); 121 memcpy(&new_var, &fbi->var, sizeof(new_var));
115 r = check_fb_var(fbi, &new_var); 122 r = check_fb_var(fbi, &new_var);
116 if (r) 123 if (r)
@@ -125,6 +132,8 @@ static ssize_t store_mirror(struct device *dev,
125 132
126 r = count; 133 r = count;
127out: 134out:
135 omapfb_put_mem_region(ofbi->region);
136
128 unlock_fb_info(fbi); 137 unlock_fb_info(fbi);
129 138
130 return r; 139 return r;
@@ -263,11 +272,15 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
263 272
264 DBG("detaching %d\n", ofbi->overlays[i]->id); 273 DBG("detaching %d\n", ofbi->overlays[i]->id);
265 274
275 omapfb_get_mem_region(ofbi->region);
276
266 omapfb_overlay_enable(ovl, 0); 277 omapfb_overlay_enable(ovl, 0);
267 278
268 if (ovl->manager) 279 if (ovl->manager)
269 ovl->manager->apply(ovl->manager); 280 ovl->manager->apply(ovl->manager);
270 281
282 omapfb_put_mem_region(ofbi->region);
283
271 for (t = i + 1; t < ofbi->num_overlays; t++) { 284 for (t = i + 1; t < ofbi->num_overlays; t++) {
272 ofbi->rotation[t-1] = ofbi->rotation[t]; 285 ofbi->rotation[t-1] = ofbi->rotation[t];
273 ofbi->overlays[t-1] = ofbi->overlays[t]; 286 ofbi->overlays[t-1] = ofbi->overlays[t];
@@ -300,7 +313,12 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
300 } 313 }
301 314
302 if (added) { 315 if (added) {
316 omapfb_get_mem_region(ofbi->region);
317
303 r = omapfb_apply_changes(fbi, 0); 318 r = omapfb_apply_changes(fbi, 0);
319
320 omapfb_put_mem_region(ofbi->region);
321
304 if (r) 322 if (r)
305 goto out; 323 goto out;
306 } 324 }
@@ -388,7 +406,12 @@ static ssize_t store_overlays_rotate(struct device *dev,
388 for (i = 0; i < num_ovls; ++i) 406 for (i = 0; i < num_ovls; ++i)
389 ofbi->rotation[i] = rotation[i]; 407 ofbi->rotation[i] = rotation[i];
390 408
409 omapfb_get_mem_region(ofbi->region);
410
391 r = omapfb_apply_changes(fbi, 0); 411 r = omapfb_apply_changes(fbi, 0);
412
413 omapfb_put_mem_region(ofbi->region);
414
392 if (r) 415 if (r)
393 goto out; 416 goto out;
394 417
@@ -408,7 +431,7 @@ static ssize_t show_size(struct device *dev,
408 struct fb_info *fbi = dev_get_drvdata(dev); 431 struct fb_info *fbi = dev_get_drvdata(dev);
409 struct omapfb_info *ofbi = FB2OFB(fbi); 432 struct omapfb_info *ofbi = FB2OFB(fbi);
410 433
411 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); 434 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
412} 435}
413 436
414static ssize_t store_size(struct device *dev, struct device_attribute *attr, 437static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -416,6 +439,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
416{ 439{
417 struct fb_info *fbi = dev_get_drvdata(dev); 440 struct fb_info *fbi = dev_get_drvdata(dev);
418 struct omapfb_info *ofbi = FB2OFB(fbi); 441 struct omapfb_info *ofbi = FB2OFB(fbi);
442 struct omapfb2_device *fbdev = ofbi->fbdev;
443 struct omapfb2_mem_region *rg;
419 unsigned long size; 444 unsigned long size;
420 int r; 445 int r;
421 int i; 446 int i;
@@ -425,15 +450,33 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
425 if (!lock_fb_info(fbi)) 450 if (!lock_fb_info(fbi))
426 return -ENODEV; 451 return -ENODEV;
427 452
428 for (i = 0; i < ofbi->num_overlays; i++) { 453 rg = ofbi->region;
429 if (ofbi->overlays[i]->info.enabled) { 454
430 r = -EBUSY; 455 down_write_nested(&rg->lock, rg->id);
431 goto out; 456 atomic_inc(&rg->lock_count);
457
458 if (atomic_read(&rg->map_count)) {
459 r = -EBUSY;
460 goto out;
461 }
462
463 for (i = 0; i < fbdev->num_fbs; i++) {
464 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
465 int j;
466
467 if (ofbi2->region != rg)
468 continue;
469
470 for (j = 0; j < ofbi2->num_overlays; j++) {
471 if (ofbi2->overlays[j]->info.enabled) {
472 r = -EBUSY;
473 goto out;
474 }
432 } 475 }
433 } 476 }
434 477
435 if (size != ofbi->region.size) { 478 if (size != ofbi->region->size) {
436 r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); 479 r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
437 if (r) { 480 if (r) {
438 dev_err(dev, "realloc fbmem failed\n"); 481 dev_err(dev, "realloc fbmem failed\n");
439 goto out; 482 goto out;
@@ -442,6 +485,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
442 485
443 r = count; 486 r = count;
444out: 487out:
488 atomic_dec(&rg->lock_count);
489 up_write(&rg->lock);
490
445 unlock_fb_info(fbi); 491 unlock_fb_info(fbi);
446 492
447 return r; 493 return r;
@@ -453,7 +499,7 @@ static ssize_t show_phys(struct device *dev,
453 struct fb_info *fbi = dev_get_drvdata(dev); 499 struct fb_info *fbi = dev_get_drvdata(dev);
454 struct omapfb_info *ofbi = FB2OFB(fbi); 500 struct omapfb_info *ofbi = FB2OFB(fbi);
455 501
456 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); 502 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
457} 503}
458 504
459static ssize_t show_virt(struct device *dev, 505static ssize_t show_virt(struct device *dev,
@@ -462,7 +508,7 @@ static ssize_t show_virt(struct device *dev,
462 struct fb_info *fbi = dev_get_drvdata(dev); 508 struct fb_info *fbi = dev_get_drvdata(dev);
463 struct omapfb_info *ofbi = FB2OFB(fbi); 509 struct omapfb_info *ofbi = FB2OFB(fbi);
464 510
465 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); 511 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
466} 512}
467 513
468static struct device_attribute omapfb_attrs[] = { 514static struct device_attribute omapfb_attrs[] = {
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index cd54fdbfd8bb..1305fc9880ba 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -27,6 +27,8 @@
27#define DEBUG 27#define DEBUG
28#endif 28#endif
29 29
30#include <linux/rwsem.h>
31
30#include <plat/display.h> 32#include <plat/display.h>
31 33
32#ifdef DEBUG 34#ifdef DEBUG
@@ -44,6 +46,7 @@ extern unsigned int omapfb_debug;
44#define OMAPFB_MAX_OVL_PER_FB 3 46#define OMAPFB_MAX_OVL_PER_FB 3
45 47
46struct omapfb2_mem_region { 48struct omapfb2_mem_region {
49 int id;
47 u32 paddr; 50 u32 paddr;
48 void __iomem *vaddr; 51 void __iomem *vaddr;
49 struct vrfb vrfb; 52 struct vrfb vrfb;
@@ -51,13 +54,15 @@ struct omapfb2_mem_region {
51 u8 type; /* OMAPFB_PLANE_MEM_* */ 54 u8 type; /* OMAPFB_PLANE_MEM_* */
52 bool alloc; /* allocated by the driver */ 55 bool alloc; /* allocated by the driver */
53 bool map; /* kernel mapped by the driver */ 56 bool map; /* kernel mapped by the driver */
57 atomic_t map_count;
58 struct rw_semaphore lock;
59 atomic_t lock_count;
54}; 60};
55 61
56/* appended to fb_info */ 62/* appended to fb_info */
57struct omapfb_info { 63struct omapfb_info {
58 int id; 64 int id;
59 struct omapfb2_mem_region region; 65 struct omapfb2_mem_region *region;
60 atomic_t map_count;
61 int num_overlays; 66 int num_overlays;
62 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; 67 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
63 struct omapfb2_device *fbdev; 68 struct omapfb2_device *fbdev;
@@ -76,6 +81,7 @@ struct omapfb2_device {
76 81
77 unsigned num_fbs; 82 unsigned num_fbs;
78 struct fb_info *fbs[10]; 83 struct fb_info *fbs[10];
84 struct omapfb2_mem_region regions[10];
79 85
80 unsigned num_displays; 86 unsigned num_displays;
81 struct omap_dss_device *displays[10]; 87 struct omap_dss_device *displays[10];
@@ -117,6 +123,9 @@ int omapfb_update_window(struct fb_info *fbi,
117int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 123int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
118 struct fb_var_screeninfo *var); 124 struct fb_var_screeninfo *var);
119 125
126int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
127 u16 posx, u16 posy, u16 outw, u16 outh);
128
120/* find the display connected to this fb, if any */ 129/* find the display connected to this fb, if any */
121static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 130static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
122{ 131{
@@ -148,8 +157,24 @@ static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
148 struct omap_overlay_info info; 157 struct omap_overlay_info info;
149 158
150 ovl->get_overlay_info(ovl, &info); 159 ovl->get_overlay_info(ovl, &info);
160 if (info.enabled == enable)
161 return 0;
151 info.enabled = enable; 162 info.enabled = enable;
152 return ovl->set_overlay_info(ovl, &info); 163 return ovl->set_overlay_info(ovl, &info);
153} 164}
154 165
166static inline struct omapfb2_mem_region *
167omapfb_get_mem_region(struct omapfb2_mem_region *rg)
168{
169 down_read_nested(&rg->lock, rg->id);
170 atomic_inc(&rg->lock_count);
171 return rg;
172}
173
174static inline void omapfb_put_mem_region(struct omapfb2_mem_region *rg)
175{
176 atomic_dec(&rg->lock_count);
177 up_read(&rg->lock);
178}
179
155#endif 180#endif
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 6552751e81aa..b6c3fc2db632 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -249,7 +249,7 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
249 info->fix.accel = FB_ACCEL_SUN_CGTHREE; 249 info->fix.accel = FB_ACCEL_SUN_CGTHREE;
250} 250}
251 251
252static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match) 252static int __devinit p9100_probe(struct platform_device *op, const struct of_device_id *match)
253{ 253{
254 struct device_node *dp = op->dev.of_node; 254 struct device_node *dp = op->dev.of_node;
255 struct fb_info *info; 255 struct fb_info *info;
@@ -326,7 +326,7 @@ out_err:
326 return err; 326 return err;
327} 327}
328 328
329static int __devexit p9100_remove(struct of_device *op) 329static int __devexit p9100_remove(struct platform_device *op)
330{ 330{
331 struct fb_info *info = dev_get_drvdata(&op->dev); 331 struct fb_info *info = dev_get_drvdata(&op->dev);
332 struct p9100_par *par = info->par; 332 struct p9100_par *par = info->par;
@@ -367,12 +367,12 @@ static int __init p9100_init(void)
367 if (fb_get_options("p9100fb", NULL)) 367 if (fb_get_options("p9100fb", NULL))
368 return -ENODEV; 368 return -ENODEV;
369 369
370 return of_register_driver(&p9100_driver, &of_bus_type); 370 return of_register_platform_driver(&p9100_driver);
371} 371}
372 372
373static void __exit p9100_exit(void) 373static void __exit p9100_exit(void)
374{ 374{
375 of_unregister_driver(&p9100_driver); 375 of_unregister_platform_driver(&p9100_driver);
376} 376}
377 377
378module_init(p9100_init); 378module_init(p9100_init);
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 72a1f4c04732..a50e1977b316 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -533,7 +533,7 @@ static int __init platinumfb_setup(char *options)
533#define invalidate_cache(addr) 533#define invalidate_cache(addr)
534#endif 534#endif
535 535
536static int __devinit platinumfb_probe(struct of_device* odev, 536static int __devinit platinumfb_probe(struct platform_device* odev,
537 const struct of_device_id *match) 537 const struct of_device_id *match)
538{ 538{
539 struct device_node *dp = odev->dev.of_node; 539 struct device_node *dp = odev->dev.of_node;
@@ -646,7 +646,7 @@ static int __devinit platinumfb_probe(struct of_device* odev,
646 return rc; 646 return rc;
647} 647}
648 648
649static int __devexit platinumfb_remove(struct of_device* odev) 649static int __devexit platinumfb_remove(struct platform_device* odev)
650{ 650{
651 struct fb_info *info = dev_get_drvdata(&odev->dev); 651 struct fb_info *info = dev_get_drvdata(&odev->dev);
652 struct fb_info_platinum *pinfo = info->par; 652 struct fb_info_platinum *pinfo = info->par;
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 9682ecc60e12..f9aca9d13d1b 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1,7 +1,7 @@
1/* linux/drivers/video/s3c-fb.c 1/* linux/drivers/video/s3c-fb.c
2 * 2 *
3 * Copyright 2008 Openmoko Inc. 3 * Copyright 2008 Openmoko Inc.
4 * Copyright 2008 Simtec Electronics 4 * Copyright 2008-2010 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/ 6 * http://armlinux.simtec.co.uk/
7 * 7 *
@@ -9,7 +9,7 @@
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software FoundatIon.
13*/ 13*/
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -21,9 +21,11 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/fb.h> 22#include <linux/fb.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/uaccess.h>
25#include <linux/interrupt.h>
24 26
25#include <mach/map.h> 27#include <mach/map.h>
26#include <mach/regs-fb.h> 28#include <plat/regs-fb-v4.h>
27#include <plat/fb.h> 29#include <plat/fb.h>
28 30
29/* This driver will export a number of framebuffer interfaces depending 31/* This driver will export a number of framebuffer interfaces depending
@@ -36,9 +38,9 @@
36 * output timings and as the control for the output power-down state. 38 * output timings and as the control for the output power-down state.
37*/ 39*/
38 40
39/* note, some of the functions that get called are derived from including 41/* note, the previous use of <mach/regs-fb.h> to get platform specific data
40 * <mach/regs-fb.h> as they are specific to the architecture that the code 42 * has been replaced by using the platform device name to pick the correct
41 * is being built for. 43 * configuration data for the system.
42*/ 44*/
43 45
44#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE 46#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE
@@ -48,13 +50,108 @@
48 __raw_writel(v, r); } while(0) 50 __raw_writel(v, r); } while(0)
49#endif /* FB_S3C_DEBUG_REGWRITE */ 51#endif /* FB_S3C_DEBUG_REGWRITE */
50 52
53/* irq_flags bits */
54#define S3C_FB_VSYNC_IRQ_EN 0
55
56#define VSYNC_TIMEOUT_MSEC 50
57
51struct s3c_fb; 58struct s3c_fb;
52 59
60#define VALID_BPP(x) (1 << ((x) - 1))
61
62#define OSD_BASE(win, variant) ((variant).osd + ((win) * (variant).osd_stride))
63#define VIDOSD_A(win, variant) (OSD_BASE(win, variant) + 0x00)
64#define VIDOSD_B(win, variant) (OSD_BASE(win, variant) + 0x04)
65#define VIDOSD_C(win, variant) (OSD_BASE(win, variant) + 0x08)
66#define VIDOSD_D(win, variant) (OSD_BASE(win, variant) + 0x0C)
67
68/**
69 * struct s3c_fb_variant - fb variant information
70 * @is_2443: Set if S3C2443/S3C2416 style hardware.
71 * @nr_windows: The number of windows.
72 * @vidtcon: The base for the VIDTCONx registers
73 * @wincon: The base for the WINxCON registers.
74 * @winmap: The base for the WINxMAP registers.
75 * @keycon: The abse for the WxKEYCON registers.
76 * @buf_start: Offset of buffer start registers.
77 * @buf_size: Offset of buffer size registers.
78 * @buf_end: Offset of buffer end registers.
79 * @osd: The base for the OSD registers.
80 * @palette: Address of palette memory, or 0 if none.
81 * @has_prtcon: Set if has PRTCON register.
82 * @has_shadowcon: Set if has SHADOWCON register.
83 */
84struct s3c_fb_variant {
85 unsigned int is_2443:1;
86 unsigned short nr_windows;
87 unsigned short vidtcon;
88 unsigned short wincon;
89 unsigned short winmap;
90 unsigned short keycon;
91 unsigned short buf_start;
92 unsigned short buf_end;
93 unsigned short buf_size;
94 unsigned short osd;
95 unsigned short osd_stride;
96 unsigned short palette[S3C_FB_MAX_WIN];
97
98 unsigned int has_prtcon:1;
99 unsigned int has_shadowcon:1;
100};
101
102/**
103 * struct s3c_fb_win_variant
104 * @has_osd_c: Set if has OSD C register.
105 * @has_osd_d: Set if has OSD D register.
106 * @has_osd_alpha: Set if can change alpha transparency for a window.
107 * @palette_sz: Size of palette in entries.
108 * @palette_16bpp: Set if palette is 16bits wide.
109 * @osd_size_off: If != 0, supports setting up OSD for a window; the appropriate
110 * register is located at the given offset from OSD_BASE.
111 * @valid_bpp: 1 bit per BPP setting to show valid bits-per-pixel.
112 *
113 * valid_bpp bit x is set if (x+1)BPP is supported.
114 */
115struct s3c_fb_win_variant {
116 unsigned int has_osd_c:1;
117 unsigned int has_osd_d:1;
118 unsigned int has_osd_alpha:1;
119 unsigned int palette_16bpp:1;
120 unsigned short osd_size_off;
121 unsigned short palette_sz;
122 u32 valid_bpp;
123};
124
125/**
126 * struct s3c_fb_driverdata - per-device type driver data for init time.
127 * @variant: The variant information for this driver.
128 * @win: The window information for each window.
129 */
130struct s3c_fb_driverdata {
131 struct s3c_fb_variant variant;
132 struct s3c_fb_win_variant *win[S3C_FB_MAX_WIN];
133};
134
135/**
136 * struct s3c_fb_palette - palette information
137 * @r: Red bitfield.
138 * @g: Green bitfield.
139 * @b: Blue bitfield.
140 * @a: Alpha bitfield.
141 */
142struct s3c_fb_palette {
143 struct fb_bitfield r;
144 struct fb_bitfield g;
145 struct fb_bitfield b;
146 struct fb_bitfield a;
147};
148
53/** 149/**
54 * struct s3c_fb_win - per window private data for each framebuffer. 150 * struct s3c_fb_win - per window private data for each framebuffer.
55 * @windata: The platform data supplied for the window configuration. 151 * @windata: The platform data supplied for the window configuration.
56 * @parent: The hardware that this window is part of. 152 * @parent: The hardware that this window is part of.
57 * @fbinfo: Pointer pack to the framebuffer info for this window. 153 * @fbinfo: Pointer pack to the framebuffer info for this window.
154 * @varint: The variant information for this window.
58 * @palette_buffer: Buffer/cache to hold palette entries. 155 * @palette_buffer: Buffer/cache to hold palette entries.
59 * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/ 156 * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/
60 * @index: The window number of this window. 157 * @index: The window number of this window.
@@ -65,6 +162,7 @@ struct s3c_fb_win {
65 struct s3c_fb *parent; 162 struct s3c_fb *parent;
66 struct fb_info *fbinfo; 163 struct fb_info *fbinfo;
67 struct s3c_fb_palette palette; 164 struct s3c_fb_palette palette;
165 struct s3c_fb_win_variant variant;
68 166
69 u32 *palette_buffer; 167 u32 *palette_buffer;
70 u32 pseudo_palette[16]; 168 u32 pseudo_palette[16];
@@ -72,37 +170,54 @@ struct s3c_fb_win {
72}; 170};
73 171
74/** 172/**
173 * struct s3c_fb_vsync - vsync information
174 * @wait: a queue for processes waiting for vsync
175 * @count: vsync interrupt count
176 */
177struct s3c_fb_vsync {
178 wait_queue_head_t wait;
179 unsigned int count;
180};
181
182/**
75 * struct s3c_fb - overall hardware state of the hardware 183 * struct s3c_fb - overall hardware state of the hardware
76 * @dev: The device that we bound to, for printing, etc. 184 * @dev: The device that we bound to, for printing, etc.
77 * @regs_res: The resource we claimed for the IO registers. 185 * @regs_res: The resource we claimed for the IO registers.
78 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 186 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
79 * @regs: The mapped hardware registers. 187 * @regs: The mapped hardware registers.
188 * @variant: Variant information for this hardware.
80 * @enabled: A bitmask of enabled hardware windows. 189 * @enabled: A bitmask of enabled hardware windows.
81 * @pdata: The platform configuration data passed with the device. 190 * @pdata: The platform configuration data passed with the device.
82 * @windows: The hardware windows that have been claimed. 191 * @windows: The hardware windows that have been claimed.
192 * @irq_no: IRQ line number
193 * @irq_flags: irq flags
194 * @vsync_info: VSYNC-related information (count, queues...)
83 */ 195 */
84struct s3c_fb { 196struct s3c_fb {
85 struct device *dev; 197 struct device *dev;
86 struct resource *regs_res; 198 struct resource *regs_res;
87 struct clk *bus_clk; 199 struct clk *bus_clk;
88 void __iomem *regs; 200 void __iomem *regs;
201 struct s3c_fb_variant variant;
89 202
90 unsigned char enabled; 203 unsigned char enabled;
91 204
92 struct s3c_fb_platdata *pdata; 205 struct s3c_fb_platdata *pdata;
93 struct s3c_fb_win *windows[S3C_FB_MAX_WIN]; 206 struct s3c_fb_win *windows[S3C_FB_MAX_WIN];
207
208 int irq_no;
209 unsigned long irq_flags;
210 struct s3c_fb_vsync vsync_info;
94}; 211};
95 212
96/** 213/**
97 * s3c_fb_win_has_palette() - determine if a mode has a palette 214 * s3c_fb_validate_win_bpp - validate the bits-per-pixel for this mode.
98 * @win: The window number being queried. 215 * @win: The device window.
99 * @bpp: The number of bits per pixel to test. 216 * @bpp: The bit depth.
100 *
101 * Work out if the given window supports palletised data at the specified bpp.
102 */ 217 */
103static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp) 218static bool s3c_fb_validate_win_bpp(struct s3c_fb_win *win, unsigned int bpp)
104{ 219{
105 return s3c_fb_win_pal_size(win) <= (1 << bpp); 220 return win->variant.valid_bpp & VALID_BPP(bpp);
106} 221}
107 222
108/** 223/**
@@ -125,7 +240,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
125 var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres); 240 var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres);
126 var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres); 241 var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres);
127 242
128 if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) { 243 if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) {
129 dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", 244 dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n",
130 win->index, var->bits_per_pixel); 245 win->index, var->bits_per_pixel);
131 return -EINVAL; 246 return -EINVAL;
@@ -140,7 +255,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
140 case 2: 255 case 2:
141 case 4: 256 case 4:
142 case 8: 257 case 8:
143 if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) { 258 if (sfb->variant.palette[win->index] != 0) {
144 /* non palletised, A:1,R:2,G:3,B:2 mode */ 259 /* non palletised, A:1,R:2,G:3,B:2 mode */
145 var->red.offset = 4; 260 var->red.offset = 4;
146 var->green.offset = 2; 261 var->green.offset = 2;
@@ -255,6 +370,66 @@ static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
255} 370}
256 371
257/** 372/**
373 * vidosd_set_size() - set OSD size for a window
374 *
375 * @win: the window to set OSD size for
376 * @size: OSD size register value
377 */
378static void vidosd_set_size(struct s3c_fb_win *win, u32 size)
379{
380 struct s3c_fb *sfb = win->parent;
381
382 /* OSD can be set up if osd_size_off != 0 for this window */
383 if (win->variant.osd_size_off)
384 writel(size, sfb->regs + OSD_BASE(win->index, sfb->variant)
385 + win->variant.osd_size_off);
386}
387
388/**
389 * vidosd_set_alpha() - set alpha transparency for a window
390 *
391 * @win: the window to set OSD size for
392 * @alpha: alpha register value
393 */
394static void vidosd_set_alpha(struct s3c_fb_win *win, u32 alpha)
395{
396 struct s3c_fb *sfb = win->parent;
397
398 if (win->variant.has_osd_alpha)
399 writel(alpha, sfb->regs + VIDOSD_C(win->index, sfb->variant));
400}
401
402/**
403 * shadow_protect_win() - disable updating values from shadow registers at vsync
404 *
405 * @win: window to protect registers for
406 * @protect: 1 to protect (disable updates)
407 */
408static void shadow_protect_win(struct s3c_fb_win *win, bool protect)
409{
410 struct s3c_fb *sfb = win->parent;
411 u32 reg;
412
413 if (protect) {
414 if (sfb->variant.has_prtcon) {
415 writel(PRTCON_PROTECT, sfb->regs + PRTCON);
416 } else if (sfb->variant.has_shadowcon) {
417 reg = readl(sfb->regs + SHADOWCON);
418 writel(reg | SHADOWCON_WINx_PROTECT(win->index),
419 sfb->regs + SHADOWCON);
420 }
421 } else {
422 if (sfb->variant.has_prtcon) {
423 writel(0, sfb->regs + PRTCON);
424 } else if (sfb->variant.has_shadowcon) {
425 reg = readl(sfb->regs + SHADOWCON);
426 writel(reg & ~SHADOWCON_WINx_PROTECT(win->index),
427 sfb->regs + SHADOWCON);
428 }
429 }
430}
431
432/**
258 * s3c_fb_set_par() - framebuffer request to set new framebuffer state. 433 * s3c_fb_set_par() - framebuffer request to set new framebuffer state.
259 * @info: The framebuffer to change. 434 * @info: The framebuffer to change.
260 * 435 *
@@ -266,14 +441,17 @@ static int s3c_fb_set_par(struct fb_info *info)
266 struct s3c_fb_win *win = info->par; 441 struct s3c_fb_win *win = info->par;
267 struct s3c_fb *sfb = win->parent; 442 struct s3c_fb *sfb = win->parent;
268 void __iomem *regs = sfb->regs; 443 void __iomem *regs = sfb->regs;
444 void __iomem *buf = regs;
269 int win_no = win->index; 445 int win_no = win->index;
270 u32 osdc_data = 0; 446 u32 alpha = 0;
271 u32 data; 447 u32 data;
272 u32 pagewidth; 448 u32 pagewidth;
273 int clkdiv; 449 int clkdiv;
274 450
275 dev_dbg(sfb->dev, "setting framebuffer parameters\n"); 451 dev_dbg(sfb->dev, "setting framebuffer parameters\n");
276 452
453 shadow_protect_win(win, 1);
454
277 switch (var->bits_per_pixel) { 455 switch (var->bits_per_pixel) {
278 case 32: 456 case 32:
279 case 24: 457 case 24:
@@ -282,7 +460,7 @@ static int s3c_fb_set_par(struct fb_info *info)
282 info->fix.visual = FB_VISUAL_TRUECOLOR; 460 info->fix.visual = FB_VISUAL_TRUECOLOR;
283 break; 461 break;
284 case 8: 462 case 8:
285 if (s3c_fb_win_has_palette(win_no, 8)) 463 if (win->variant.palette_sz >= 256)
286 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 464 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
287 else 465 else
288 info->fix.visual = FB_VISUAL_TRUECOLOR; 466 info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -297,12 +475,15 @@ static int s3c_fb_set_par(struct fb_info *info)
297 475
298 info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; 476 info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
299 477
478 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
479 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
480
300 /* disable the window whilst we update it */ 481 /* disable the window whilst we update it */
301 writel(0, regs + WINCON(win_no)); 482 writel(0, regs + WINCON(win_no));
302 483
303 /* use window 0 as the basis for the lcd output timings */ 484 /* use platform specified window as the basis for the lcd timings */
304 485
305 if (win_no == 0) { 486 if (win_no == sfb->pdata->default_win) {
306 clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock); 487 clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
307 488
308 data = sfb->pdata->vidcon0; 489 data = sfb->pdata->vidcon0;
@@ -315,6 +496,9 @@ static int s3c_fb_set_par(struct fb_info *info)
315 496
316 /* write the timing data to the panel */ 497 /* write the timing data to the panel */
317 498
499 if (sfb->variant.is_2443)
500 data |= (1 << 5);
501
318 data |= VIDCON0_ENVID | VIDCON0_ENVID_F; 502 data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
319 writel(data, regs + VIDCON0); 503 writel(data, regs + VIDCON0);
320 504
@@ -322,53 +506,54 @@ static int s3c_fb_set_par(struct fb_info *info)
322 VIDTCON0_VFPD(var->lower_margin - 1) | 506 VIDTCON0_VFPD(var->lower_margin - 1) |
323 VIDTCON0_VSPW(var->vsync_len - 1); 507 VIDTCON0_VSPW(var->vsync_len - 1);
324 508
325 writel(data, regs + VIDTCON0); 509 writel(data, regs + sfb->variant.vidtcon);
326 510
327 data = VIDTCON1_HBPD(var->left_margin - 1) | 511 data = VIDTCON1_HBPD(var->left_margin - 1) |
328 VIDTCON1_HFPD(var->right_margin - 1) | 512 VIDTCON1_HFPD(var->right_margin - 1) |
329 VIDTCON1_HSPW(var->hsync_len - 1); 513 VIDTCON1_HSPW(var->hsync_len - 1);
330 514
331 writel(data, regs + VIDTCON1); 515 /* VIDTCON1 */
516 writel(data, regs + sfb->variant.vidtcon + 4);
332 517
333 data = VIDTCON2_LINEVAL(var->yres - 1) | 518 data = VIDTCON2_LINEVAL(var->yres - 1) |
334 VIDTCON2_HOZVAL(var->xres - 1); 519 VIDTCON2_HOZVAL(var->xres - 1);
335 writel(data, regs + VIDTCON2); 520 writel(data, regs +sfb->variant.vidtcon + 8 );
336 } 521 }
337 522
338 /* write the buffer address */ 523 /* write the buffer address */
339 524
340 writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no)); 525 /* start and end registers stride is 8 */
526 buf = regs + win_no * 8;
527
528 writel(info->fix.smem_start, buf + sfb->variant.buf_start);
341 529
342 data = info->fix.smem_start + info->fix.line_length * var->yres; 530 data = info->fix.smem_start + info->fix.line_length * var->yres;
343 writel(data, regs + VIDW_BUF_END(win_no)); 531 writel(data, buf + sfb->variant.buf_end);
344 532
345 pagewidth = (var->xres * var->bits_per_pixel) >> 3; 533 pagewidth = (var->xres * var->bits_per_pixel) >> 3;
346 data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) | 534 data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
347 VIDW_BUF_SIZE_PAGEWIDTH(pagewidth); 535 VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
348 writel(data, regs + VIDW_BUF_SIZE(win_no)); 536 writel(data, regs + sfb->variant.buf_size + (win_no * 4));
349 537
350 /* write 'OSD' registers to control position of framebuffer */ 538 /* write 'OSD' registers to control position of framebuffer */
351 539
352 data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0); 540 data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
353 writel(data, regs + VIDOSD_A(win_no)); 541 writel(data, regs + VIDOSD_A(win_no, sfb->variant));
354 542
355 data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel, 543 data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
356 var->xres - 1)) | 544 var->xres - 1)) |
357 VIDOSDxB_BOTRIGHT_Y(var->yres - 1); 545 VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
358 546
359 writel(data, regs + VIDOSD_B(win_no)); 547 writel(data, regs + VIDOSD_B(win_no, sfb->variant));
360 548
361 data = var->xres * var->yres; 549 data = var->xres * var->yres;
362 550
363 osdc_data = VIDISD14C_ALPHA1_R(0xf) | 551 alpha = VIDISD14C_ALPHA1_R(0xf) |
364 VIDISD14C_ALPHA1_G(0xf) | 552 VIDISD14C_ALPHA1_G(0xf) |
365 VIDISD14C_ALPHA1_B(0xf); 553 VIDISD14C_ALPHA1_B(0xf);
366 554
367 if (s3c_fb_has_osd_d(win_no)) { 555 vidosd_set_alpha(win, alpha);
368 writel(data, regs + VIDOSD_D(win_no)); 556 vidosd_set_size(win, data);
369 writel(osdc_data, regs + VIDOSD_C(win_no));
370 } else
371 writel(data, regs + VIDOSD_C(win_no));
372 557
373 data = WINCONx_ENWIN; 558 data = WINCONx_ENWIN;
374 559
@@ -424,13 +609,15 @@ static int s3c_fb_set_par(struct fb_info *info)
424 else 609 else
425 data |= WINCON0_BPPMODE_24BPP_888; 610 data |= WINCON0_BPPMODE_24BPP_888;
426 611
612 data |= WINCONx_WSWP;
427 data |= WINCONx_BURSTLEN_16WORD; 613 data |= WINCONx_BURSTLEN_16WORD;
428 break; 614 break;
429 } 615 }
430 616
431 /* It has no color key control register for window0 */ 617 /* Enable the colour keying for the window below this one */
432 if (win_no > 0) { 618 if (win_no > 0) {
433 u32 keycon0_data = 0, keycon1_data = 0; 619 u32 keycon0_data = 0, keycon1_data = 0;
620 void __iomem *keycon = regs + sfb->variant.keycon;
434 621
435 keycon0_data = ~(WxKEYCON0_KEYBL_EN | 622 keycon0_data = ~(WxKEYCON0_KEYBL_EN |
436 WxKEYCON0_KEYEN_F | 623 WxKEYCON0_KEYEN_F |
@@ -438,12 +625,23 @@ static int s3c_fb_set_par(struct fb_info *info)
438 625
439 keycon1_data = WxKEYCON1_COLVAL(0xffffff); 626 keycon1_data = WxKEYCON1_COLVAL(0xffffff);
440 627
441 writel(keycon0_data, regs + WxKEYCONy(win_no-1, 0)); 628 keycon += (win_no - 1) * 8;
442 writel(keycon1_data, regs + WxKEYCONy(win_no-1, 1)); 629
630 writel(keycon0_data, keycon + WKEYCON0);
631 writel(keycon1_data, keycon + WKEYCON1);
632 }
633
634 writel(data, regs + sfb->variant.wincon + (win_no * 4));
635 writel(0x0, regs + sfb->variant.winmap + (win_no * 4));
636
637 /* Enable DMA channel for this window */
638 if (sfb->variant.has_shadowcon) {
639 data = readl(sfb->regs + SHADOWCON);
640 data |= SHADOWCON_CHx_ENABLE(win_no);
641 writel(data, sfb->regs + SHADOWCON);
443 } 642 }
444 643
445 writel(data, regs + WINCON(win_no)); 644 shadow_protect_win(win, 0);
446 writel(0x0, regs + WINxMAP(win_no));
447 645
448 return 0; 646 return 0;
449} 647}
@@ -470,7 +668,7 @@ static void s3c_fb_update_palette(struct s3c_fb *sfb,
470 void __iomem *palreg; 668 void __iomem *palreg;
471 u32 palcon; 669 u32 palcon;
472 670
473 palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg); 671 palreg = sfb->regs + sfb->variant.palette[win->index];
474 672
475 dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n", 673 dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n",
476 __func__, win->index, reg, palreg, value); 674 __func__, win->index, reg, palreg, value);
@@ -480,10 +678,10 @@ static void s3c_fb_update_palette(struct s3c_fb *sfb,
480 palcon = readl(sfb->regs + WPALCON); 678 palcon = readl(sfb->regs + WPALCON);
481 writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON); 679 writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON);
482 680
483 if (s3c_fb_pal_is16(win->index)) 681 if (win->variant.palette_16bpp)
484 writew(value, palreg); 682 writew(value, palreg + (reg * 2));
485 else 683 else
486 writel(value, palreg); 684 writel(value, palreg + (reg * 4));
487 685
488 writel(palcon, sfb->regs + WPALCON); 686 writel(palcon, sfb->regs + WPALCON);
489} 687}
@@ -532,7 +730,7 @@ static int s3c_fb_setcolreg(unsigned regno,
532 break; 730 break;
533 731
534 case FB_VISUAL_PSEUDOCOLOR: 732 case FB_VISUAL_PSEUDOCOLOR:
535 if (regno < s3c_fb_win_pal_size(win->index)) { 733 if (regno < win->variant.palette_sz) {
536 val = chan_to_field(red, &win->palette.r); 734 val = chan_to_field(red, &win->palette.r);
537 val |= chan_to_field(green, &win->palette.g); 735 val |= chan_to_field(green, &win->palette.g);
538 val |= chan_to_field(blue, &win->palette.b); 736 val |= chan_to_field(blue, &win->palette.b);
@@ -591,7 +789,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
591 789
592 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); 790 dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
593 791
594 wincon = readl(sfb->regs + WINCON(index)); 792 wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4));
595 793
596 switch (blank_mode) { 794 switch (blank_mode) {
597 case FB_BLANK_POWERDOWN: 795 case FB_BLANK_POWERDOWN:
@@ -602,11 +800,11 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
602 case FB_BLANK_NORMAL: 800 case FB_BLANK_NORMAL:
603 /* disable the DMA and display 0x0 (black) */ 801 /* disable the DMA and display 0x0 (black) */
604 writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0), 802 writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
605 sfb->regs + WINxMAP(index)); 803 sfb->regs + sfb->variant.winmap + (index * 4));
606 break; 804 break;
607 805
608 case FB_BLANK_UNBLANK: 806 case FB_BLANK_UNBLANK:
609 writel(0x0, sfb->regs + WINxMAP(index)); 807 writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4));
610 wincon |= WINCONx_ENWIN; 808 wincon |= WINCONx_ENWIN;
611 sfb->enabled |= (1 << index); 809 sfb->enabled |= (1 << index);
612 break; 810 break;
@@ -617,7 +815,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
617 return 1; 815 return 1;
618 } 816 }
619 817
620 writel(wincon, sfb->regs + WINCON(index)); 818 writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4));
621 819
622 /* Check the enabled state to see if we need to be running the 820 /* Check the enabled state to see if we need to be running the
623 * main LCD interface, as if there are no active windows then 821 * main LCD interface, as if there are no active windows then
@@ -636,12 +834,185 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
636 /* we're stuck with this until we can do something about overriding 834 /* we're stuck with this until we can do something about overriding
637 * the power control using the blanking event for a single fb. 835 * the power control using the blanking event for a single fb.
638 */ 836 */
639 if (index == 0) 837 if (index == sfb->pdata->default_win)
640 s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); 838 s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0);
641 839
642 return 0; 840 return 0;
643} 841}
644 842
843/**
844 * s3c_fb_pan_display() - Pan the display.
845 *
846 * Note that the offsets can be written to the device at any time, as their
847 * values are latched at each vsync automatically. This also means that only
848 * the last call to this function will have any effect on next vsync, but
849 * there is no need to sleep waiting for it to prevent tearing.
850 *
851 * @var: The screen information to verify.
852 * @info: The framebuffer device.
853 */
854static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
855 struct fb_info *info)
856{
857 struct s3c_fb_win *win = info->par;
858 struct s3c_fb *sfb = win->parent;
859 void __iomem *buf = sfb->regs + win->index * 8;
860 unsigned int start_boff, end_boff;
861
862 /* Offset in bytes to the start of the displayed area */
863 start_boff = var->yoffset * info->fix.line_length;
864 /* X offset depends on the current bpp */
865 if (info->var.bits_per_pixel >= 8) {
866 start_boff += var->xoffset * (info->var.bits_per_pixel >> 3);
867 } else {
868 switch (info->var.bits_per_pixel) {
869 case 4:
870 start_boff += var->xoffset >> 1;
871 break;
872 case 2:
873 start_boff += var->xoffset >> 2;
874 break;
875 case 1:
876 start_boff += var->xoffset >> 3;
877 break;
878 default:
879 dev_err(sfb->dev, "invalid bpp\n");
880 return -EINVAL;
881 }
882 }
883 /* Offset in bytes to the end of the displayed area */
884 end_boff = start_boff + var->yres * info->fix.line_length;
885
886 /* Temporarily turn off per-vsync update from shadow registers until
887 * both start and end addresses are updated to prevent corruption */
888 shadow_protect_win(win, 1);
889
890 writel(info->fix.smem_start + start_boff, buf + sfb->variant.buf_start);
891 writel(info->fix.smem_start + end_boff, buf + sfb->variant.buf_end);
892
893 shadow_protect_win(win, 0);
894
895 return 0;
896}
897
898/**
899 * s3c_fb_enable_irq() - enable framebuffer interrupts
900 * @sfb: main hardware state
901 */
902static void s3c_fb_enable_irq(struct s3c_fb *sfb)
903{
904 void __iomem *regs = sfb->regs;
905 u32 irq_ctrl_reg;
906
907 if (!test_and_set_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) {
908 /* IRQ disabled, enable it */
909 irq_ctrl_reg = readl(regs + VIDINTCON0);
910
911 irq_ctrl_reg |= VIDINTCON0_INT_ENABLE;
912 irq_ctrl_reg |= VIDINTCON0_INT_FRAME;
913
914 irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL0_MASK;
915 irq_ctrl_reg |= VIDINTCON0_FRAMESEL0_VSYNC;
916 irq_ctrl_reg &= ~VIDINTCON0_FRAMESEL1_MASK;
917 irq_ctrl_reg |= VIDINTCON0_FRAMESEL1_NONE;
918
919 writel(irq_ctrl_reg, regs + VIDINTCON0);
920 }
921}
922
923/**
924 * s3c_fb_disable_irq() - disable framebuffer interrupts
925 * @sfb: main hardware state
926 */
927static void s3c_fb_disable_irq(struct s3c_fb *sfb)
928{
929 void __iomem *regs = sfb->regs;
930 u32 irq_ctrl_reg;
931
932 if (test_and_clear_bit(S3C_FB_VSYNC_IRQ_EN, &sfb->irq_flags)) {
933 /* IRQ enabled, disable it */
934 irq_ctrl_reg = readl(regs + VIDINTCON0);
935
936 irq_ctrl_reg &= ~VIDINTCON0_INT_FRAME;
937 irq_ctrl_reg &= ~VIDINTCON0_INT_ENABLE;
938
939 writel(irq_ctrl_reg, regs + VIDINTCON0);
940 }
941}
942
943static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
944{
945 struct s3c_fb *sfb = dev_id;
946 void __iomem *regs = sfb->regs;
947 u32 irq_sts_reg;
948
949 irq_sts_reg = readl(regs + VIDINTCON1);
950
951 if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
952
953 /* VSYNC interrupt, accept it */
954 writel(VIDINTCON1_INT_FRAME, regs + VIDINTCON1);
955
956 sfb->vsync_info.count++;
957 wake_up_interruptible(&sfb->vsync_info.wait);
958 }
959
960 /* We only support waiting for VSYNC for now, so it's safe
961 * to always disable irqs here.
962 */
963 s3c_fb_disable_irq(sfb);
964
965 return IRQ_HANDLED;
966}
967
968/**
969 * s3c_fb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout
970 * @sfb: main hardware state
971 * @crtc: head index.
972 */
973static int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc)
974{
975 unsigned long count;
976 int ret;
977
978 if (crtc != 0)
979 return -ENODEV;
980
981 count = sfb->vsync_info.count;
982 s3c_fb_enable_irq(sfb);
983 ret = wait_event_interruptible_timeout(sfb->vsync_info.wait,
984 count != sfb->vsync_info.count,
985 msecs_to_jiffies(VSYNC_TIMEOUT_MSEC));
986 if (ret == 0)
987 return -ETIMEDOUT;
988
989 return 0;
990}
991
992static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd,
993 unsigned long arg)
994{
995 struct s3c_fb_win *win = info->par;
996 struct s3c_fb *sfb = win->parent;
997 int ret;
998 u32 crtc;
999
1000 switch (cmd) {
1001 case FBIO_WAITFORVSYNC:
1002 if (get_user(crtc, (u32 __user *)arg)) {
1003 ret = -EFAULT;
1004 break;
1005 }
1006
1007 ret = s3c_fb_wait_for_vsync(sfb, crtc);
1008 break;
1009 default:
1010 ret = -ENOTTY;
1011 }
1012
1013 return ret;
1014}
1015
645static struct fb_ops s3c_fb_ops = { 1016static struct fb_ops s3c_fb_ops = {
646 .owner = THIS_MODULE, 1017 .owner = THIS_MODULE,
647 .fb_check_var = s3c_fb_check_var, 1018 .fb_check_var = s3c_fb_check_var,
@@ -651,9 +1022,33 @@ static struct fb_ops s3c_fb_ops = {
651 .fb_fillrect = cfb_fillrect, 1022 .fb_fillrect = cfb_fillrect,
652 .fb_copyarea = cfb_copyarea, 1023 .fb_copyarea = cfb_copyarea,
653 .fb_imageblit = cfb_imageblit, 1024 .fb_imageblit = cfb_imageblit,
1025 .fb_pan_display = s3c_fb_pan_display,
1026 .fb_ioctl = s3c_fb_ioctl,
654}; 1027};
655 1028
656/** 1029/**
1030 * s3c_fb_missing_pixclock() - calculates pixel clock
1031 * @mode: The video mode to change.
1032 *
1033 * Calculate the pixel clock when none has been given through platform data.
1034 */
1035static void __devinit s3c_fb_missing_pixclock(struct fb_videomode *mode)
1036{
1037 u64 pixclk = 1000000000000ULL;
1038 u32 div;
1039
1040 div = mode->left_margin + mode->hsync_len + mode->right_margin +
1041 mode->xres;
1042 div *= mode->upper_margin + mode->vsync_len + mode->lower_margin +
1043 mode->yres;
1044 div *= mode->refresh ? : 60;
1045
1046 do_div(pixclk, div);
1047
1048 mode->pixclock = pixclk;
1049}
1050
1051/**
657 * s3c_fb_alloc_memory() - allocate display memory for framebuffer window 1052 * s3c_fb_alloc_memory() - allocate display memory for framebuffer window
658 * @sfb: The base resources for the hardware. 1053 * @sfb: The base resources for the hardware.
659 * @win: The window to initialise memory for. 1054 * @win: The window to initialise memory for.
@@ -711,7 +1106,8 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
711{ 1106{
712 struct fb_info *fbi = win->fbinfo; 1107 struct fb_info *fbi = win->fbinfo;
713 1108
714 dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), 1109 if (fbi->screen_base)
1110 dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
715 fbi->screen_base, fbi->fix.smem_start); 1111 fbi->screen_base, fbi->fix.smem_start);
716} 1112}
717 1113
@@ -724,9 +1120,18 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
724 */ 1120 */
725static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) 1121static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
726{ 1122{
1123 u32 data;
1124
727 if (win->fbinfo) { 1125 if (win->fbinfo) {
1126 if (sfb->variant.has_shadowcon) {
1127 data = readl(sfb->regs + SHADOWCON);
1128 data &= ~SHADOWCON_CHx_ENABLE(win->index);
1129 data &= ~SHADOWCON_CHx_LOCAL_ENABLE(win->index);
1130 writel(data, sfb->regs + SHADOWCON);
1131 }
728 unregister_framebuffer(win->fbinfo); 1132 unregister_framebuffer(win->fbinfo);
729 fb_dealloc_cmap(&win->fbinfo->cmap); 1133 if (win->fbinfo->cmap.len)
1134 fb_dealloc_cmap(&win->fbinfo->cmap);
730 s3c_fb_free_memory(sfb, win); 1135 s3c_fb_free_memory(sfb, win);
731 framebuffer_release(win->fbinfo); 1136 framebuffer_release(win->fbinfo);
732 } 1137 }
@@ -735,12 +1140,14 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
735/** 1140/**
736 * s3c_fb_probe_win() - register an hardware window 1141 * s3c_fb_probe_win() - register an hardware window
737 * @sfb: The base resources for the hardware 1142 * @sfb: The base resources for the hardware
1143 * @variant: The variant information for this window.
738 * @res: Pointer to where to place the resultant window. 1144 * @res: Pointer to where to place the resultant window.
739 * 1145 *
740 * Allocate and do the basic initialisation for one of the hardware's graphics 1146 * Allocate and do the basic initialisation for one of the hardware's graphics
741 * windows. 1147 * windows.
742 */ 1148 */
743static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, 1149static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
1150 struct s3c_fb_win_variant *variant,
744 struct s3c_fb_win **res) 1151 struct s3c_fb_win **res)
745{ 1152{
746 struct fb_var_screeninfo *var; 1153 struct fb_var_screeninfo *var;
@@ -751,9 +1158,11 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
751 int palette_size; 1158 int palette_size;
752 int ret; 1159 int ret;
753 1160
754 dev_dbg(sfb->dev, "probing window %d\n", win_no); 1161 dev_dbg(sfb->dev, "probing window %d, variant %p\n", win_no, variant);
1162
1163 init_waitqueue_head(&sfb->vsync_info.wait);
755 1164
756 palette_size = s3c_fb_win_pal_size(win_no); 1165 palette_size = variant->palette_sz * 4;
757 1166
758 fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + 1167 fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
759 palette_size * sizeof(u32), sfb->dev); 1168 palette_size * sizeof(u32), sfb->dev);
@@ -770,7 +1179,9 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
770 WARN_ON(windata->win_mode.yres == 0); 1179 WARN_ON(windata->win_mode.yres == 0);
771 1180
772 win = fbinfo->par; 1181 win = fbinfo->par;
1182 *res = win;
773 var = &fbinfo->var; 1183 var = &fbinfo->var;
1184 win->variant = *variant;
774 win->fbinfo = fbinfo; 1185 win->fbinfo = fbinfo;
775 win->parent = sfb; 1186 win->parent = sfb;
776 win->windata = windata; 1187 win->windata = windata;
@@ -784,7 +1195,24 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
784 } 1195 }
785 1196
786 /* setup the r/b/g positions for the window's palette */ 1197 /* setup the r/b/g positions for the window's palette */
787 s3c_fb_init_palette(win_no, &win->palette); 1198 if (win->variant.palette_16bpp) {
1199 /* Set RGB 5:6:5 as default */
1200 win->palette.r.offset = 11;
1201 win->palette.r.length = 5;
1202 win->palette.g.offset = 5;
1203 win->palette.g.length = 6;
1204 win->palette.b.offset = 0;
1205 win->palette.b.length = 5;
1206
1207 } else {
1208 /* Set 8bpp or 8bpp and 1bit alpha */
1209 win->palette.r.offset = 16;
1210 win->palette.r.length = 8;
1211 win->palette.g.offset = 8;
1212 win->palette.g.length = 8;
1213 win->palette.b.offset = 0;
1214 win->palette.b.length = 8;
1215 }
788 1216
789 /* setup the initial video mode from the window */ 1217 /* setup the initial video mode from the window */
790 fb_videomode_to_var(&fbinfo->var, initmode); 1218 fb_videomode_to_var(&fbinfo->var, initmode);
@@ -808,7 +1236,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
808 1236
809 /* create initial colour map */ 1237 /* create initial colour map */
810 1238
811 ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1); 1239 ret = fb_alloc_cmap(&fbinfo->cmap, win->variant.palette_sz, 1);
812 if (ret == 0) 1240 if (ret == 0)
813 fb_set_cmap(&fbinfo->cmap, fbinfo); 1241 fb_set_cmap(&fbinfo->cmap, fbinfo);
814 else 1242 else
@@ -826,7 +1254,6 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
826 return ret; 1254 return ret;
827 } 1255 }
828 1256
829 *res = win;
830 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); 1257 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);
831 1258
832 return 0; 1259 return 0;
@@ -842,18 +1269,19 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
842static void s3c_fb_clear_win(struct s3c_fb *sfb, int win) 1269static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
843{ 1270{
844 void __iomem *regs = sfb->regs; 1271 void __iomem *regs = sfb->regs;
845 1272 u32 reg;
846 writel(0, regs + WINCON(win)); 1273
847 writel(0xffffff, regs + WxKEYCONy(win, 0)); 1274 writel(0, regs + sfb->variant.wincon + (win * 4));
848 writel(0xffffff, regs + WxKEYCONy(win, 1)); 1275 writel(0, regs + VIDOSD_A(win, sfb->variant));
849 1276 writel(0, regs + VIDOSD_B(win, sfb->variant));
850 writel(0, regs + VIDOSD_A(win)); 1277 writel(0, regs + VIDOSD_C(win, sfb->variant));
851 writel(0, regs + VIDOSD_B(win)); 1278 reg = readl(regs + SHADOWCON);
852 writel(0, regs + VIDOSD_C(win)); 1279 writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON);
853} 1280}
854 1281
855static int __devinit s3c_fb_probe(struct platform_device *pdev) 1282static int __devinit s3c_fb_probe(struct platform_device *pdev)
856{ 1283{
1284 struct s3c_fb_driverdata *fbdrv;
857 struct device *dev = &pdev->dev; 1285 struct device *dev = &pdev->dev;
858 struct s3c_fb_platdata *pd; 1286 struct s3c_fb_platdata *pd;
859 struct s3c_fb *sfb; 1287 struct s3c_fb *sfb;
@@ -861,6 +1289,13 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
861 int win; 1289 int win;
862 int ret = 0; 1290 int ret = 0;
863 1291
1292 fbdrv = (struct s3c_fb_driverdata *)platform_get_device_id(pdev)->driver_data;
1293
1294 if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) {
1295 dev_err(dev, "too many windows, cannot attach\n");
1296 return -EINVAL;
1297 }
1298
864 pd = pdev->dev.platform_data; 1299 pd = pdev->dev.platform_data;
865 if (!pd) { 1300 if (!pd) {
866 dev_err(dev, "no platform data specified\n"); 1301 dev_err(dev, "no platform data specified\n");
@@ -873,8 +1308,11 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
873 return -ENOMEM; 1308 return -ENOMEM;
874 } 1309 }
875 1310
1311 dev_dbg(dev, "allocate new framebuffer %p\n", sfb);
1312
876 sfb->dev = dev; 1313 sfb->dev = dev;
877 sfb->pdata = pd; 1314 sfb->pdata = pd;
1315 sfb->variant = fbdrv->variant;
878 1316
879 sfb->bus_clk = clk_get(dev, "lcd"); 1317 sfb->bus_clk = clk_get(dev, "lcd");
880 if (IS_ERR(sfb->bus_clk)) { 1318 if (IS_ERR(sfb->bus_clk)) {
@@ -906,6 +1344,20 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
906 goto err_req_region; 1344 goto err_req_region;
907 } 1345 }
908 1346
1347 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1348 if (!res) {
1349 dev_err(dev, "failed to acquire irq resource\n");
1350 ret = -ENOENT;
1351 goto err_ioremap;
1352 }
1353 sfb->irq_no = res->start;
1354 ret = request_irq(sfb->irq_no, s3c_fb_irq,
1355 0, "s3c_fb", sfb);
1356 if (ret) {
1357 dev_err(dev, "irq request failed\n");
1358 goto err_ioremap;
1359 }
1360
909 dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); 1361 dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
910 1362
911 /* setup gpio and output polarity controls */ 1363 /* setup gpio and output polarity controls */
@@ -916,21 +1368,34 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
916 1368
917 /* zero all windows before we do anything */ 1369 /* zero all windows before we do anything */
918 1370
919 for (win = 0; win < S3C_FB_MAX_WIN; win++) 1371 for (win = 0; win < fbdrv->variant.nr_windows; win++)
920 s3c_fb_clear_win(sfb, win); 1372 s3c_fb_clear_win(sfb, win);
921 1373
1374 /* initialise colour key controls */
1375 for (win = 0; win < (fbdrv->variant.nr_windows - 1); win++) {
1376 void __iomem *regs = sfb->regs + sfb->variant.keycon;
1377
1378 regs += (win * 8);
1379 writel(0xffffff, regs + WKEYCON0);
1380 writel(0xffffff, regs + WKEYCON1);
1381 }
1382
922 /* we have the register setup, start allocating framebuffers */ 1383 /* we have the register setup, start allocating framebuffers */
923 1384
924 for (win = 0; win < S3C_FB_MAX_WIN; win++) { 1385 for (win = 0; win < fbdrv->variant.nr_windows; win++) {
925 if (!pd->win[win]) 1386 if (!pd->win[win])
926 continue; 1387 continue;
927 1388
928 ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]); 1389 if (!pd->win[win]->win_mode.pixclock)
1390 s3c_fb_missing_pixclock(&pd->win[win]->win_mode);
1391
1392 ret = s3c_fb_probe_win(sfb, win, fbdrv->win[win],
1393 &sfb->windows[win]);
929 if (ret < 0) { 1394 if (ret < 0) {
930 dev_err(dev, "failed to create window %d\n", win); 1395 dev_err(dev, "failed to create window %d\n", win);
931 for (; win >= 0; win--) 1396 for (; win >= 0; win--)
932 s3c_fb_release_win(sfb, sfb->windows[win]); 1397 s3c_fb_release_win(sfb, sfb->windows[win]);
933 goto err_ioremap; 1398 goto err_irq;
934 } 1399 }
935 } 1400 }
936 1401
@@ -938,6 +1403,9 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
938 1403
939 return 0; 1404 return 0;
940 1405
1406err_irq:
1407 free_irq(sfb->irq_no, sfb);
1408
941err_ioremap: 1409err_ioremap:
942 iounmap(sfb->regs); 1410 iounmap(sfb->regs);
943 1411
@@ -970,6 +1438,8 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
970 if (sfb->windows[win]) 1438 if (sfb->windows[win])
971 s3c_fb_release_win(sfb, sfb->windows[win]); 1439 s3c_fb_release_win(sfb, sfb->windows[win]);
972 1440
1441 free_irq(sfb->irq_no, sfb);
1442
973 iounmap(sfb->regs); 1443 iounmap(sfb->regs);
974 1444
975 clk_disable(sfb->bus_clk); 1445 clk_disable(sfb->bus_clk);
@@ -1016,9 +1486,17 @@ static int s3c_fb_resume(struct platform_device *pdev)
1016 writel(pd->vidcon1, sfb->regs + VIDCON1); 1486 writel(pd->vidcon1, sfb->regs + VIDCON1);
1017 1487
1018 /* zero all windows before we do anything */ 1488 /* zero all windows before we do anything */
1019 for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) 1489 for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++)
1020 s3c_fb_clear_win(sfb, win_no); 1490 s3c_fb_clear_win(sfb, win_no);
1021 1491
1492 for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) {
1493 void __iomem *regs = sfb->regs + sfb->variant.keycon;
1494
1495 regs += (win_no * 8);
1496 writel(0xffffff, regs + WKEYCON0);
1497 writel(0xffffff, regs + WKEYCON1);
1498 }
1499
1022 /* restore framebuffers */ 1500 /* restore framebuffers */
1023 for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { 1501 for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
1024 win = sfb->windows[win_no]; 1502 win = sfb->windows[win_no];
@@ -1036,11 +1514,208 @@ static int s3c_fb_resume(struct platform_device *pdev)
1036#define s3c_fb_resume NULL 1514#define s3c_fb_resume NULL
1037#endif 1515#endif
1038 1516
1517
1518#define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4))
1519#define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8))
1520
1521static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = {
1522 [0] = {
1523 .has_osd_c = 1,
1524 .osd_size_off = 0x8,
1525 .palette_sz = 256,
1526 .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24),
1527 },
1528 [1] = {
1529 .has_osd_c = 1,
1530 .has_osd_d = 1,
1531 .osd_size_off = 0x12,
1532 .has_osd_alpha = 1,
1533 .palette_sz = 256,
1534 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1535 VALID_BPP(18) | VALID_BPP(19) |
1536 VALID_BPP(24) | VALID_BPP(25)),
1537 },
1538 [2] = {
1539 .has_osd_c = 1,
1540 .has_osd_d = 1,
1541 .osd_size_off = 0x12,
1542 .has_osd_alpha = 1,
1543 .palette_sz = 16,
1544 .palette_16bpp = 1,
1545 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1546 VALID_BPP(18) | VALID_BPP(19) |
1547 VALID_BPP(24) | VALID_BPP(25)),
1548 },
1549 [3] = {
1550 .has_osd_c = 1,
1551 .has_osd_alpha = 1,
1552 .palette_sz = 16,
1553 .palette_16bpp = 1,
1554 .valid_bpp = (VALID_BPP124 | VALID_BPP(16) |
1555 VALID_BPP(18) | VALID_BPP(19) |
1556 VALID_BPP(24) | VALID_BPP(25)),
1557 },
1558 [4] = {
1559 .has_osd_c = 1,
1560 .has_osd_alpha = 1,
1561 .palette_sz = 4,
1562 .palette_16bpp = 1,
1563 .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) |
1564 VALID_BPP(16) | VALID_BPP(18) |
1565 VALID_BPP(24) | VALID_BPP(25)),
1566 },
1567};
1568
1569static struct s3c_fb_driverdata s3c_fb_data_64xx = {
1570 .variant = {
1571 .nr_windows = 5,
1572 .vidtcon = VIDTCON0,
1573 .wincon = WINCON(0),
1574 .winmap = WINxMAP(0),
1575 .keycon = WKEYCON,
1576 .osd = VIDOSD_BASE,
1577 .osd_stride = 16,
1578 .buf_start = VIDW_BUF_START(0),
1579 .buf_size = VIDW_BUF_SIZE(0),
1580 .buf_end = VIDW_BUF_END(0),
1581
1582 .palette = {
1583 [0] = 0x400,
1584 [1] = 0x800,
1585 [2] = 0x300,
1586 [3] = 0x320,
1587 [4] = 0x340,
1588 },
1589
1590 .has_prtcon = 1,
1591 },
1592 .win[0] = &s3c_fb_data_64xx_wins[0],
1593 .win[1] = &s3c_fb_data_64xx_wins[1],
1594 .win[2] = &s3c_fb_data_64xx_wins[2],
1595 .win[3] = &s3c_fb_data_64xx_wins[3],
1596 .win[4] = &s3c_fb_data_64xx_wins[4],
1597};
1598
1599static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
1600 .variant = {
1601 .nr_windows = 5,
1602 .vidtcon = VIDTCON0,
1603 .wincon = WINCON(0),
1604 .winmap = WINxMAP(0),
1605 .keycon = WKEYCON,
1606 .osd = VIDOSD_BASE,
1607 .osd_stride = 16,
1608 .buf_start = VIDW_BUF_START(0),
1609 .buf_size = VIDW_BUF_SIZE(0),
1610 .buf_end = VIDW_BUF_END(0),
1611
1612 .palette = {
1613 [0] = 0x2400,
1614 [1] = 0x2800,
1615 [2] = 0x2c00,
1616 [3] = 0x3000,
1617 [4] = 0x3400,
1618 },
1619
1620 .has_prtcon = 1,
1621 },
1622 .win[0] = &s3c_fb_data_64xx_wins[0],
1623 .win[1] = &s3c_fb_data_64xx_wins[1],
1624 .win[2] = &s3c_fb_data_64xx_wins[2],
1625 .win[3] = &s3c_fb_data_64xx_wins[3],
1626 .win[4] = &s3c_fb_data_64xx_wins[4],
1627};
1628
1629static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
1630 .variant = {
1631 .nr_windows = 5,
1632 .vidtcon = VIDTCON0,
1633 .wincon = WINCON(0),
1634 .winmap = WINxMAP(0),
1635 .keycon = WKEYCON,
1636 .osd = VIDOSD_BASE,
1637 .osd_stride = 16,
1638 .buf_start = VIDW_BUF_START(0),
1639 .buf_size = VIDW_BUF_SIZE(0),
1640 .buf_end = VIDW_BUF_END(0),
1641
1642 .palette = {
1643 [0] = 0x2400,
1644 [1] = 0x2800,
1645 [2] = 0x2c00,
1646 [3] = 0x3000,
1647 [4] = 0x3400,
1648 },
1649
1650 .has_shadowcon = 1,
1651 },
1652 .win[0] = &s3c_fb_data_64xx_wins[0],
1653 .win[1] = &s3c_fb_data_64xx_wins[1],
1654 .win[2] = &s3c_fb_data_64xx_wins[2],
1655 .win[3] = &s3c_fb_data_64xx_wins[3],
1656 .win[4] = &s3c_fb_data_64xx_wins[4],
1657};
1658
1659/* S3C2443/S3C2416 style hardware */
1660static struct s3c_fb_driverdata s3c_fb_data_s3c2443 = {
1661 .variant = {
1662 .nr_windows = 2,
1663 .is_2443 = 1,
1664
1665 .vidtcon = 0x08,
1666 .wincon = 0x14,
1667 .winmap = 0xd0,
1668 .keycon = 0xb0,
1669 .osd = 0x28,
1670 .osd_stride = 12,
1671 .buf_start = 0x64,
1672 .buf_size = 0x94,
1673 .buf_end = 0x7c,
1674
1675 .palette = {
1676 [0] = 0x400,
1677 [1] = 0x800,
1678 },
1679 },
1680 .win[0] = &(struct s3c_fb_win_variant) {
1681 .palette_sz = 256,
1682 .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24),
1683 },
1684 .win[1] = &(struct s3c_fb_win_variant) {
1685 .has_osd_c = 1,
1686 .has_osd_alpha = 1,
1687 .palette_sz = 256,
1688 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1689 VALID_BPP(18) | VALID_BPP(19) |
1690 VALID_BPP(24) | VALID_BPP(25) |
1691 VALID_BPP(28)),
1692 },
1693};
1694
1695static struct platform_device_id s3c_fb_driver_ids[] = {
1696 {
1697 .name = "s3c-fb",
1698 .driver_data = (unsigned long)&s3c_fb_data_64xx,
1699 }, {
1700 .name = "s5pc100-fb",
1701 .driver_data = (unsigned long)&s3c_fb_data_s5pc100,
1702 }, {
1703 .name = "s5pv210-fb",
1704 .driver_data = (unsigned long)&s3c_fb_data_s5pv210,
1705 }, {
1706 .name = "s3c2443-fb",
1707 .driver_data = (unsigned long)&s3c_fb_data_s3c2443,
1708 },
1709 {},
1710};
1711MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids);
1712
1039static struct platform_driver s3c_fb_driver = { 1713static struct platform_driver s3c_fb_driver = {
1040 .probe = s3c_fb_probe, 1714 .probe = s3c_fb_probe,
1041 .remove = __devexit_p(s3c_fb_remove), 1715 .remove = __devexit_p(s3c_fb_remove),
1042 .suspend = s3c_fb_suspend, 1716 .suspend = s3c_fb_suspend,
1043 .resume = s3c_fb_resume, 1717 .resume = s3c_fb_resume,
1718 .id_table = s3c_fb_driver_ids,
1044 .driver = { 1719 .driver = {
1045 .name = "s3c-fb", 1720 .name = "s3c-fb",
1046 .owner = THIS_MODULE, 1721 .owner = THIS_MODULE,
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
new file mode 100644
index 000000000000..5699ce0c1780
--- /dev/null
+++ b/drivers/video/sh_mipi_dsi.c
@@ -0,0 +1,505 @@
1/*
2 * Renesas SH-mobile MIPI DSI support
3 *
4 * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/clk.h>
12#include <linux/delay.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/string.h>
18#include <linux/types.h>
19
20#include <video/mipi_display.h>
21#include <video/sh_mipi_dsi.h>
22#include <video/sh_mobile_lcdc.h>
23
24#define CMTSRTCTR 0x80d0
25#define CMTSRTREQ 0x8070
26
27#define DSIINTE 0x0060
28
29/* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */
30#define MAX_SH_MIPI_DSI 2
31
32struct sh_mipi {
33 void __iomem *base;
34 struct clk *dsit_clk;
35 struct clk *dsip_clk;
36};
37
38static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
39
40/* Protect the above array */
41static DEFINE_MUTEX(array_lock);
42
43static struct sh_mipi *sh_mipi_by_handle(int handle)
44{
45 if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0)
46 return NULL;
47
48 return mipi_dsi[handle];
49}
50
51static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd,
52 u8 cmd, u8 param)
53{
54 u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8);
55 int cnt = 100;
56
57 /* transmit a short packet to LCD panel */
58 iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */
59 iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */
60
61 while ((ioread32(mipi->base + 0x8070) & 1) && --cnt)
62 udelay(1);
63
64 return cnt ? 0 : -ETIMEDOUT;
65}
66
67#define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \
68 -EINVAL : (c) - 1)
69
70static int sh_mipi_dcs(int handle, u8 cmd)
71{
72 struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
73 if (!mipi)
74 return -ENODEV;
75 return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
76}
77
78static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param)
79{
80 struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
81 if (!mipi)
82 return -ENODEV;
83 return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd,
84 param);
85}
86
87static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
88{
89 /*
90 * enable LCDC data tx, transition to LPS after completion of each HS
91 * packet
92 */
93 iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */
94}
95
96static void sh_mipi_shutdown(struct platform_device *pdev)
97{
98 struct sh_mipi *mipi = platform_get_drvdata(pdev);
99
100 sh_mipi_dsi_enable(mipi, false);
101}
102
103static void mipi_display_on(void *arg, struct fb_info *info)
104{
105 struct sh_mipi *mipi = arg;
106
107 sh_mipi_dsi_enable(mipi, true);
108}
109
110static void mipi_display_off(void *arg)
111{
112 struct sh_mipi *mipi = arg;
113
114 sh_mipi_dsi_enable(mipi, false);
115}
116
117static int __init sh_mipi_setup(struct sh_mipi *mipi,
118 struct sh_mipi_dsi_info *pdata)
119{
120 void __iomem *base = mipi->base;
121 struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
122 u32 pctype, datatype, pixfmt;
123 u32 linelength;
124 bool yuv;
125
126 /* Select data format */
127 switch (pdata->data_format) {
128 case MIPI_RGB888:
129 pctype = 0;
130 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
131 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
132 linelength = ch->lcd_cfg.xres * 3;
133 yuv = false;
134 break;
135 case MIPI_RGB565:
136 pctype = 1;
137 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
138 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
139 linelength = ch->lcd_cfg.xres * 2;
140 yuv = false;
141 break;
142 case MIPI_RGB666_LP:
143 pctype = 2;
144 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
145 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
146 linelength = ch->lcd_cfg.xres * 3;
147 yuv = false;
148 break;
149 case MIPI_RGB666:
150 pctype = 3;
151 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
152 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
153 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
154 yuv = false;
155 break;
156 case MIPI_BGR888:
157 pctype = 8;
158 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
159 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
160 linelength = ch->lcd_cfg.xres * 3;
161 yuv = false;
162 break;
163 case MIPI_BGR565:
164 pctype = 9;
165 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
166 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
167 linelength = ch->lcd_cfg.xres * 2;
168 yuv = false;
169 break;
170 case MIPI_BGR666_LP:
171 pctype = 0xa;
172 datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
173 pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
174 linelength = ch->lcd_cfg.xres * 3;
175 yuv = false;
176 break;
177 case MIPI_BGR666:
178 pctype = 0xb;
179 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
180 pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
181 linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
182 yuv = false;
183 break;
184 case MIPI_YUYV:
185 pctype = 4;
186 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
187 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
188 linelength = ch->lcd_cfg.xres * 2;
189 yuv = true;
190 break;
191 case MIPI_UYVY:
192 pctype = 5;
193 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
194 pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
195 linelength = ch->lcd_cfg.xres * 2;
196 yuv = true;
197 break;
198 case MIPI_YUV420_L:
199 pctype = 6;
200 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
201 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
202 linelength = (ch->lcd_cfg.xres * 12 + 7) / 8;
203 yuv = true;
204 break;
205 case MIPI_YUV420:
206 pctype = 7;
207 datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
208 pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
209 /* Length of U/V line */
210 linelength = (ch->lcd_cfg.xres + 1) / 2;
211 yuv = true;
212 break;
213 default:
214 return -EINVAL;
215 }
216
217 if ((yuv && ch->interface_type != YUV422) ||
218 (!yuv && ch->interface_type != RGB24))
219 return -EINVAL;
220
221 /* reset DSI link */
222 iowrite32(0x00000001, base); /* SYSCTRL */
223 /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
224 udelay(50);
225 iowrite32(0x00000000, base); /* SYSCTRL */
226
227 /* setup DSI link */
228
229 /*
230 * Default = ULPS enable |
231 * Contention detection enabled |
232 * EoT packet transmission enable |
233 * CRC check enable |
234 * ECC check enable
235 * additionally enable first two lanes
236 */
237 iowrite32(0x00003703, base + 0x04); /* SYSCONF */
238 /*
239 * T_wakeup = 0x7000
240 * T_hs-trail = 3
241 * T_hs-prepare = 3
242 * T_clk-trail = 3
243 * T_clk-prepare = 2
244 */
245 iowrite32(0x70003332, base + 0x08); /* TIMSET */
246 /* no responses requested */
247 iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */
248 /* request response to packets of type 0x28 */
249 iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */
250 /* High-speed transmission timeout, default 0xffffffff */
251 iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */
252 /* LP reception timeout, default 0xffffffff */
253 iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */
254 /* Turn-around timeout, default 0xffffffff */
255 iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */
256 /* Peripheral reset timeout, default 0xffffffff */
257 iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */
258 /* Enable timeout counters */
259 iowrite32(0x00000f00, base + 0x30); /* DSICTRL */
260 /* Interrupts not used, disable all */
261 iowrite32(0, base + DSIINTE);
262 /* DSI-Tx bias on */
263 iowrite32(0x00000001, base + 0x70); /* PHYCTRL */
264 udelay(200);
265 /* Deassert resets, power on, set multiplier */
266 iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */
267
268 /* setup l-bridge */
269
270 /*
271 * Enable transmission of all packets,
272 * transmit LPS after each HS packet completion
273 */
274 iowrite32(0x00000006, base + 0x8000); /* DTCTR */
275 /* VSYNC width = 2 (<< 17) */
276 iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */
277 /*
278 * Non-burst mode with sync pulses: VSE and HSE are output,
279 * HSA period allowed, no commands in LP
280 */
281 iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
282 /*
283 * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
284 * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
285 * (unused, since VMCTR2[HSABM] = 0)
286 */
287 iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
288
289 msleep(5);
290
291 /* setup LCD panel */
292
293 /* cf. drivers/video/omap/lcd_mipid.c */
294 sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE);
295 msleep(120);
296 /*
297 * [7] - Page Address Mode
298 * [6] - Column Address Mode
299 * [5] - Page / Column Address Mode
300 * [4] - Display Device Line Refresh Order
301 * [3] - RGB/BGR Order
302 * [2] - Display Data Latch Data Order
303 * [1] - Flip Horizontal
304 * [0] - Flip Vertical
305 */
306 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
307 /* cf. set_data_lines() */
308 sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT,
309 pixfmt << 4);
310 sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
311
312 return 0;
313}
314
315static int __init sh_mipi_probe(struct platform_device *pdev)
316{
317 struct sh_mipi *mipi;
318 struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
319 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
320 unsigned long rate, f_current;
321 int idx = pdev->id, ret;
322 char dsip_clk[] = "dsi.p_clk";
323
324 if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
325 return -ENODEV;
326
327 mutex_lock(&array_lock);
328 if (idx < 0)
329 for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
330 ;
331
332 if (idx == ARRAY_SIZE(mipi_dsi)) {
333 ret = -EBUSY;
334 goto efindslot;
335 }
336
337 mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
338 if (!mipi) {
339 ret = -ENOMEM;
340 goto ealloc;
341 }
342
343 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
344 dev_err(&pdev->dev, "MIPI register region already claimed\n");
345 ret = -EBUSY;
346 goto ereqreg;
347 }
348
349 mipi->base = ioremap(res->start, resource_size(res));
350 if (!mipi->base) {
351 ret = -ENOMEM;
352 goto emap;
353 }
354
355 mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
356 if (IS_ERR(mipi->dsit_clk)) {
357 ret = PTR_ERR(mipi->dsit_clk);
358 goto eclktget;
359 }
360
361 f_current = clk_get_rate(mipi->dsit_clk);
362 /* 80MHz required by the datasheet */
363 rate = clk_round_rate(mipi->dsit_clk, 80000000);
364 if (rate > 0 && rate != f_current)
365 ret = clk_set_rate(mipi->dsit_clk, rate);
366 else
367 ret = rate;
368 if (ret < 0)
369 goto esettrate;
370
371 dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
372
373 sprintf(dsip_clk, "dsi%1.1dp_clk", idx);
374 mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk);
375 if (IS_ERR(mipi->dsip_clk)) {
376 ret = PTR_ERR(mipi->dsip_clk);
377 goto eclkpget;
378 }
379
380 f_current = clk_get_rate(mipi->dsip_clk);
381 /* Between 10 and 50MHz */
382 rate = clk_round_rate(mipi->dsip_clk, 24000000);
383 if (rate > 0 && rate != f_current)
384 ret = clk_set_rate(mipi->dsip_clk, rate);
385 else
386 ret = rate;
387 if (ret < 0)
388 goto esetprate;
389
390 dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate);
391
392 msleep(10);
393
394 ret = clk_enable(mipi->dsit_clk);
395 if (ret < 0)
396 goto eclkton;
397
398 ret = clk_enable(mipi->dsip_clk);
399 if (ret < 0)
400 goto eclkpon;
401
402 mipi_dsi[idx] = mipi;
403
404 ret = sh_mipi_setup(mipi, pdata);
405 if (ret < 0)
406 goto emipisetup;
407
408 mutex_unlock(&array_lock);
409 platform_set_drvdata(pdev, mipi);
410
411 /* Set up LCDC callbacks */
412 pdata->lcd_chan->board_cfg.board_data = mipi;
413 pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
414 pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
415
416 return 0;
417
418emipisetup:
419 mipi_dsi[idx] = NULL;
420 clk_disable(mipi->dsip_clk);
421eclkpon:
422 clk_disable(mipi->dsit_clk);
423eclkton:
424esetprate:
425 clk_put(mipi->dsip_clk);
426eclkpget:
427esettrate:
428 clk_put(mipi->dsit_clk);
429eclktget:
430 iounmap(mipi->base);
431emap:
432 release_mem_region(res->start, resource_size(res));
433ereqreg:
434 kfree(mipi);
435ealloc:
436efindslot:
437 mutex_unlock(&array_lock);
438
439 return ret;
440}
441
442static int __exit sh_mipi_remove(struct platform_device *pdev)
443{
444 struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
445 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
446 struct sh_mipi *mipi = platform_get_drvdata(pdev);
447 int i, ret;
448
449 mutex_lock(&array_lock);
450
451 for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++)
452 ;
453
454 if (i == ARRAY_SIZE(mipi_dsi)) {
455 ret = -EINVAL;
456 } else {
457 ret = 0;
458 mipi_dsi[i] = NULL;
459 }
460
461 mutex_unlock(&array_lock);
462
463 if (ret < 0)
464 return ret;
465
466 pdata->lcd_chan->board_cfg.display_on = NULL;
467 pdata->lcd_chan->board_cfg.display_off = NULL;
468 pdata->lcd_chan->board_cfg.board_data = NULL;
469
470 clk_disable(mipi->dsip_clk);
471 clk_disable(mipi->dsit_clk);
472 clk_put(mipi->dsit_clk);
473 clk_put(mipi->dsip_clk);
474 iounmap(mipi->base);
475 if (res)
476 release_mem_region(res->start, resource_size(res));
477 platform_set_drvdata(pdev, NULL);
478 kfree(mipi);
479
480 return 0;
481}
482
483static struct platform_driver sh_mipi_driver = {
484 .remove = __exit_p(sh_mipi_remove),
485 .shutdown = sh_mipi_shutdown,
486 .driver = {
487 .name = "sh-mipi-dsi",
488 },
489};
490
491static int __init sh_mipi_init(void)
492{
493 return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe);
494}
495module_init(sh_mipi_init);
496
497static void __exit sh_mipi_exit(void)
498{
499 platform_driver_unregister(&sh_mipi_driver);
500}
501module_exit(sh_mipi_exit);
502
503MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
504MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
505MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
new file mode 100644
index 000000000000..2fde08cc66bf
--- /dev/null
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -0,0 +1,1028 @@
1/*
2 * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
3 * for SLISHDMI13T and SLIPHDMIT IP cores
4 *
5 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/console.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/slab.h>
23#include <linux/types.h>
24#include <linux/workqueue.h>
25
26#include <video/sh_mobile_hdmi.h>
27#include <video/sh_mobile_lcdc.h>
28
29#define HDMI_SYSTEM_CTRL 0x00 /* System control */
30#define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control,
31 bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
32#define HDMI_20_BIT_N_FOR_AUDIO_RPKT_15_8 0x02 /* bits 15..8 of 20-bit N for Audio Clock Regeneration packet */
33#define HDMI_20_BIT_N_FOR_AUDIO_RPKT_7_0 0x03 /* bits 7..0 of 20-bit N for Audio Clock Regeneration packet */
34#define HDMI_SPDIF_AUDIO_SAMP_FREQ_CTS 0x04 /* SPDIF audio sampling frequency,
35 bits 19..16 of Internal CTS */
36#define HDMI_INTERNAL_CTS_15_8 0x05 /* bits 15..8 of Internal CTS */
37#define HDMI_INTERNAL_CTS_7_0 0x06 /* bits 7..0 of Internal CTS */
38#define HDMI_EXTERNAL_CTS_19_16 0x07 /* External CTS */
39#define HDMI_EXTERNAL_CTS_15_8 0x08 /* External CTS */
40#define HDMI_EXTERNAL_CTS_7_0 0x09 /* External CTS */
41#define HDMI_AUDIO_SETTING_1 0x0A /* Audio setting.1 */
42#define HDMI_AUDIO_SETTING_2 0x0B /* Audio setting.2 */
43#define HDMI_I2S_AUDIO_SET 0x0C /* I2S audio setting */
44#define HDMI_DSD_AUDIO_SET 0x0D /* DSD audio setting */
45#define HDMI_DEBUG_MONITOR_1 0x0E /* Debug monitor.1 */
46#define HDMI_DEBUG_MONITOR_2 0x0F /* Debug monitor.2 */
47#define HDMI_I2S_INPUT_PIN_SWAP 0x10 /* I2S input pin swap */
48#define HDMI_AUDIO_STATUS_BITS_SETTING_1 0x11 /* Audio status bits setting.1 */
49#define HDMI_AUDIO_STATUS_BITS_SETTING_2 0x12 /* Audio status bits setting.2 */
50#define HDMI_CATEGORY_CODE 0x13 /* Category code */
51#define HDMI_SOURCE_NUM_AUDIO_WORD_LEN 0x14 /* Source number/Audio word length */
52#define HDMI_AUDIO_VIDEO_SETTING_1 0x15 /* Audio/Video setting.1 */
53#define HDMI_VIDEO_SETTING_1 0x16 /* Video setting.1 */
54#define HDMI_DEEP_COLOR_MODES 0x17 /* Deep Color Modes */
55
56/* 12 16- and 10-bit Color space conversion parameters: 0x18..0x2f */
57#define HDMI_COLOR_SPACE_CONVERSION_PARAMETERS 0x18
58
59#define HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS 0x30 /* External video parameter settings */
60#define HDMI_EXTERNAL_H_TOTAL_7_0 0x31 /* External horizontal total (LSB) */
61#define HDMI_EXTERNAL_H_TOTAL_11_8 0x32 /* External horizontal total (MSB) */
62#define HDMI_EXTERNAL_H_BLANK_7_0 0x33 /* External horizontal blank (LSB) */
63#define HDMI_EXTERNAL_H_BLANK_9_8 0x34 /* External horizontal blank (MSB) */
64#define HDMI_EXTERNAL_H_DELAY_7_0 0x35 /* External horizontal delay (LSB) */
65#define HDMI_EXTERNAL_H_DELAY_9_8 0x36 /* External horizontal delay (MSB) */
66#define HDMI_EXTERNAL_H_DURATION_7_0 0x37 /* External horizontal duration (LSB) */
67#define HDMI_EXTERNAL_H_DURATION_9_8 0x38 /* External horizontal duration (MSB) */
68#define HDMI_EXTERNAL_V_TOTAL_7_0 0x39 /* External vertical total (LSB) */
69#define HDMI_EXTERNAL_V_TOTAL_9_8 0x3A /* External vertical total (MSB) */
70#define HDMI_AUDIO_VIDEO_SETTING_2 0x3B /* Audio/Video setting.2 */
71#define HDMI_EXTERNAL_V_BLANK 0x3D /* External vertical blank */
72#define HDMI_EXTERNAL_V_DELAY 0x3E /* External vertical delay */
73#define HDMI_EXTERNAL_V_DURATION 0x3F /* External vertical duration */
74#define HDMI_CTRL_PKT_MANUAL_SEND_CONTROL 0x40 /* Control packet manual send control */
75#define HDMI_CTRL_PKT_AUTO_SEND 0x41 /* Control packet auto send with VSYNC control */
76#define HDMI_AUTO_CHECKSUM_OPTION 0x42 /* Auto checksum option */
77#define HDMI_VIDEO_SETTING_2 0x45 /* Video setting.2 */
78#define HDMI_OUTPUT_OPTION 0x46 /* Output option */
79#define HDMI_SLIPHDMIT_PARAM_OPTION 0x51 /* SLIPHDMIT parameter option */
80#define HDMI_HSYNC_PMENT_AT_EMB_7_0 0x52 /* HSYNC placement at embedded sync (LSB) */
81#define HDMI_HSYNC_PMENT_AT_EMB_15_8 0x53 /* HSYNC placement at embedded sync (MSB) */
82#define HDMI_VSYNC_PMENT_AT_EMB_7_0 0x54 /* VSYNC placement at embedded sync (LSB) */
83#define HDMI_VSYNC_PMENT_AT_EMB_14_8 0x55 /* VSYNC placement at embedded sync (MSB) */
84#define HDMI_SLIPHDMIT_PARAM_SETTINGS_1 0x56 /* SLIPHDMIT parameter settings.1 */
85#define HDMI_SLIPHDMIT_PARAM_SETTINGS_2 0x57 /* SLIPHDMIT parameter settings.2 */
86#define HDMI_SLIPHDMIT_PARAM_SETTINGS_3 0x58 /* SLIPHDMIT parameter settings.3 */
87#define HDMI_SLIPHDMIT_PARAM_SETTINGS_5 0x59 /* SLIPHDMIT parameter settings.5 */
88#define HDMI_SLIPHDMIT_PARAM_SETTINGS_6 0x5A /* SLIPHDMIT parameter settings.6 */
89#define HDMI_SLIPHDMIT_PARAM_SETTINGS_7 0x5B /* SLIPHDMIT parameter settings.7 */
90#define HDMI_SLIPHDMIT_PARAM_SETTINGS_8 0x5C /* SLIPHDMIT parameter settings.8 */
91#define HDMI_SLIPHDMIT_PARAM_SETTINGS_9 0x5D /* SLIPHDMIT parameter settings.9 */
92#define HDMI_SLIPHDMIT_PARAM_SETTINGS_10 0x5E /* SLIPHDMIT parameter settings.10 */
93#define HDMI_CTRL_PKT_BUF_INDEX 0x5F /* Control packet buffer index */
94#define HDMI_CTRL_PKT_BUF_ACCESS_HB0 0x60 /* Control packet data buffer access window - HB0 */
95#define HDMI_CTRL_PKT_BUF_ACCESS_HB1 0x61 /* Control packet data buffer access window - HB1 */
96#define HDMI_CTRL_PKT_BUF_ACCESS_HB2 0x62 /* Control packet data buffer access window - HB2 */
97#define HDMI_CTRL_PKT_BUF_ACCESS_PB0 0x63 /* Control packet data buffer access window - PB0 */
98#define HDMI_CTRL_PKT_BUF_ACCESS_PB1 0x64 /* Control packet data buffer access window - PB1 */
99#define HDMI_CTRL_PKT_BUF_ACCESS_PB2 0x65 /* Control packet data buffer access window - PB2 */
100#define HDMI_CTRL_PKT_BUF_ACCESS_PB3 0x66 /* Control packet data buffer access window - PB3 */
101#define HDMI_CTRL_PKT_BUF_ACCESS_PB4 0x67 /* Control packet data buffer access window - PB4 */
102#define HDMI_CTRL_PKT_BUF_ACCESS_PB5 0x68 /* Control packet data buffer access window - PB5 */
103#define HDMI_CTRL_PKT_BUF_ACCESS_PB6 0x69 /* Control packet data buffer access window - PB6 */
104#define HDMI_CTRL_PKT_BUF_ACCESS_PB7 0x6A /* Control packet data buffer access window - PB7 */
105#define HDMI_CTRL_PKT_BUF_ACCESS_PB8 0x6B /* Control packet data buffer access window - PB8 */
106#define HDMI_CTRL_PKT_BUF_ACCESS_PB9 0x6C /* Control packet data buffer access window - PB9 */
107#define HDMI_CTRL_PKT_BUF_ACCESS_PB10 0x6D /* Control packet data buffer access window - PB10 */
108#define HDMI_CTRL_PKT_BUF_ACCESS_PB11 0x6E /* Control packet data buffer access window - PB11 */
109#define HDMI_CTRL_PKT_BUF_ACCESS_PB12 0x6F /* Control packet data buffer access window - PB12 */
110#define HDMI_CTRL_PKT_BUF_ACCESS_PB13 0x70 /* Control packet data buffer access window - PB13 */
111#define HDMI_CTRL_PKT_BUF_ACCESS_PB14 0x71 /* Control packet data buffer access window - PB14 */
112#define HDMI_CTRL_PKT_BUF_ACCESS_PB15 0x72 /* Control packet data buffer access window - PB15 */
113#define HDMI_CTRL_PKT_BUF_ACCESS_PB16 0x73 /* Control packet data buffer access window - PB16 */
114#define HDMI_CTRL_PKT_BUF_ACCESS_PB17 0x74 /* Control packet data buffer access window - PB17 */
115#define HDMI_CTRL_PKT_BUF_ACCESS_PB18 0x75 /* Control packet data buffer access window - PB18 */
116#define HDMI_CTRL_PKT_BUF_ACCESS_PB19 0x76 /* Control packet data buffer access window - PB19 */
117#define HDMI_CTRL_PKT_BUF_ACCESS_PB20 0x77 /* Control packet data buffer access window - PB20 */
118#define HDMI_CTRL_PKT_BUF_ACCESS_PB21 0x78 /* Control packet data buffer access window - PB21 */
119#define HDMI_CTRL_PKT_BUF_ACCESS_PB22 0x79 /* Control packet data buffer access window - PB22 */
120#define HDMI_CTRL_PKT_BUF_ACCESS_PB23 0x7A /* Control packet data buffer access window - PB23 */
121#define HDMI_CTRL_PKT_BUF_ACCESS_PB24 0x7B /* Control packet data buffer access window - PB24 */
122#define HDMI_CTRL_PKT_BUF_ACCESS_PB25 0x7C /* Control packet data buffer access window - PB25 */
123#define HDMI_CTRL_PKT_BUF_ACCESS_PB26 0x7D /* Control packet data buffer access window - PB26 */
124#define HDMI_CTRL_PKT_BUF_ACCESS_PB27 0x7E /* Control packet data buffer access window - PB27 */
125#define HDMI_EDID_KSV_FIFO_ACCESS_WINDOW 0x80 /* EDID/KSV FIFO access window */
126#define HDMI_DDC_BUS_ACCESS_FREQ_CTRL_7_0 0x81 /* DDC bus access frequency control (LSB) */
127#define HDMI_DDC_BUS_ACCESS_FREQ_CTRL_15_8 0x82 /* DDC bus access frequency control (MSB) */
128#define HDMI_INTERRUPT_MASK_1 0x92 /* Interrupt mask.1 */
129#define HDMI_INTERRUPT_MASK_2 0x93 /* Interrupt mask.2 */
130#define HDMI_INTERRUPT_STATUS_1 0x94 /* Interrupt status.1 */
131#define HDMI_INTERRUPT_STATUS_2 0x95 /* Interrupt status.2 */
132#define HDMI_INTERRUPT_MASK_3 0x96 /* Interrupt mask.3 */
133#define HDMI_INTERRUPT_MASK_4 0x97 /* Interrupt mask.4 */
134#define HDMI_INTERRUPT_STATUS_3 0x98 /* Interrupt status.3 */
135#define HDMI_INTERRUPT_STATUS_4 0x99 /* Interrupt status.4 */
136#define HDMI_SOFTWARE_HDCP_CONTROL_1 0x9A /* Software HDCP control.1 */
137#define HDMI_FRAME_COUNTER 0x9C /* Frame counter */
138#define HDMI_FRAME_COUNTER_FOR_RI_CHECK 0x9D /* Frame counter for Ri check */
139#define HDMI_HDCP_CONTROL 0xAF /* HDCP control */
140#define HDMI_RI_FRAME_COUNT_REGISTER 0xB2 /* Ri frame count register */
141#define HDMI_DDC_BUS_CONTROL 0xB7 /* DDC bus control */
142#define HDMI_HDCP_STATUS 0xB8 /* HDCP status */
143#define HDMI_SHA0 0xB9 /* sha0 */
144#define HDMI_SHA1 0xBA /* sha1 */
145#define HDMI_SHA2 0xBB /* sha2 */
146#define HDMI_SHA3 0xBC /* sha3 */
147#define HDMI_SHA4 0xBD /* sha4 */
148#define HDMI_BCAPS_READ 0xBE /* BCAPS read / debug */
149#define HDMI_AKSV_BKSV_7_0_MONITOR 0xBF /* AKSV/BKSV[7:0] monitor */
150#define HDMI_AKSV_BKSV_15_8_MONITOR 0xC0 /* AKSV/BKSV[15:8] monitor */
151#define HDMI_AKSV_BKSV_23_16_MONITOR 0xC1 /* AKSV/BKSV[23:16] monitor */
152#define HDMI_AKSV_BKSV_31_24_MONITOR 0xC2 /* AKSV/BKSV[31:24] monitor */
153#define HDMI_AKSV_BKSV_39_32_MONITOR 0xC3 /* AKSV/BKSV[39:32] monitor */
154#define HDMI_EDID_SEGMENT_POINTER 0xC4 /* EDID segment pointer */
155#define HDMI_EDID_WORD_ADDRESS 0xC5 /* EDID word address */
156#define HDMI_EDID_DATA_FIFO_ADDRESS 0xC6 /* EDID data FIFO address */
157#define HDMI_NUM_OF_HDMI_DEVICES 0xC7 /* Number of HDMI devices */
158#define HDMI_HDCP_ERROR_CODE 0xC8 /* HDCP error code */
159#define HDMI_100MS_TIMER_SET 0xC9 /* 100ms timer setting */
160#define HDMI_5SEC_TIMER_SET 0xCA /* 5sec timer setting */
161#define HDMI_RI_READ_COUNT 0xCB /* Ri read count */
162#define HDMI_AN_SEED 0xCC /* An seed */
163#define HDMI_MAX_NUM_OF_RCIVRS_ALLOWED 0xCD /* Maximum number of receivers allowed */
164#define HDMI_HDCP_MEMORY_ACCESS_CONTROL_1 0xCE /* HDCP memory access control.1 */
165#define HDMI_HDCP_MEMORY_ACCESS_CONTROL_2 0xCF /* HDCP memory access control.2 */
166#define HDMI_HDCP_CONTROL_2 0xD0 /* HDCP Control 2 */
167#define HDMI_HDCP_KEY_MEMORY_CONTROL 0xD2 /* HDCP Key Memory Control */
168#define HDMI_COLOR_SPACE_CONV_CONFIG_1 0xD3 /* Color space conversion configuration.1 */
169#define HDMI_VIDEO_SETTING_3 0xD4 /* Video setting.3 */
170#define HDMI_RI_7_0 0xD5 /* Ri[7:0] */
171#define HDMI_RI_15_8 0xD6 /* Ri[15:8] */
172#define HDMI_PJ 0xD7 /* Pj */
173#define HDMI_SHA_RD 0xD8 /* sha_rd */
174#define HDMI_RI_7_0_SAVED 0xD9 /* Ri[7:0] saved */
175#define HDMI_RI_15_8_SAVED 0xDA /* Ri[15:8] saved */
176#define HDMI_PJ_SAVED 0xDB /* Pj saved */
177#define HDMI_NUM_OF_DEVICES 0xDC /* Number of devices */
178#define HDMI_HOT_PLUG_MSENS_STATUS 0xDF /* Hot plug/MSENS status */
179#define HDMI_BCAPS_WRITE 0xE0 /* bcaps */
180#define HDMI_BSTAT_7_0 0xE1 /* bstat[7:0] */
181#define HDMI_BSTAT_15_8 0xE2 /* bstat[15:8] */
182#define HDMI_BKSV_7_0 0xE3 /* bksv[7:0] */
183#define HDMI_BKSV_15_8 0xE4 /* bksv[15:8] */
184#define HDMI_BKSV_23_16 0xE5 /* bksv[23:16] */
185#define HDMI_BKSV_31_24 0xE6 /* bksv[31:24] */
186#define HDMI_BKSV_39_32 0xE7 /* bksv[39:32] */
187#define HDMI_AN_7_0 0xE8 /* An[7:0] */
188#define HDMI_AN_15_8 0xE9 /* An [15:8] */
189#define HDMI_AN_23_16 0xEA /* An [23:16] */
190#define HDMI_AN_31_24 0xEB /* An [31:24] */
191#define HDMI_AN_39_32 0xEC /* An [39:32] */
192#define HDMI_AN_47_40 0xED /* An [47:40] */
193#define HDMI_AN_55_48 0xEE /* An [55:48] */
194#define HDMI_AN_63_56 0xEF /* An [63:56] */
195#define HDMI_PRODUCT_ID 0xF0 /* Product ID */
196#define HDMI_REVISION_ID 0xF1 /* Revision ID */
197#define HDMI_TEST_MODE 0xFE /* Test mode */
198
199enum hotplug_state {
200 HDMI_HOTPLUG_DISCONNECTED,
201 HDMI_HOTPLUG_CONNECTED,
202 HDMI_HOTPLUG_EDID_DONE,
203};
204
205struct sh_hdmi {
206 void __iomem *base;
207 enum hotplug_state hp_state;
208 struct clk *hdmi_clk;
209 struct device *dev;
210 struct fb_info *info;
211 struct delayed_work edid_work;
212 struct fb_var_screeninfo var;
213};
214
215static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
216{
217 iowrite8(data, hdmi->base + reg);
218}
219
220static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
221{
222 return ioread8(hdmi->base + reg);
223}
224
225/* External video parameter settings */
226static void hdmi_external_video_param(struct sh_hdmi *hdmi)
227{
228 struct fb_var_screeninfo *var = &hdmi->var;
229 u16 htotal, hblank, hdelay, vtotal, vblank, vdelay, voffset;
230 u8 sync = 0;
231
232 htotal = var->xres + var->right_margin + var->left_margin + var->hsync_len;
233
234 hdelay = var->hsync_len + var->left_margin;
235 hblank = var->right_margin + hdelay;
236
237 /*
238 * Vertical timing looks a bit different in Figure 18,
239 * but let's try the same first by setting offset = 0
240 */
241 vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
242
243 vdelay = var->vsync_len + var->upper_margin;
244 vblank = var->lower_margin + vdelay;
245 voffset = min(var->upper_margin / 2, 6U);
246
247 /*
248 * [3]: VSYNC polarity: Positive
249 * [2]: HSYNC polarity: Positive
250 * [1]: Interlace/Progressive: Progressive
251 * [0]: External video settings enable: used.
252 */
253 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
254 sync |= 4;
255 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
256 sync |= 8;
257
258 pr_debug("H: %u, %u, %u, %u; V: %u, %u, %u, %u; sync 0x%x\n",
259 htotal, hblank, hdelay, var->hsync_len,
260 vtotal, vblank, vdelay, var->vsync_len, sync);
261
262 hdmi_write(hdmi, sync | (voffset << 4), HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS);
263
264 hdmi_write(hdmi, htotal, HDMI_EXTERNAL_H_TOTAL_7_0);
265 hdmi_write(hdmi, htotal >> 8, HDMI_EXTERNAL_H_TOTAL_11_8);
266
267 hdmi_write(hdmi, hblank, HDMI_EXTERNAL_H_BLANK_7_0);
268 hdmi_write(hdmi, hblank >> 8, HDMI_EXTERNAL_H_BLANK_9_8);
269
270 hdmi_write(hdmi, hdelay, HDMI_EXTERNAL_H_DELAY_7_0);
271 hdmi_write(hdmi, hdelay >> 8, HDMI_EXTERNAL_H_DELAY_9_8);
272
273 hdmi_write(hdmi, var->hsync_len, HDMI_EXTERNAL_H_DURATION_7_0);
274 hdmi_write(hdmi, var->hsync_len >> 8, HDMI_EXTERNAL_H_DURATION_9_8);
275
276 hdmi_write(hdmi, vtotal, HDMI_EXTERNAL_V_TOTAL_7_0);
277 hdmi_write(hdmi, vtotal >> 8, HDMI_EXTERNAL_V_TOTAL_9_8);
278
279 hdmi_write(hdmi, vblank, HDMI_EXTERNAL_V_BLANK);
280
281 hdmi_write(hdmi, vdelay, HDMI_EXTERNAL_V_DELAY);
282
283 hdmi_write(hdmi, var->vsync_len, HDMI_EXTERNAL_V_DURATION);
284
285 /* Set bit 0 of HDMI_EXTERNAL_VIDEO_PARAM_SETTINGS here for manual mode */
286}
287
288/**
289 * sh_hdmi_video_config()
290 */
291static void sh_hdmi_video_config(struct sh_hdmi *hdmi)
292{
293 /*
294 * [7:4]: Audio sampling frequency: 48kHz
295 * [3:1]: Input video format: RGB and YCbCr 4:4:4 (Y on Green)
296 * [0]: Internal/External DE select: internal
297 */
298 hdmi_write(hdmi, 0x20, HDMI_AUDIO_VIDEO_SETTING_1);
299
300 /*
301 * [7:6]: Video output format: RGB 4:4:4
302 * [5:4]: Input video data width: 8 bit
303 * [3:1]: EAV/SAV location: channel 1
304 * [0]: Video input color space: RGB
305 */
306 hdmi_write(hdmi, 0x34, HDMI_VIDEO_SETTING_1);
307
308 /*
309 * [7:6]: Together with bit [6] of HDMI_AUDIO_VIDEO_SETTING_2, which is
310 * left at 0 by default, this configures 24bpp and sets the Color Depth
311 * (CD) field in the General Control Packet
312 */
313 hdmi_write(hdmi, 0x20, HDMI_DEEP_COLOR_MODES);
314}
315
316/**
317 * sh_hdmi_audio_config()
318 */
319static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)
320{
321 /*
322 * [7:4] L/R data swap control
323 * [3:0] appropriate N[19:16]
324 */
325 hdmi_write(hdmi, 0x00, HDMI_L_R_DATA_SWAP_CTRL_RPKT);
326 /* appropriate N[15:8] */
327 hdmi_write(hdmi, 0x18, HDMI_20_BIT_N_FOR_AUDIO_RPKT_15_8);
328 /* appropriate N[7:0] */
329 hdmi_write(hdmi, 0x00, HDMI_20_BIT_N_FOR_AUDIO_RPKT_7_0);
330
331 /* [7:4] 48 kHz SPDIF not used */
332 hdmi_write(hdmi, 0x20, HDMI_SPDIF_AUDIO_SAMP_FREQ_CTS);
333
334 /*
335 * [6:5] set required down sampling rate if required
336 * [4:3] set required audio source
337 */
338 hdmi_write(hdmi, 0x00, HDMI_AUDIO_SETTING_1);
339
340 /* [3:0] set sending channel number for channel status */
341 hdmi_write(hdmi, 0x40, HDMI_AUDIO_SETTING_2);
342
343 /*
344 * [5:2] set valid I2S source input pin
345 * [1:0] set input I2S source mode
346 */
347 hdmi_write(hdmi, 0x04, HDMI_I2S_AUDIO_SET);
348
349 /* [7:4] set valid DSD source input pin */
350 hdmi_write(hdmi, 0x00, HDMI_DSD_AUDIO_SET);
351
352 /* [7:0] set appropriate I2S input pin swap settings if required */
353 hdmi_write(hdmi, 0x00, HDMI_I2S_INPUT_PIN_SWAP);
354
355 /*
356 * [7] set validity bit for channel status
357 * [3:0] set original sample frequency for channel status
358 */
359 hdmi_write(hdmi, 0x00, HDMI_AUDIO_STATUS_BITS_SETTING_1);
360
361 /*
362 * [7] set value for channel status
363 * [6] set value for channel status
364 * [5] set copyright bit for channel status
365 * [4:2] set additional information for channel status
366 * [1:0] set clock accuracy for channel status
367 */
368 hdmi_write(hdmi, 0x00, HDMI_AUDIO_STATUS_BITS_SETTING_2);
369
370 /* [7:0] set category code for channel status */
371 hdmi_write(hdmi, 0x00, HDMI_CATEGORY_CODE);
372
373 /*
374 * [7:4] set source number for channel status
375 * [3:0] set word length for channel status
376 */
377 hdmi_write(hdmi, 0x00, HDMI_SOURCE_NUM_AUDIO_WORD_LEN);
378
379 /* [7:4] set sample frequency for channel status */
380 hdmi_write(hdmi, 0x20, HDMI_AUDIO_VIDEO_SETTING_1);
381}
382
383/**
384 * sh_hdmi_phy_config()
385 */
386static void sh_hdmi_phy_config(struct sh_hdmi *hdmi)
387{
388 /* 720p, 8bit, 74.25MHz. Might need to be adjusted for other formats */
389 hdmi_write(hdmi, 0x19, HDMI_SLIPHDMIT_PARAM_SETTINGS_1);
390 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_2);
391 hdmi_write(hdmi, 0x00, HDMI_SLIPHDMIT_PARAM_SETTINGS_3);
392 /* PLLA_CONFIG[7:0]: VCO gain, VCO offset, LPF resistance[0] */
393 hdmi_write(hdmi, 0x44, HDMI_SLIPHDMIT_PARAM_SETTINGS_5);
394 hdmi_write(hdmi, 0x32, HDMI_SLIPHDMIT_PARAM_SETTINGS_6);
395 hdmi_write(hdmi, 0x4A, HDMI_SLIPHDMIT_PARAM_SETTINGS_7);
396 hdmi_write(hdmi, 0x0E, HDMI_SLIPHDMIT_PARAM_SETTINGS_8);
397 hdmi_write(hdmi, 0x25, HDMI_SLIPHDMIT_PARAM_SETTINGS_9);
398 hdmi_write(hdmi, 0x04, HDMI_SLIPHDMIT_PARAM_SETTINGS_10);
399}
400
401/**
402 * sh_hdmi_avi_infoframe_setup() - Auxiliary Video Information InfoFrame CONTROL PACKET
403 */
404static void sh_hdmi_avi_infoframe_setup(struct sh_hdmi *hdmi)
405{
406 /* AVI InfoFrame */
407 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_INDEX);
408
409 /* Packet Type = 0x82 */
410 hdmi_write(hdmi, 0x82, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
411
412 /* Version = 0x02 */
413 hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
414
415 /* Length = 13 (0x0D) */
416 hdmi_write(hdmi, 0x0D, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
417
418 /* N. A. Checksum */
419 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0);
420
421 /*
422 * Y = RGB
423 * A0 = No Data
424 * B = Bar Data not valid
425 * S = No Data
426 */
427 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
428
429 /*
430 * C = No Data
431 * M = 16:9 Picture Aspect Ratio
432 * R = Same as picture aspect ratio
433 */
434 hdmi_write(hdmi, 0x28, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
435
436 /*
437 * ITC = No Data
438 * EC = xvYCC601
439 * Q = Default (depends on video format)
440 * SC = No Known non_uniform Scaling
441 */
442 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3);
443
444 /*
445 * VIC = 1280 x 720p: ignored if external config is used
446 * Send 2 for 720 x 480p, 16 for 1080p
447 */
448 hdmi_write(hdmi, 4, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
449
450 /* PR = No Repetition */
451 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
452
453 /* Line Number of End of Top Bar (lower 8 bits) */
454 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB6);
455
456 /* Line Number of End of Top Bar (upper 8 bits) */
457 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB7);
458
459 /* Line Number of Start of Bottom Bar (lower 8 bits) */
460 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB8);
461
462 /* Line Number of Start of Bottom Bar (upper 8 bits) */
463 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB9);
464
465 /* Pixel Number of End of Left Bar (lower 8 bits) */
466 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10);
467
468 /* Pixel Number of End of Left Bar (upper 8 bits) */
469 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB11);
470
471 /* Pixel Number of Start of Right Bar (lower 8 bits) */
472 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB12);
473
474 /* Pixel Number of Start of Right Bar (upper 8 bits) */
475 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB13);
476}
477
478/**
479 * sh_hdmi_audio_infoframe_setup() - Audio InfoFrame of CONTROL PACKET
480 */
481static void sh_hdmi_audio_infoframe_setup(struct sh_hdmi *hdmi)
482{
483 /* Audio InfoFrame */
484 hdmi_write(hdmi, 0x08, HDMI_CTRL_PKT_BUF_INDEX);
485
486 /* Packet Type = 0x84 */
487 hdmi_write(hdmi, 0x84, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
488
489 /* Version Number = 0x01 */
490 hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
491
492 /* 0 Length = 10 (0x0A) */
493 hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
494
495 /* n. a. Checksum */
496 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0);
497
498 /* Audio Channel Count = Refer to Stream Header */
499 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB1);
500
501 /* Refer to Stream Header */
502 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB2);
503
504 /* Format depends on coding type (i.e. CT0...CT3) */
505 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB3);
506
507 /* Speaker Channel Allocation = Front Right + Front Left */
508 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB4);
509
510 /* Level Shift Value = 0 dB, Down - mix is permitted or no information */
511 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB5);
512
513 /* Reserved (0) */
514 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB6);
515 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB7);
516 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB8);
517 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB9);
518 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB10);
519}
520
521/**
522 * sh_hdmi_gamut_metadata_setup() - Gamut Metadata Packet of CONTROL PACKET
523 */
524static void sh_hdmi_gamut_metadata_setup(struct sh_hdmi *hdmi)
525{
526 int i;
527
528 /* Gamut Metadata Packet */
529 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_INDEX);
530
531 /* Packet Type = 0x0A */
532 hdmi_write(hdmi, 0x0A, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
533 /* Gamut Packet is not used, so default value */
534 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
535 /* Gamut Packet is not used, so default value */
536 hdmi_write(hdmi, 0x10, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
537
538 /* GBD bytes 0 through 27 */
539 for (i = 0; i <= 27; i++)
540 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0_63H - PB27_7EH */
541 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
542}
543
544/**
545 * sh_hdmi_acp_setup() - Audio Content Protection Packet (ACP)
546 */
547static void sh_hdmi_acp_setup(struct sh_hdmi *hdmi)
548{
549 int i;
550
551 /* Audio Content Protection Packet (ACP) */
552 hdmi_write(hdmi, 0x01, HDMI_CTRL_PKT_BUF_INDEX);
553
554 /* Packet Type = 0x04 */
555 hdmi_write(hdmi, 0x04, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
556 /* ACP_Type */
557 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
558 /* Reserved (0) */
559 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
560
561 /* GBD bytes 0 through 27 */
562 for (i = 0; i <= 27; i++)
563 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
564 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
565}
566
567/**
568 * sh_hdmi_isrc1_setup() - ISRC1 Packet
569 */
570static void sh_hdmi_isrc1_setup(struct sh_hdmi *hdmi)
571{
572 int i;
573
574 /* ISRC1 Packet */
575 hdmi_write(hdmi, 0x02, HDMI_CTRL_PKT_BUF_INDEX);
576
577 /* Packet Type = 0x05 */
578 hdmi_write(hdmi, 0x05, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
579 /* ISRC_Cont, ISRC_Valid, Reserved (0), ISRC_Status */
580 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
581 /* Reserved (0) */
582 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
583
584 /* PB0 UPC_EAN_ISRC_0-15 */
585 /* Bytes PB16-PB27 shall be set to a value of 0. */
586 for (i = 0; i <= 27; i++)
587 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
588 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
589}
590
591/**
592 * sh_hdmi_isrc2_setup() - ISRC2 Packet
593 */
594static void sh_hdmi_isrc2_setup(struct sh_hdmi *hdmi)
595{
596 int i;
597
598 /* ISRC2 Packet */
599 hdmi_write(hdmi, 0x03, HDMI_CTRL_PKT_BUF_INDEX);
600
601 /* HB0 Packet Type = 0x06 */
602 hdmi_write(hdmi, 0x06, HDMI_CTRL_PKT_BUF_ACCESS_HB0);
603 /* Reserved (0) */
604 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB1);
605 /* Reserved (0) */
606 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_HB2);
607
608 /* PB0 UPC_EAN_ISRC_16-31 */
609 /* Bytes PB16-PB27 shall be set to a value of 0. */
610 for (i = 0; i <= 27; i++)
611 /* HDMI_CTRL_PKT_BUF_ACCESS_PB0 - PB27 */
612 hdmi_write(hdmi, 0x00, HDMI_CTRL_PKT_BUF_ACCESS_PB0 + i);
613}
614
615/**
616 * sh_hdmi_configure() - Initialise HDMI for output
617 */
618static void sh_hdmi_configure(struct sh_hdmi *hdmi)
619{
620 /* Configure video format */
621 sh_hdmi_video_config(hdmi);
622
623 /* Configure audio format */
624 sh_hdmi_audio_config(hdmi);
625
626 /* Configure PHY */
627 sh_hdmi_phy_config(hdmi);
628
629 /* Auxiliary Video Information (AVI) InfoFrame */
630 sh_hdmi_avi_infoframe_setup(hdmi);
631
632 /* Audio InfoFrame */
633 sh_hdmi_audio_infoframe_setup(hdmi);
634
635 /* Gamut Metadata packet */
636 sh_hdmi_gamut_metadata_setup(hdmi);
637
638 /* Audio Content Protection (ACP) Packet */
639 sh_hdmi_acp_setup(hdmi);
640
641 /* ISRC1 Packet */
642 sh_hdmi_isrc1_setup(hdmi);
643
644 /* ISRC2 Packet */
645 sh_hdmi_isrc2_setup(hdmi);
646
647 /*
648 * Control packet auto send with VSYNC control: auto send
649 * General control, Gamut metadata, ISRC, and ACP packets
650 */
651 hdmi_write(hdmi, 0x8E, HDMI_CTRL_PKT_AUTO_SEND);
652
653 /* FIXME */
654 msleep(10);
655
656 /* PS mode b->d, reset PLLA and PLLB */
657 hdmi_write(hdmi, 0x4C, HDMI_SYSTEM_CTRL);
658
659 udelay(10);
660
661 hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
662}
663
664static void sh_hdmi_read_edid(struct sh_hdmi *hdmi)
665{
666 struct fb_var_screeninfo *var = &hdmi->var;
667 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
668 struct fb_videomode *lcd_cfg = &pdata->lcd_chan->lcd_cfg;
669 unsigned long height = var->height, width = var->width;
670 int i;
671 u8 edid[128];
672
673 /* Read EDID */
674 pr_debug("Read back EDID code:");
675 for (i = 0; i < 128; i++) {
676 edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
677#ifdef DEBUG
678 if ((i % 16) == 0) {
679 printk(KERN_CONT "\n");
680 printk(KERN_DEBUG "%02X | %02X", i, edid[i]);
681 } else {
682 printk(KERN_CONT " %02X", edid[i]);
683 }
684#endif
685 }
686#ifdef DEBUG
687 printk(KERN_CONT "\n");
688#endif
689 fb_parse_edid(edid, var);
690 pr_debug("%u-%u-%u-%u x %u-%u-%u-%u @ %lu kHz monitor detected\n",
691 var->left_margin, var->xres, var->right_margin, var->hsync_len,
692 var->upper_margin, var->yres, var->lower_margin, var->vsync_len,
693 PICOS2KHZ(var->pixclock));
694
695 /* FIXME: Use user-provided configuration instead of EDID */
696 var->width = width;
697 var->xres = lcd_cfg->xres;
698 var->xres_virtual = lcd_cfg->xres;
699 var->left_margin = lcd_cfg->left_margin;
700 var->right_margin = lcd_cfg->right_margin;
701 var->hsync_len = lcd_cfg->hsync_len;
702 var->height = height;
703 var->yres = lcd_cfg->yres;
704 var->yres_virtual = lcd_cfg->yres * 2;
705 var->upper_margin = lcd_cfg->upper_margin;
706 var->lower_margin = lcd_cfg->lower_margin;
707 var->vsync_len = lcd_cfg->vsync_len;
708 var->sync = lcd_cfg->sync;
709 var->pixclock = lcd_cfg->pixclock;
710
711 hdmi_external_video_param(hdmi);
712}
713
714static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
715{
716 struct sh_hdmi *hdmi = dev_id;
717 u8 status1, status2, mask1, mask2;
718
719 /* mode_b and PLLA and PLLB reset */
720 hdmi_write(hdmi, 0x2C, HDMI_SYSTEM_CTRL);
721
722 /* How long shall reset be held? */
723 udelay(10);
724
725 /* mode_b and PLLA and PLLB reset release */
726 hdmi_write(hdmi, 0x20, HDMI_SYSTEM_CTRL);
727
728 status1 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_1);
729 status2 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_2);
730
731 mask1 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_1);
732 mask2 = hdmi_read(hdmi, HDMI_INTERRUPT_MASK_2);
733
734 /* Correct would be to ack only set bits, but the datasheet requires 0xff */
735 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_1);
736 hdmi_write(hdmi, 0xFF, HDMI_INTERRUPT_STATUS_2);
737
738 if (printk_ratelimit())
739 pr_debug("IRQ #%d: Status #1: 0x%x & 0x%x, #2: 0x%x & 0x%x\n",
740 irq, status1, mask1, status2, mask2);
741
742 if (!((status1 & mask1) | (status2 & mask2))) {
743 return IRQ_NONE;
744 } else if (status1 & 0xc0) {
745 u8 msens;
746
747 /* Datasheet specifies 10ms... */
748 udelay(500);
749
750 msens = hdmi_read(hdmi, HDMI_HOT_PLUG_MSENS_STATUS);
751 pr_debug("MSENS 0x%x\n", msens);
752 /* Check, if hot plug & MSENS pin status are both high */
753 if ((msens & 0xC0) == 0xC0) {
754 /* Display plug in */
755 hdmi->hp_state = HDMI_HOTPLUG_CONNECTED;
756
757 /* Set EDID word address */
758 hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS);
759 /* Set EDID segment pointer */
760 hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
761 /* Enable EDID interrupt */
762 hdmi_write(hdmi, 0xC6, HDMI_INTERRUPT_MASK_1);
763 } else if (!(status1 & 0x80)) {
764 /* Display unplug, beware multiple interrupts */
765 if (hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED)
766 schedule_delayed_work(&hdmi->edid_work, 0);
767
768 hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
769 /* display_off will switch back to mode_a */
770 }
771 } else if (status1 & 2) {
772 /* EDID error interrupt: retry */
773 /* Set EDID word address */
774 hdmi_write(hdmi, 0x00, HDMI_EDID_WORD_ADDRESS);
775 /* Set EDID segment pointer */
776 hdmi_write(hdmi, 0x00, HDMI_EDID_SEGMENT_POINTER);
777 } else if (status1 & 4) {
778 /* Disable EDID interrupt */
779 hdmi_write(hdmi, 0xC0, HDMI_INTERRUPT_MASK_1);
780 hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
781 schedule_delayed_work(&hdmi->edid_work, msecs_to_jiffies(10));
782 }
783
784 return IRQ_HANDLED;
785}
786
787static void hdmi_display_on(void *arg, struct fb_info *info)
788{
789 struct sh_hdmi *hdmi = arg;
790 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
791
792 if (info->var.xres != 1280 || info->var.yres != 720) {
793 dev_warn(info->device, "Unsupported framebuffer geometry %ux%u\n",
794 info->var.xres, info->var.yres);
795 return;
796 }
797
798 pr_debug("%s(%p): state %x\n", __func__, pdata->lcd_dev, info->state);
799 /*
800 * FIXME: not a good place to store fb_info. And we cannot nullify it
801 * even on monitor disconnect. What should the lifecycle be?
802 */
803 hdmi->info = info;
804 switch (hdmi->hp_state) {
805 case HDMI_HOTPLUG_EDID_DONE:
806 /* PS mode d->e. All functions are active */
807 hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
808 pr_debug("HDMI running\n");
809 break;
810 case HDMI_HOTPLUG_DISCONNECTED:
811 info->state = FBINFO_STATE_SUSPENDED;
812 default:
813 hdmi->var = info->var;
814 }
815}
816
817static void hdmi_display_off(void *arg)
818{
819 struct sh_hdmi *hdmi = arg;
820 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
821
822 pr_debug("%s(%p)\n", __func__, pdata->lcd_dev);
823 /* PS mode e->a */
824 hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
825}
826
827/* Hotplug interrupt occurred, read EDID */
828static void edid_work_fn(struct work_struct *work)
829{
830 struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
831 struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data;
832
833 pr_debug("%s(%p): begin, hotplug status %d\n", __func__,
834 pdata->lcd_dev, hdmi->hp_state);
835
836 if (!pdata->lcd_dev)
837 return;
838
839 if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
840 pm_runtime_get_sync(hdmi->dev);
841 /* A device has been plugged in */
842 sh_hdmi_read_edid(hdmi);
843 msleep(10);
844 sh_hdmi_configure(hdmi);
845 /* Switched to another (d) power-save mode */
846 msleep(10);
847
848 if (!hdmi->info)
849 return;
850
851 acquire_console_sem();
852
853 /* HDMI plug in */
854 hdmi->info->var = hdmi->var;
855 if (hdmi->info->state != FBINFO_STATE_RUNNING)
856 fb_set_suspend(hdmi->info, 0);
857 else
858 hdmi_display_on(hdmi, hdmi->info);
859
860 release_console_sem();
861 } else {
862 if (!hdmi->info)
863 return;
864
865 acquire_console_sem();
866
867 /* HDMI disconnect */
868 fb_set_suspend(hdmi->info, 1);
869
870 release_console_sem();
871 pm_runtime_put(hdmi->dev);
872 }
873
874 pr_debug("%s(%p): end\n", __func__, pdata->lcd_dev);
875}
876
877static int __init sh_hdmi_probe(struct platform_device *pdev)
878{
879 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
880 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
881 int irq = platform_get_irq(pdev, 0), ret;
882 struct sh_hdmi *hdmi;
883 long rate;
884
885 if (!res || !pdata || irq < 0)
886 return -ENODEV;
887
888 hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
889 if (!hdmi) {
890 dev_err(&pdev->dev, "Cannot allocate device data\n");
891 return -ENOMEM;
892 }
893
894 hdmi->dev = &pdev->dev;
895
896 hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
897 if (IS_ERR(hdmi->hdmi_clk)) {
898 ret = PTR_ERR(hdmi->hdmi_clk);
899 dev_err(&pdev->dev, "Unable to get clock: %d\n", ret);
900 goto egetclk;
901 }
902
903 rate = PICOS2KHZ(pdata->lcd_chan->lcd_cfg.pixclock) * 1000;
904
905 rate = clk_round_rate(hdmi->hdmi_clk, rate);
906 if (rate < 0) {
907 ret = rate;
908 dev_err(&pdev->dev, "Cannot get suitable rate: %ld\n", rate);
909 goto erate;
910 }
911
912 ret = clk_set_rate(hdmi->hdmi_clk, rate);
913 if (ret < 0) {
914 dev_err(&pdev->dev, "Cannot set rate %ld: %d\n", rate, ret);
915 goto erate;
916 }
917
918 pr_debug("HDMI set frequency %lu\n", rate);
919
920 ret = clk_enable(hdmi->hdmi_clk);
921 if (ret < 0) {
922 dev_err(&pdev->dev, "Cannot enable clock: %d\n", ret);
923 goto eclkenable;
924 }
925
926 dev_info(&pdev->dev, "Enabled HDMI clock at %luHz\n", rate);
927
928 if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) {
929 dev_err(&pdev->dev, "HDMI register region already claimed\n");
930 ret = -EBUSY;
931 goto ereqreg;
932 }
933
934 hdmi->base = ioremap(res->start, resource_size(res));
935 if (!hdmi->base) {
936 dev_err(&pdev->dev, "HDMI register region already claimed\n");
937 ret = -ENOMEM;
938 goto emap;
939 }
940
941 platform_set_drvdata(pdev, hdmi);
942
943#if 1
944 /* Product and revision IDs are 0 in sh-mobile version */
945 dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
946 hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
947#endif
948
949 /* Set up LCDC callbacks */
950 pdata->lcd_chan->board_cfg.board_data = hdmi;
951 pdata->lcd_chan->board_cfg.display_on = hdmi_display_on;
952 pdata->lcd_chan->board_cfg.display_off = hdmi_display_off;
953
954 INIT_DELAYED_WORK(&hdmi->edid_work, edid_work_fn);
955
956 pm_runtime_enable(&pdev->dev);
957 pm_runtime_resume(&pdev->dev);
958
959 ret = request_irq(irq, sh_hdmi_hotplug, 0,
960 dev_name(&pdev->dev), hdmi);
961 if (ret < 0) {
962 dev_err(&pdev->dev, "Unable to request irq: %d\n", ret);
963 goto ereqirq;
964 }
965
966 return 0;
967
968ereqirq:
969 pm_runtime_disable(&pdev->dev);
970 iounmap(hdmi->base);
971emap:
972 release_mem_region(res->start, resource_size(res));
973ereqreg:
974 clk_disable(hdmi->hdmi_clk);
975eclkenable:
976erate:
977 clk_put(hdmi->hdmi_clk);
978egetclk:
979 kfree(hdmi);
980
981 return ret;
982}
983
984static int __exit sh_hdmi_remove(struct platform_device *pdev)
985{
986 struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
987 struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
988 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
989 int irq = platform_get_irq(pdev, 0);
990
991 pdata->lcd_chan->board_cfg.display_on = NULL;
992 pdata->lcd_chan->board_cfg.display_off = NULL;
993 pdata->lcd_chan->board_cfg.board_data = NULL;
994
995 free_irq(irq, hdmi);
996 pm_runtime_disable(&pdev->dev);
997 cancel_delayed_work_sync(&hdmi->edid_work);
998 clk_disable(hdmi->hdmi_clk);
999 clk_put(hdmi->hdmi_clk);
1000 iounmap(hdmi->base);
1001 release_mem_region(res->start, resource_size(res));
1002 kfree(hdmi);
1003
1004 return 0;
1005}
1006
1007static struct platform_driver sh_hdmi_driver = {
1008 .remove = __exit_p(sh_hdmi_remove),
1009 .driver = {
1010 .name = "sh-mobile-hdmi",
1011 },
1012};
1013
1014static int __init sh_hdmi_init(void)
1015{
1016 return platform_driver_probe(&sh_hdmi_driver, sh_hdmi_probe);
1017}
1018module_init(sh_hdmi_init);
1019
1020static void __exit sh_hdmi_exit(void)
1021{
1022 platform_driver_unregister(&sh_hdmi_driver);
1023}
1024module_exit(sh_hdmi_exit);
1025
1026MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1027MODULE_DESCRIPTION("SuperH / ARM-shmobile HDMI driver");
1028MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 12c451a711e9..d72075a9f01c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -56,6 +56,7 @@ static int lcdc_shared_regs[] = {
56/* per-channel registers */ 56/* per-channel registers */
57enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 57enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
58 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR, 58 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
59 LDHAJR,
59 NR_CH_REGS }; 60 NR_CH_REGS };
60 61
61static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { 62static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
@@ -74,6 +75,7 @@ static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
74 [LDVLNR] = 0x450, 75 [LDVLNR] = 0x450,
75 [LDVSYNR] = 0x454, 76 [LDVSYNR] = 0x454,
76 [LDPMR] = 0x460, 77 [LDPMR] = 0x460,
78 [LDHAJR] = 0x4a0,
77}; 79};
78 80
79static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = { 81static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
@@ -137,6 +139,7 @@ struct sh_mobile_lcdc_priv {
137 struct clk *dot_clk; 139 struct clk *dot_clk;
138 unsigned long lddckr; 140 unsigned long lddckr;
139 struct sh_mobile_lcdc_chan ch[2]; 141 struct sh_mobile_lcdc_chan ch[2];
142 struct notifier_block notifier;
140 unsigned long saved_shared_regs[NR_SHARED_REGS]; 143 unsigned long saved_shared_regs[NR_SHARED_REGS];
141 int started; 144 int started;
142}; 145};
@@ -404,6 +407,56 @@ static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
404 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */ 407 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */
405} 408}
406 409
410static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
411{
412 struct fb_var_screeninfo *var = &ch->info->var;
413 unsigned long h_total, hsync_pos;
414 u32 tmp;
415
416 tmp = ch->ldmt1r_value;
417 tmp |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
418 tmp |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
419 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0;
420 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0;
421 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0;
422 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0;
423 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0;
424 lcdc_write_chan(ch, LDMT1R, tmp);
425
426 /* setup SYS bus */
427 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
428 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
429
430 /* horizontal configuration */
431 h_total = var->xres + var->hsync_len +
432 var->left_margin + var->right_margin;
433 tmp = h_total / 8; /* HTCN */
434 tmp |= (var->xres / 8) << 16; /* HDCN */
435 lcdc_write_chan(ch, LDHCNR, tmp);
436
437 hsync_pos = var->xres + var->right_margin;
438 tmp = hsync_pos / 8; /* HSYNP */
439 tmp |= (var->hsync_len / 8) << 16; /* HSYNW */
440 lcdc_write_chan(ch, LDHSYNR, tmp);
441
442 /* vertical configuration */
443 tmp = var->yres + var->vsync_len +
444 var->upper_margin + var->lower_margin; /* VTLN */
445 tmp |= var->yres << 16; /* VDLN */
446 lcdc_write_chan(ch, LDVLNR, tmp);
447
448 tmp = var->yres + var->lower_margin; /* VSYNP */
449 tmp |= var->vsync_len << 16; /* VSYNW */
450 lcdc_write_chan(ch, LDVSYNR, tmp);
451
452 /* Adjust horizontal synchronisation for HDMI */
453 tmp = ((var->xres & 7) << 24) |
454 ((h_total & 7) << 16) |
455 ((var->hsync_len & 7) << 8) |
456 hsync_pos;
457 lcdc_write_chan(ch, LDHAJR, tmp);
458}
459
407static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) 460static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
408{ 461{
409 struct sh_mobile_lcdc_chan *ch; 462 struct sh_mobile_lcdc_chan *ch;
@@ -470,49 +523,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
470 if (!ch->enabled) 523 if (!ch->enabled)
471 continue; 524 continue;
472 525
473 tmp = ch->ldmt1r_value; 526 sh_mobile_lcdc_geometry(ch);
474 tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
475 tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
476 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0;
477 tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0;
478 tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0;
479 tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0;
480 tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0;
481 lcdc_write_chan(ch, LDMT1R, tmp);
482
483 /* setup SYS bus */
484 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
485 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
486
487 /* horizontal configuration */
488 tmp = lcd_cfg->xres + lcd_cfg->hsync_len;
489 tmp += lcd_cfg->left_margin;
490 tmp += lcd_cfg->right_margin;
491 tmp /= 8; /* HTCN */
492 tmp |= (lcd_cfg->xres / 8) << 16; /* HDCN */
493 lcdc_write_chan(ch, LDHCNR, tmp);
494
495 tmp = lcd_cfg->xres;
496 tmp += lcd_cfg->right_margin;
497 tmp /= 8; /* HSYNP */
498 tmp |= (lcd_cfg->hsync_len / 8) << 16; /* HSYNW */
499 lcdc_write_chan(ch, LDHSYNR, tmp);
500 527
501 /* power supply */ 528 /* power supply */
502 lcdc_write_chan(ch, LDPMR, 0); 529 lcdc_write_chan(ch, LDPMR, 0);
503 530
504 /* vertical configuration */
505 tmp = lcd_cfg->yres + lcd_cfg->vsync_len;
506 tmp += lcd_cfg->upper_margin;
507 tmp += lcd_cfg->lower_margin; /* VTLN */
508 tmp |= lcd_cfg->yres << 16; /* VDLN */
509 lcdc_write_chan(ch, LDVLNR, tmp);
510
511 tmp = lcd_cfg->yres;
512 tmp += lcd_cfg->lower_margin; /* VSYNP */
513 tmp |= lcd_cfg->vsync_len << 16; /* VSYNW */
514 lcdc_write_chan(ch, LDVSYNR, tmp);
515
516 board_cfg = &ch->cfg.board_cfg; 531 board_cfg = &ch->cfg.board_cfg;
517 if (board_cfg->setup_sys) 532 if (board_cfg->setup_sys)
518 ret = board_cfg->setup_sys(board_cfg->board_data, ch, 533 ret = board_cfg->setup_sys(board_cfg->board_data, ch,
@@ -577,7 +592,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
577 592
578 board_cfg = &ch->cfg.board_cfg; 593 board_cfg = &ch->cfg.board_cfg;
579 if (board_cfg->display_on) 594 if (board_cfg->display_on)
580 board_cfg->display_on(board_cfg->board_data); 595 board_cfg->display_on(board_cfg->board_data, ch->info);
581 } 596 }
582 597
583 return 0; 598 return 0;
@@ -943,6 +958,62 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
943 .runtime_resume = sh_mobile_lcdc_runtime_resume, 958 .runtime_resume = sh_mobile_lcdc_runtime_resume,
944}; 959};
945 960
961static int sh_mobile_lcdc_notify(struct notifier_block *nb,
962 unsigned long action, void *data)
963{
964 struct fb_event *event = data;
965 struct fb_info *info = event->info;
966 struct sh_mobile_lcdc_chan *ch = info->par;
967 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
968 struct fb_var_screeninfo *var;
969
970 if (&ch->lcdc->notifier != nb)
971 return 0;
972
973 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
974 __func__, action, event->data);
975
976 switch(action) {
977 case FB_EVENT_SUSPEND:
978 if (board_cfg->display_off)
979 board_cfg->display_off(board_cfg->board_data);
980 pm_runtime_put(info->device);
981 break;
982 case FB_EVENT_RESUME:
983 var = &info->var;
984
985 /* HDMI must be enabled before LCDC configuration */
986 if (board_cfg->display_on)
987 board_cfg->display_on(board_cfg->board_data, ch->info);
988
989 /* Check if the new display is not in our modelist */
990 if (ch->info->modelist.next &&
991 !fb_match_mode(var, &ch->info->modelist)) {
992 struct fb_videomode mode;
993 int ret;
994
995 /* Can we handle this display? */
996 if (var->xres > ch->cfg.lcd_cfg.xres ||
997 var->yres > ch->cfg.lcd_cfg.yres)
998 return -ENOMEM;
999
1000 /* Add to the modelist */
1001 fb_var_to_videomode(&mode, var);
1002 ret = fb_add_videomode(&mode, &ch->info->modelist);
1003 if (ret < 0)
1004 return ret;
1005 }
1006
1007 pm_runtime_get_sync(info->device);
1008
1009 sh_mobile_lcdc_geometry(ch);
1010
1011 break;
1012 }
1013
1014 return 0;
1015}
1016
946static int sh_mobile_lcdc_remove(struct platform_device *pdev); 1017static int sh_mobile_lcdc_remove(struct platform_device *pdev);
947 1018
948static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) 1019static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
@@ -1020,15 +1091,19 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1020 goto err1; 1091 goto err1;
1021 } 1092 }
1022 1093
1094 priv->base = ioremap_nocache(res->start, resource_size(res));
1095 if (!priv->base)
1096 goto err1;
1097
1023 error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); 1098 error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
1024 if (error) { 1099 if (error) {
1025 dev_err(&pdev->dev, "unable to setup clocks\n"); 1100 dev_err(&pdev->dev, "unable to setup clocks\n");
1026 goto err1; 1101 goto err1;
1027 } 1102 }
1028 1103
1029 priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
1030
1031 for (i = 0; i < j; i++) { 1104 for (i = 0; i < j; i++) {
1105 struct fb_var_screeninfo *var;
1106 struct fb_videomode *lcd_cfg;
1032 cfg = &priv->ch[i].cfg; 1107 cfg = &priv->ch[i].cfg;
1033 1108
1034 priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); 1109 priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
@@ -1039,22 +1114,33 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1039 } 1114 }
1040 1115
1041 info = priv->ch[i].info; 1116 info = priv->ch[i].info;
1117 var = &info->var;
1118 lcd_cfg = &cfg->lcd_cfg;
1042 info->fbops = &sh_mobile_lcdc_ops; 1119 info->fbops = &sh_mobile_lcdc_ops;
1043 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; 1120 var->xres = var->xres_virtual = lcd_cfg->xres;
1044 info->var.yres = cfg->lcd_cfg.yres; 1121 var->yres = lcd_cfg->yres;
1045 /* Default Y virtual resolution is 2x panel size */ 1122 /* Default Y virtual resolution is 2x panel size */
1046 info->var.yres_virtual = info->var.yres * 2; 1123 var->yres_virtual = var->yres * 2;
1047 info->var.width = cfg->lcd_size_cfg.width; 1124 var->width = cfg->lcd_size_cfg.width;
1048 info->var.height = cfg->lcd_size_cfg.height; 1125 var->height = cfg->lcd_size_cfg.height;
1049 info->var.activate = FB_ACTIVATE_NOW; 1126 var->activate = FB_ACTIVATE_NOW;
1050 error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp); 1127 var->left_margin = lcd_cfg->left_margin;
1128 var->right_margin = lcd_cfg->right_margin;
1129 var->upper_margin = lcd_cfg->upper_margin;
1130 var->lower_margin = lcd_cfg->lower_margin;
1131 var->hsync_len = lcd_cfg->hsync_len;
1132 var->vsync_len = lcd_cfg->vsync_len;
1133 var->sync = lcd_cfg->sync;
1134 var->pixclock = lcd_cfg->pixclock;
1135
1136 error = sh_mobile_lcdc_set_bpp(var, cfg->bpp);
1051 if (error) 1137 if (error)
1052 break; 1138 break;
1053 1139
1054 info->fix = sh_mobile_lcdc_fix; 1140 info->fix = sh_mobile_lcdc_fix;
1055 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); 1141 info->fix.line_length = lcd_cfg->xres * (cfg->bpp / 8);
1056 info->fix.smem_len = info->fix.line_length * 1142 info->fix.smem_len = info->fix.line_length *
1057 info->var.yres_virtual; 1143 var->yres_virtual;
1058 1144
1059 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, 1145 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
1060 &priv->ch[i].dma_handle, GFP_KERNEL); 1146 &priv->ch[i].dma_handle, GFP_KERNEL);
@@ -1119,10 +1205,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1119 ch->cfg.bpp); 1205 ch->cfg.bpp);
1120 1206
1121 /* deferred io mode: disable clock to save power */ 1207 /* deferred io mode: disable clock to save power */
1122 if (info->fbdefio) 1208 if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
1123 sh_mobile_lcdc_clk_off(priv); 1209 sh_mobile_lcdc_clk_off(priv);
1124 } 1210 }
1125 1211
1212 /* Failure ignored */
1213 priv->notifier.notifier_call = sh_mobile_lcdc_notify;
1214 fb_register_client(&priv->notifier);
1215
1126 return 0; 1216 return 0;
1127err1: 1217err1:
1128 sh_mobile_lcdc_remove(pdev); 1218 sh_mobile_lcdc_remove(pdev);
@@ -1136,6 +1226,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
1136 struct fb_info *info; 1226 struct fb_info *info;
1137 int i; 1227 int i;
1138 1228
1229 fb_unregister_client(&priv->notifier);
1230
1139 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) 1231 for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
1140 if (priv->ch[i].info && priv->ch[i].info->dev) 1232 if (priv->ch[i].info && priv->ch[i].info->dev)
1141 unregister_framebuffer(priv->ch[i].info); 1233 unregister_framebuffer(priv->ch[i].info);
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c
index 489b44e8db81..5dbe06af2226 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/sunxvr1000.c
@@ -111,7 +111,7 @@ static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
111 return 0; 111 return 0;
112} 112}
113 113
114static int __devinit gfb_probe(struct of_device *op, 114static int __devinit gfb_probe(struct platform_device *op,
115 const struct of_device_id *match) 115 const struct of_device_id *match)
116{ 116{
117 struct device_node *dp = op->dev.of_node; 117 struct device_node *dp = op->dev.of_node;
@@ -172,7 +172,7 @@ err_out:
172 return err; 172 return err;
173} 173}
174 174
175static int __devexit gfb_remove(struct of_device *op) 175static int __devexit gfb_remove(struct platform_device *op)
176{ 176{
177 struct fb_info *info = dev_get_drvdata(&op->dev); 177 struct fb_info *info = dev_get_drvdata(&op->dev);
178 struct gfb_info *gp = info->par; 178 struct gfb_info *gp = info->par;
@@ -213,12 +213,12 @@ static int __init gfb_init(void)
213 if (fb_get_options("gfb", NULL)) 213 if (fb_get_options("gfb", NULL))
214 return -ENODEV; 214 return -ENODEV;
215 215
216 return of_register_driver(&gfb_driver, &of_bus_type); 216 return of_register_platform_driver(&gfb_driver);
217} 217}
218 218
219static void __exit gfb_exit(void) 219static void __exit gfb_exit(void)
220{ 220{
221 of_unregister_driver(&gfb_driver); 221 of_unregister_platform_driver(&gfb_driver);
222} 222}
223 223
224module_init(gfb_init); 224module_init(gfb_init);
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index cc039b33d2d8..77ad27955cf0 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -342,7 +342,7 @@ tcx_init_fix(struct fb_info *info, int linebytes)
342 info->fix.accel = FB_ACCEL_SUN_TCX; 342 info->fix.accel = FB_ACCEL_SUN_TCX;
343} 343}
344 344
345static void tcx_unmap_regs(struct of_device *op, struct fb_info *info, 345static void tcx_unmap_regs(struct platform_device *op, struct fb_info *info,
346 struct tcx_par *par) 346 struct tcx_par *par)
347{ 347{
348 if (par->tec) 348 if (par->tec)
@@ -362,7 +362,7 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
362 info->screen_base, info->fix.smem_len); 362 info->screen_base, info->fix.smem_len);
363} 363}
364 364
365static int __devinit tcx_probe(struct of_device *op, 365static int __devinit tcx_probe(struct platform_device *op,
366 const struct of_device_id *match) 366 const struct of_device_id *match)
367{ 367{
368 struct device_node *dp = op->dev.of_node; 368 struct device_node *dp = op->dev.of_node;
@@ -486,7 +486,7 @@ out_err:
486 return err; 486 return err;
487} 487}
488 488
489static int __devexit tcx_remove(struct of_device *op) 489static int __devexit tcx_remove(struct platform_device *op)
490{ 490{
491 struct fb_info *info = dev_get_drvdata(&op->dev); 491 struct fb_info *info = dev_get_drvdata(&op->dev);
492 struct tcx_par *par = info->par; 492 struct tcx_par *par = info->par;
@@ -526,12 +526,12 @@ static int __init tcx_init(void)
526 if (fb_get_options("tcxfb", NULL)) 526 if (fb_get_options("tcxfb", NULL))
527 return -ENODEV; 527 return -ENODEV;
528 528
529 return of_register_driver(&tcx_driver, &of_bus_type); 529 return of_register_platform_driver(&tcx_driver);
530} 530}
531 531
532static void __exit tcx_exit(void) 532static void __exit tcx_exit(void)
533{ 533{
534 of_unregister_driver(&tcx_driver); 534 of_unregister_platform_driver(&tcx_driver);
535} 535}
536 536
537module_init(tcx_init); 537module_init(tcx_init);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 980548390048..3ee5e63cfa4f 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1571,8 +1571,8 @@ out_err_iobase:
1571 if (default_par->mtrr_handle >= 0) 1571 if (default_par->mtrr_handle >= 0)
1572 mtrr_del(default_par->mtrr_handle, info->fix.smem_start, 1572 mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
1573 info->fix.smem_len); 1573 info->fix.smem_len);
1574 release_mem_region(pci_resource_start(pdev, 2), 1574 release_region(pci_resource_start(pdev, 2),
1575 pci_resource_len(pdev, 2)); 1575 pci_resource_len(pdev, 2));
1576out_err_screenbase: 1576out_err_screenbase:
1577 if (info->screen_base) 1577 if (info->screen_base)
1578 iounmap(info->screen_base); 1578 iounmap(info->screen_base);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 1b3b1c718e80..aba7686b1a32 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -305,7 +305,7 @@ tgafb_set_par(struct fb_info *info)
305 TGA_WRITE_REG(par, htimings, TGA_HORIZ_REG); 305 TGA_WRITE_REG(par, htimings, TGA_HORIZ_REG);
306 TGA_WRITE_REG(par, vtimings, TGA_VERT_REG); 306 TGA_WRITE_REG(par, vtimings, TGA_VERT_REG);
307 307
308 /* Initalise RAMDAC. */ 308 /* Initialise RAMDAC. */
309 if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) { 309 if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
310 310
311 /* Init BT485 RAMDAC registers. */ 311 /* Init BT485 RAMDAC registers. */
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 7b8839ebf3c4..52ec0959d462 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -1977,8 +1977,7 @@ static void __devexit uvesafb_exit(void)
1977 1977
1978module_exit(uvesafb_exit); 1978module_exit(uvesafb_exit);
1979 1979
1980#define param_get_scroll NULL 1980static int param_set_scroll(const char *val, const struct kernel_param *kp)
1981static int param_set_scroll(const char *val, struct kernel_param *kp)
1982{ 1981{
1983 ypan = 0; 1982 ypan = 0;
1984 1983
@@ -1993,7 +1992,9 @@ static int param_set_scroll(const char *val, struct kernel_param *kp)
1993 1992
1994 return 0; 1993 return 0;
1995} 1994}
1996 1995static struct kernel_param_ops param_ops_scroll = {
1996 .set = param_set_scroll,
1997};
1997#define param_check_scroll(name, p) __param_check(name, p, void) 1998#define param_check_scroll(name, p) __param_check(name, p, void)
1998 1999
1999module_param_named(scroll, ypan, scroll, 0); 2000module_param_named(scroll, ypan, scroll, 0);
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index d9b6e06e0700..ef1f3de2e052 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -160,7 +160,6 @@ struct lvds_setting_information {
160 int v_active; 160 int v_active;
161 int bpp; 161 int bpp;
162 int refresh_rate; 162 int refresh_rate;
163 int get_lcd_size_method;
164 int lcd_panel_id; 163 int lcd_panel_id;
165 int lcd_panel_hres; 164 int lcd_panel_hres;
166 int lcd_panel_vres; 165 int lcd_panel_vres;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index b996803ae2c1..7dcb4d5bb9c3 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -23,143 +23,341 @@
23#include "global.h" 23#include "global.h"
24 24
25static struct pll_map pll_value[] = { 25static struct pll_map pll_value[] = {
26 {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, 26 {25175000,
27 CX700_25_175M, VX855_25_175M}, 27 {99, 7, 3},
28 {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, 28 {85, 3, 4}, /* ignoring bit difference: 0x00008000 */
29 CX700_29_581M, VX855_29_581M}, 29 {141, 5, 4},
30 {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, 30 {141, 5, 4} },
31 CX700_26_880M, VX855_26_880M}, 31 {29581000,
32 {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, 32 {33, 4, 2},
33 CX700_31_490M, VX855_31_490M}, 33 {66, 2, 4}, /* ignoring bit difference: 0x00808000 */
34 {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, 34 {166, 5, 4}, /* ignoring bit difference: 0x00008000 */
35 CX700_31_500M, VX855_31_500M}, 35 {165, 5, 4} },
36 {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, 36 {26880000,
37 CX700_31_728M, VX855_31_728M}, 37 {15, 4, 1},
38 {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, 38 {30, 2, 3}, /* ignoring bit difference: 0x00808000 */
39 CX700_32_668M, VX855_32_668M}, 39 {150, 5, 4},
40 {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, 40 {150, 5, 4} },
41 CX700_36_000M, VX855_36_000M}, 41 {31500000,
42 {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, 42 {53, 3, 3}, /* ignoring bit difference: 0x00008000 */
43 CX700_40_000M, VX855_40_000M}, 43 {141, 4, 4}, /* ignoring bit difference: 0x00008000 */
44 {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, 44 {176, 5, 4},
45 CX700_41_291M, VX855_41_291M}, 45 {176, 5, 4} },
46 {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, 46 {31728000,
47 CX700_43_163M, VX855_43_163M}, 47 {31, 7, 1},
48 {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, 48 {177, 5, 4}, /* ignoring bit difference: 0x00008000 */
49 CX700_45_250M, VX855_45_250M}, 49 {177, 5, 4},
50 {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, 50 {142, 4, 4} },
51 CX700_46_000M, VX855_46_000M}, 51 {32688000,
52 {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, 52 {73, 4, 3},
53 CX700_46_996M, VX855_46_996M}, 53 {146, 4, 4}, /* ignoring bit difference: 0x00008000 */
54 {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, 54 {183, 5, 4},
55 CX700_48_000M, VX855_48_000M}, 55 {146, 4, 4} },
56 {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, 56 {36000000,
57 CX700_48_875M, VX855_48_875M}, 57 {101, 5, 3}, /* ignoring bit difference: 0x00008000 */
58 {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, 58 {161, 4, 4}, /* ignoring bit difference: 0x00008000 */
59 CX700_49_500M, VX855_49_500M}, 59 {202, 5, 4},
60 {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, 60 {161, 4, 4} },
61 CX700_52_406M, VX855_52_406M}, 61 {40000000,
62 {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, 62 {89, 4, 3},
63 CX700_52_977M, VX855_52_977M}, 63 {89, 4, 3}, /* ignoring bit difference: 0x00008000 */
64 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, 64 {112, 5, 3},
65 CX700_56_250M, VX855_56_250M}, 65 {112, 5, 3} },
66 {CLK_57_275M, 0, 0, 0, VX855_57_275M}, 66 {41291000,
67 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, 67 {23, 4, 1},
68 CX700_60_466M, VX855_60_466M}, 68 {69, 3, 3}, /* ignoring bit difference: 0x00008000 */
69 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, 69 {115, 5, 3},
70 CX700_61_500M, VX855_61_500M}, 70 {115, 5, 3} },
71 {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, 71 {43163000,
72 CX700_65_000M, VX855_65_000M}, 72 {121, 5, 3},
73 {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, 73 {121, 5, 3}, /* ignoring bit difference: 0x00008000 */
74 CX700_65_178M, VX855_65_178M}, 74 {121, 5, 3},
75 {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, 75 {121, 5, 3} },
76 CX700_66_750M, VX855_66_750M}, 76 {45250000,
77 {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, 77 {127, 5, 3},
78 CX700_68_179M, VX855_68_179M}, 78 {127, 5, 3}, /* ignoring bit difference: 0x00808000 */
79 {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, 79 {127, 5, 3},
80 CX700_69_924M, VX855_69_924M}, 80 {127, 5, 3} },
81 {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, 81 {46000000,
82 CX700_70_159M, VX855_70_159M}, 82 {90, 7, 2},
83 {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, 83 {103, 4, 3}, /* ignoring bit difference: 0x00008000 */
84 CX700_72_000M, VX855_72_000M}, 84 {129, 5, 3},
85 {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, 85 {103, 4, 3} },
86 CX700_78_750M, VX855_78_750M}, 86 {46996000,
87 {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, 87 {105, 4, 3}, /* ignoring bit difference: 0x00008000 */
88 CX700_80_136M, VX855_80_136M}, 88 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */
89 {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, 89 {131, 5, 3}, /* ignoring bit difference: 0x00808000 */
90 CX700_83_375M, VX855_83_375M}, 90 {105, 4, 3} },
91 {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, 91 {48000000,
92 CX700_83_950M, VX855_83_950M}, 92 {67, 20, 0},
93 {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, 93 {134, 5, 3}, /* ignoring bit difference: 0x00808000 */
94 CX700_84_750M, VX855_84_750M}, 94 {134, 5, 3},
95 {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, 95 {134, 5, 3} },
96 CX700_85_860M, VX855_85_860M}, 96 {48875000,
97 {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, 97 {99, 29, 0},
98 CX700_88_750M, VX855_88_750M}, 98 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */
99 {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, 99 {82, 3, 3}, /* ignoring bit difference: 0x00808000 */
100 CX700_94_500M, VX855_94_500M}, 100 {137, 5, 3} },
101 {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, 101 {49500000,
102 CX700_97_750M, VX855_97_750M}, 102 {83, 6, 2},
103 {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M, 103 {83, 3, 3}, /* ignoring bit difference: 0x00008000 */
104 CX700_101_000M, VX855_101_000M}, 104 {138, 5, 3},
105 {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M, 105 {83, 3, 3} },
106 CX700_106_500M, VX855_106_500M}, 106 {52406000,
107 {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M, 107 {117, 4, 3},
108 CX700_108_000M, VX855_108_000M}, 108 {117, 4, 3}, /* ignoring bit difference: 0x00008000 */
109 {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M, 109 {117, 4, 3},
110 CX700_113_309M, VX855_113_309M}, 110 {88, 3, 3} },
111 {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M, 111 {52977000,
112 CX700_118_840M, VX855_118_840M}, 112 {37, 5, 1},
113 {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M, 113 {148, 5, 3}, /* ignoring bit difference: 0x00808000 */
114 CX700_119_000M, VX855_119_000M}, 114 {148, 5, 3},
115 {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M, 115 {148, 5, 3} },
116 CX700_121_750M, 0}, 116 {56250000,
117 {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M, 117 {55, 7, 1}, /* ignoring bit difference: 0x00008000 */
118 CX700_125_104M, 0}, 118 {126, 4, 3}, /* ignoring bit difference: 0x00008000 */
119 {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M, 119 {157, 5, 3},
120 CX700_133_308M, 0}, 120 {157, 5, 3} },
121 {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M, 121 {57275000,
122 CX700_135_000M, VX855_135_000M}, 122 {0, 0, 0},
123 {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M, 123 {2, 2, 0},
124 CX700_136_700M, VX855_136_700M}, 124 {2, 2, 0},
125 {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M, 125 {157, 5, 3} }, /* ignoring bit difference: 0x00808000 */
126 CX700_138_400M, VX855_138_400M}, 126 {60466000,
127 {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M, 127 {76, 9, 1},
128 CX700_146_760M, VX855_146_760M}, 128 {169, 5, 3}, /* ignoring bit difference: 0x00808000 */
129 {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M, 129 {169, 5, 3}, /* FIXED: old = {72, 2, 3} */
130 CX700_153_920M, VX855_153_920M}, 130 {169, 5, 3} },
131 {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M, 131 {61500000,
132 CX700_156_000M, VX855_156_000M}, 132 {86, 20, 0},
133 {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M, 133 {172, 5, 3}, /* ignoring bit difference: 0x00808000 */
134 CX700_157_500M, VX855_157_500M}, 134 {172, 5, 3},
135 {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M, 135 {172, 5, 3} },
136 CX700_162_000M, VX855_162_000M}, 136 {65000000,
137 {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M, 137 {109, 6, 2}, /* ignoring bit difference: 0x00008000 */
138 CX700_187_000M, VX855_187_000M}, 138 {109, 3, 3}, /* ignoring bit difference: 0x00008000 */
139 {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M, 139 {109, 3, 3},
140 CX700_193_295M, VX855_193_295M}, 140 {109, 3, 3} },
141 {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M, 141 {65178000,
142 CX700_202_500M, VX855_202_500M}, 142 {91, 5, 2},
143 {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M, 143 {182, 5, 3}, /* ignoring bit difference: 0x00808000 */
144 CX700_204_000M, VX855_204_000M}, 144 {109, 3, 3},
145 {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M, 145 {182, 5, 3} },
146 CX700_218_500M, VX855_218_500M}, 146 {66750000,
147 {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M, 147 {75, 4, 2},
148 CX700_234_000M, VX855_234_000M}, 148 {150, 4, 3}, /* ignoring bit difference: 0x00808000 */
149 {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M, 149 {150, 4, 3},
150 CX700_267_250M, VX855_267_250M}, 150 {112, 3, 3} },
151 {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M, 151 {68179000,
152 CX700_297_500M, VX855_297_500M}, 152 {19, 4, 0},
153 {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, 153 {114, 3, 3}, /* ignoring bit difference: 0x00008000 */
154 CX700_74_481M, VX855_74_481M}, 154 {190, 5, 3},
155 {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M, 155 {191, 5, 3} },
156 CX700_172_798M, VX855_172_798M}, 156 {69924000,
157 {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M, 157 {83, 17, 0},
158 CX700_122_614M, VX855_122_614M}, 158 {195, 5, 3}, /* ignoring bit difference: 0x00808000 */
159 {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, 159 {195, 5, 3},
160 CX700_74_270M, 0}, 160 {195, 5, 3} },
161 {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M, 161 {70159000,
162 CX700_148_500M, VX855_148_500M} 162 {98, 20, 0},
163 {196, 5, 3}, /* ignoring bit difference: 0x00808000 */
164 {196, 5, 3},
165 {195, 5, 3} },
166 {72000000,
167 {121, 24, 0},
168 {161, 4, 3}, /* ignoring bit difference: 0x00808000 */
169 {161, 4, 3},
170 {161, 4, 3} },
171 {78750000,
172 {33, 3, 1},
173 {66, 3, 2}, /* ignoring bit difference: 0x00008000 */
174 {110, 5, 2},
175 {110, 5, 2} },
176 {80136000,
177 {28, 5, 0},
178 {68, 3, 2}, /* ignoring bit difference: 0x00008000 */
179 {112, 5, 2},
180 {112, 5, 2} },
181 {83375000,
182 {93, 2, 3},
183 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */
184 {93, 4, 2}, /* ignoring bit difference: 0x00800000 */
185 {117, 5, 2} },
186 {83950000,
187 {41, 7, 0},
188 {117, 5, 2}, /* ignoring bit difference: 0x00008000 */
189 {117, 5, 2},
190 {117, 5, 2} },
191 {84750000,
192 {118, 5, 2},
193 {118, 5, 2}, /* ignoring bit difference: 0x00808000 */
194 {118, 5, 2},
195 {118, 5, 2} },
196 {85860000,
197 {84, 7, 1},
198 {120, 5, 2}, /* ignoring bit difference: 0x00808000 */
199 {120, 5, 2},
200 {118, 5, 2} },
201 {88750000,
202 {31, 5, 0},
203 {124, 5, 2}, /* ignoring bit difference: 0x00808000 */
204 {174, 7, 2}, /* ignoring bit difference: 0x00808000 */
205 {124, 5, 2} },
206 {94500000,
207 {33, 5, 0},
208 {132, 5, 2}, /* ignoring bit difference: 0x00008000 */
209 {132, 5, 2},
210 {132, 5, 2} },
211 {97750000,
212 {82, 6, 1},
213 {137, 5, 2}, /* ignoring bit difference: 0x00808000 */
214 {137, 5, 2},
215 {137, 5, 2} },
216 {101000000,
217 {127, 9, 1},
218 {141, 5, 2}, /* ignoring bit difference: 0x00808000 */
219 {141, 5, 2},
220 {141, 5, 2} },
221 {106500000,
222 {119, 4, 2},
223 {119, 4, 2}, /* ignoring bit difference: 0x00808000 */
224 {119, 4, 2},
225 {149, 5, 2} },
226 {108000000,
227 {121, 4, 2},
228 {121, 4, 2}, /* ignoring bit difference: 0x00808000 */
229 {151, 5, 2},
230 {151, 5, 2} },
231 {113309000,
232 {95, 12, 0},
233 {95, 3, 2}, /* ignoring bit difference: 0x00808000 */
234 {95, 3, 2},
235 {159, 5, 2} },
236 {118840000,
237 {83, 5, 1},
238 {166, 5, 2}, /* ignoring bit difference: 0x00808000 */
239 {166, 5, 2},
240 {166, 5, 2} },
241 {119000000,
242 {108, 13, 0},
243 {133, 4, 2}, /* ignoring bit difference: 0x00808000 */
244 {133, 4, 2},
245 {167, 5, 2} },
246 {121750000,
247 {85, 5, 1},
248 {170, 5, 2}, /* ignoring bit difference: 0x00808000 */
249 {68, 2, 2},
250 {0, 0, 0} },
251 {125104000,
252 {53, 6, 0}, /* ignoring bit difference: 0x00008000 */
253 {106, 3, 2}, /* ignoring bit difference: 0x00008000 */
254 {175, 5, 2},
255 {0, 0, 0} },
256 {135000000,
257 {94, 5, 1},
258 {28, 3, 0}, /* ignoring bit difference: 0x00804000 */
259 {151, 4, 2},
260 {189, 5, 2} },
261 {136700000,
262 {115, 12, 0},
263 {191, 5, 2}, /* ignoring bit difference: 0x00808000 */
264 {191, 5, 2},
265 {191, 5, 2} },
266 {138400000,
267 {87, 9, 0},
268 {116, 3, 2}, /* ignoring bit difference: 0x00808000 */
269 {116, 3, 2},
270 {194, 5, 2} },
271 {146760000,
272 {103, 5, 1},
273 {206, 5, 2}, /* ignoring bit difference: 0x00808000 */
274 {206, 5, 2},
275 {206, 5, 2} },
276 {153920000,
277 {86, 8, 0},
278 {86, 4, 1}, /* ignoring bit difference: 0x00808000 */
279 {86, 4, 1},
280 {86, 4, 1} }, /* FIXED: old = {84, 2, 1} */
281 {156000000,
282 {109, 5, 1},
283 {109, 5, 1}, /* ignoring bit difference: 0x00808000 */
284 {109, 5, 1},
285 {108, 5, 1} },
286 {157500000,
287 {55, 5, 0}, /* ignoring bit difference: 0x00008000 */
288 {22, 2, 0}, /* ignoring bit difference: 0x00802000 */
289 {110, 5, 1},
290 {110, 5, 1} },
291 {162000000,
292 {113, 5, 1},
293 {113, 5, 1}, /* ignoring bit difference: 0x00808000 */
294 {113, 5, 1},
295 {113, 5, 1} },
296 {187000000,
297 {118, 9, 0},
298 {131, 5, 1}, /* ignoring bit difference: 0x00808000 */
299 {131, 5, 1},
300 {131, 5, 1} },
301 {193295000,
302 {108, 8, 0},
303 {81, 3, 1}, /* ignoring bit difference: 0x00808000 */
304 {135, 5, 1},
305 {135, 5, 1} },
306 {202500000,
307 {99, 7, 0},
308 {85, 3, 1}, /* ignoring bit difference: 0x00808000 */
309 {142, 5, 1},
310 {142, 5, 1} },
311 {204000000,
312 {100, 7, 0},
313 {143, 5, 1}, /* ignoring bit difference: 0x00808000 */
314 {143, 5, 1},
315 {143, 5, 1} },
316 {218500000,
317 {92, 6, 0},
318 {153, 5, 1}, /* ignoring bit difference: 0x00808000 */
319 {153, 5, 1},
320 {153, 5, 1} },
321 {234000000,
322 {98, 6, 0},
323 {98, 3, 1}, /* ignoring bit difference: 0x00008000 */
324 {98, 3, 1},
325 {164, 5, 1} },
326 {267250000,
327 {112, 6, 0},
328 {112, 3, 1}, /* ignoring bit difference: 0x00808000 */
329 {187, 5, 1},
330 {187, 5, 1} },
331 {297500000,
332 {102, 5, 0}, /* ignoring bit difference: 0x00008000 */
333 {166, 4, 1}, /* ignoring bit difference: 0x00008000 */
334 {208, 5, 1},
335 {208, 5, 1} },
336 {74481000,
337 {26, 5, 0},
338 {125, 3, 3}, /* ignoring bit difference: 0x00808000 */
339 {208, 5, 3},
340 {209, 5, 3} },
341 {172798000,
342 {121, 5, 1},
343 {121, 5, 1}, /* ignoring bit difference: 0x00808000 */
344 {121, 5, 1},
345 {121, 5, 1} },
346 {122614000,
347 {60, 7, 0},
348 {137, 4, 2}, /* ignoring bit difference: 0x00808000 */
349 {137, 4, 2},
350 {172, 5, 2} },
351 {74270000,
352 {83, 8, 1},
353 {208, 5, 3},
354 {208, 5, 3},
355 {0, 0, 0} },
356 {148500000,
357 {83, 8, 0},
358 {208, 5, 2},
359 {166, 4, 2},
360 {208, 5, 2} }
163}; 361};
164 362
165static struct fifo_depth_select display_fifo_depth_reg = { 363static struct fifo_depth_select display_fifo_depth_reg = {
@@ -1360,40 +1558,70 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1360 1558
1361} 1559}
1362 1560
1561static u32 cle266_encode_pll(struct pll_config pll)
1562{
1563 return (pll.multiplier << 8)
1564 | (pll.rshift << 6)
1565 | pll.divisor;
1566}
1567
1568static u32 k800_encode_pll(struct pll_config pll)
1569{
1570 return ((pll.divisor - 2) << 16)
1571 | (pll.rshift << 10)
1572 | (pll.multiplier - 2);
1573}
1574
1575static u32 vx855_encode_pll(struct pll_config pll)
1576{
1577 return (pll.divisor << 16)
1578 | (pll.rshift << 10)
1579 | pll.multiplier;
1580}
1581
1363u32 viafb_get_clk_value(int clk) 1582u32 viafb_get_clk_value(int clk)
1364{ 1583{
1365 int i; 1584 u32 value = 0;
1585 int i = 0;
1366 1586
1367 for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) { 1587 while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk)
1368 if (clk == pll_value[i].clk) { 1588 i++;
1369 switch (viaparinfo->chip_info->gfx_chip_name) { 1589
1370 case UNICHROME_CLE266: 1590 if (i == NUM_TOTAL_PLL_TABLE) {
1371 case UNICHROME_K400: 1591 printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!");
1372 return pll_value[i].cle266_pll; 1592 } else {
1373 1593 switch (viaparinfo->chip_info->gfx_chip_name) {
1374 case UNICHROME_K800: 1594 case UNICHROME_CLE266:
1375 case UNICHROME_PM800: 1595 case UNICHROME_K400:
1376 case UNICHROME_CN700: 1596 value = cle266_encode_pll(pll_value[i].cle266_pll);
1377 return pll_value[i].k800_pll; 1597 break;
1378 1598
1379 case UNICHROME_CX700: 1599 case UNICHROME_K800:
1380 case UNICHROME_K8M890: 1600 case UNICHROME_PM800:
1381 case UNICHROME_P4M890: 1601 case UNICHROME_CN700:
1382 case UNICHROME_P4M900: 1602 value = k800_encode_pll(pll_value[i].k800_pll);
1383 case UNICHROME_VX800: 1603 break;
1384 return pll_value[i].cx700_pll; 1604
1385 case UNICHROME_VX855: 1605 case UNICHROME_CX700:
1386 return pll_value[i].vx855_pll; 1606 case UNICHROME_CN750:
1387 } 1607 case UNICHROME_K8M890:
1608 case UNICHROME_P4M890:
1609 case UNICHROME_P4M900:
1610 case UNICHROME_VX800:
1611 value = k800_encode_pll(pll_value[i].cx700_pll);
1612 break;
1613
1614 case UNICHROME_VX855:
1615 value = vx855_encode_pll(pll_value[i].vx855_pll);
1616 break;
1388 } 1617 }
1389 } 1618 }
1390 1619
1391 DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n"); 1620 return value;
1392 return 0;
1393} 1621}
1394 1622
1395/* Set VCLK*/ 1623/* Set VCLK*/
1396void viafb_set_vclock(u32 CLK, int set_iga) 1624void viafb_set_vclock(u32 clk, int set_iga)
1397{ 1625{
1398 /* H.W. Reset : ON */ 1626 /* H.W. Reset : ON */
1399 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1627 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
@@ -1403,26 +1631,23 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1403 switch (viaparinfo->chip_info->gfx_chip_name) { 1631 switch (viaparinfo->chip_info->gfx_chip_name) {
1404 case UNICHROME_CLE266: 1632 case UNICHROME_CLE266:
1405 case UNICHROME_K400: 1633 case UNICHROME_K400:
1406 viafb_write_reg(SR46, VIASR, CLK / 0x100); 1634 via_write_reg(VIASR, SR46, (clk & 0x00FF));
1407 viafb_write_reg(SR47, VIASR, CLK % 0x100); 1635 via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1408 break; 1636 break;
1409 1637
1410 case UNICHROME_K800: 1638 case UNICHROME_K800:
1411 case UNICHROME_PM800: 1639 case UNICHROME_PM800:
1412 case UNICHROME_CN700: 1640 case UNICHROME_CN700:
1413 case UNICHROME_CX700: 1641 case UNICHROME_CX700:
1642 case UNICHROME_CN750:
1414 case UNICHROME_K8M890: 1643 case UNICHROME_K8M890:
1415 case UNICHROME_P4M890: 1644 case UNICHROME_P4M890:
1416 case UNICHROME_P4M900: 1645 case UNICHROME_P4M900:
1417 case UNICHROME_VX800: 1646 case UNICHROME_VX800:
1418 case UNICHROME_VX855: 1647 case UNICHROME_VX855:
1419 viafb_write_reg(SR44, VIASR, CLK / 0x10000); 1648 via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1420 DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000); 1649 via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1421 viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100); 1650 via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1422 DEBUG_MSG(KERN_INFO "\nSR45=%x",
1423 (CLK & 0xFFFF) / 0x100);
1424 viafb_write_reg(SR46, VIASR, CLK % 0x100);
1425 DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
1426 break; 1651 break;
1427 } 1652 }
1428 } 1653 }
@@ -1432,22 +1657,23 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1432 switch (viaparinfo->chip_info->gfx_chip_name) { 1657 switch (viaparinfo->chip_info->gfx_chip_name) {
1433 case UNICHROME_CLE266: 1658 case UNICHROME_CLE266:
1434 case UNICHROME_K400: 1659 case UNICHROME_K400:
1435 viafb_write_reg(SR44, VIASR, CLK / 0x100); 1660 via_write_reg(VIASR, SR44, (clk & 0x00FF));
1436 viafb_write_reg(SR45, VIASR, CLK % 0x100); 1661 via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1437 break; 1662 break;
1438 1663
1439 case UNICHROME_K800: 1664 case UNICHROME_K800:
1440 case UNICHROME_PM800: 1665 case UNICHROME_PM800:
1441 case UNICHROME_CN700: 1666 case UNICHROME_CN700:
1442 case UNICHROME_CX700: 1667 case UNICHROME_CX700:
1668 case UNICHROME_CN750:
1443 case UNICHROME_K8M890: 1669 case UNICHROME_K8M890:
1444 case UNICHROME_P4M890: 1670 case UNICHROME_P4M890:
1445 case UNICHROME_P4M900: 1671 case UNICHROME_P4M900:
1446 case UNICHROME_VX800: 1672 case UNICHROME_VX800:
1447 case UNICHROME_VX855: 1673 case UNICHROME_VX855:
1448 viafb_write_reg(SR4A, VIASR, CLK / 0x10000); 1674 via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1449 viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100); 1675 via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1450 viafb_write_reg(SR4C, VIASR, CLK % 0x100); 1676 via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1451 break; 1677 break;
1452 } 1678 }
1453 } 1679 }
@@ -1791,8 +2017,6 @@ void viafb_init_chip_info(int chip_type)
1791 viafb_set_iga_path(); 2017 viafb_set_iga_path();
1792 2018
1793 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method; 2019 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
1794 viaparinfo->lvds_setting_info->get_lcd_size_method =
1795 GET_LCD_SIZE_BY_USER_SETTING;
1796 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode; 2020 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
1797 viaparinfo->lvds_setting_info2->display_method = 2021 viaparinfo->lvds_setting_info2->display_method =
1798 viaparinfo->lvds_setting_info->display_method; 2022 viaparinfo->lvds_setting_info->display_method;
@@ -1946,13 +2170,6 @@ static void init_tmds_chip_info(void)
1946 2170
1947static void init_lvds_chip_info(void) 2171static void init_lvds_chip_info(void)
1948{ 2172{
1949 if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
1950 viaparinfo->lvds_setting_info->get_lcd_size_method =
1951 GET_LCD_SIZE_BY_VGA_BIOS;
1952 else
1953 viaparinfo->lvds_setting_info->get_lcd_size_method =
1954 GET_LCD_SIZE_BY_USER_SETTING;
1955
1956 viafb_lvds_trasmitter_identify(); 2173 viafb_lvds_trasmitter_identify();
1957 viafb_init_lcd_size(); 2174 viafb_init_lcd_size();
1958 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info, 2175 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index a109de379816..c44399895294 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -700,12 +700,18 @@ struct _lcd_scaling_factor {
700 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; 700 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
701}; 701};
702 702
703struct pll_config {
704 u16 multiplier;
705 u8 divisor;
706 u8 rshift;
707};
708
703struct pll_map { 709struct pll_map {
704 u32 clk; 710 u32 clk;
705 u32 cle266_pll; 711 struct pll_config cle266_pll;
706 u32 k800_pll; 712 struct pll_config k800_pll;
707 u32 cx700_pll; 713 struct pll_config cx700_pll;
708 u32 vx855_pll; 714 struct pll_config vx855_pll;
709}; 715};
710 716
711struct rgbLUT { 717struct rgbLUT {
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
index c430fa23008a..6010d10b59e8 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/via/ioctl.h
@@ -35,11 +35,9 @@
35#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */ 35#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */
36#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */ 36#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */
37#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */ 37#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */
38#define VIAFB_SET_DEVICE 0x5649410A
39#define VIAFB_GET_DEVICE 0x5649410B 38#define VIAFB_GET_DEVICE 0x5649410B
40#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */ 39#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */
41#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */ 40#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */
42#define VIAFB_SET_DEVICE_INFO 0x56494114
43#define VIAFB_GET_DEVICE_INFO 0x56494115 41#define VIAFB_GET_DEVICE_INFO 0x56494115
44 42
45#define VIAFB_GET_DEVICE_SUPPORT 0x56494118 43#define VIAFB_GET_DEVICE_SUPPORT 0x56494118
@@ -50,7 +48,6 @@
50#define VIAFB_GET_GAMMA_LUT 0x56494124 48#define VIAFB_GET_GAMMA_LUT 0x56494124
51#define VIAFB_SET_GAMMA_LUT 0x56494125 49#define VIAFB_SET_GAMMA_LUT 0x56494125
52#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126 50#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
53#define VIAFB_SET_SECOND_MODE 0x56494129
54#define VIAFB_SYNC_SURFACE 0x56494130 51#define VIAFB_SYNC_SURFACE 0x56494130
55#define VIAFB_GET_DRIVER_CAPS 0x56494131 52#define VIAFB_GET_DRIVER_CAPS 0x56494131
56#define VIAFB_GET_IGA_SCALING_INFO 0x56494132 53#define VIAFB_GET_IGA_SCALING_INFO 0x56494132
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 2ab0f156439a..fc25ae30c5f6 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -75,8 +75,6 @@ static void check_diport_of_integrated_lvds(
75static struct display_timing lcd_centering_timging(struct display_timing 75static struct display_timing lcd_centering_timging(struct display_timing
76 mode_crt_reg, 76 mode_crt_reg,
77 struct display_timing panel_crt_reg); 77 struct display_timing panel_crt_reg);
78static void viafb_load_scaling_factor_for_p4m900(int set_hres,
79 int set_vres, int panel_hres, int panel_vres);
80 78
81static int check_lvds_chip(int device_id_subaddr, int device_id) 79static int check_lvds_chip(int device_id_subaddr, int device_id)
82{ 80{
@@ -89,33 +87,8 @@ static int check_lvds_chip(int device_id_subaddr, int device_id)
89void viafb_init_lcd_size(void) 87void viafb_init_lcd_size(void)
90{ 88{
91 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); 89 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
92 DEBUG_MSG(KERN_INFO
93 "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
94 viaparinfo->lvds_setting_info->get_lcd_size_method);
95 90
96 switch (viaparinfo->lvds_setting_info->get_lcd_size_method) { 91 fp_id_to_vindex(viafb_lcd_panel_id);
97 case GET_LCD_SIZE_BY_SYSTEM_BIOS:
98 break;
99 case GET_LCD_SZIE_BY_HW_STRAPPING:
100 break;
101 case GET_LCD_SIZE_BY_VGA_BIOS:
102 DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
103 fp_id_to_vindex(viafb_lcd_panel_id);
104 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
105 viaparinfo->lvds_setting_info->lcd_panel_id);
106 break;
107 case GET_LCD_SIZE_BY_USER_SETTING:
108 DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
109 fp_id_to_vindex(viafb_lcd_panel_id);
110 DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
111 viaparinfo->lvds_setting_info->lcd_panel_id);
112 break;
113 default:
114 DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
115 viaparinfo->lvds_setting_info->lcd_panel_id =
116 LCD_PANEL_ID1_800X600;
117 fp_id_to_vindex(LCD_PANEL_ID1_800X600);
118 }
119 viaparinfo->lvds_setting_info2->lcd_panel_id = 92 viaparinfo->lvds_setting_info2->lcd_panel_id =
120 viaparinfo->lvds_setting_info->lcd_panel_id; 93 viaparinfo->lvds_setting_info->lcd_panel_id;
121 viaparinfo->lvds_setting_info2->lcd_panel_hres = 94 viaparinfo->lvds_setting_info2->lcd_panel_hres =
@@ -437,14 +410,9 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
437 410
438 /* LCD Scaling Enable */ 411 /* LCD Scaling Enable */
439 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2); 412 viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
440 if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
441 viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
442 panel_hres, panel_vres);
443 return;
444 }
445 413
446 /* Check if expansion for horizontal */ 414 /* Check if expansion for horizontal */
447 if (set_hres != panel_hres) { 415 if (set_hres < panel_hres) {
448 /* Load Horizontal Scaling Factor */ 416 /* Load Horizontal Scaling Factor */
449 switch (viaparinfo->chip_info->gfx_chip_name) { 417 switch (viaparinfo->chip_info->gfx_chip_name) {
450 case UNICHROME_CLE266: 418 case UNICHROME_CLE266:
@@ -464,6 +432,10 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
464 case UNICHROME_CX700: 432 case UNICHROME_CX700:
465 case UNICHROME_K8M890: 433 case UNICHROME_K8M890:
466 case UNICHROME_P4M890: 434 case UNICHROME_P4M890:
435 case UNICHROME_P4M900:
436 case UNICHROME_CN750:
437 case UNICHROME_VX800:
438 case UNICHROME_VX855:
467 reg_value = 439 reg_value =
468 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); 440 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
469 /* Horizontal scaling enabled */ 441 /* Horizontal scaling enabled */
@@ -483,7 +455,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
483 } 455 }
484 456
485 /* Check if expansion for vertical */ 457 /* Check if expansion for vertical */
486 if (set_vres != panel_vres) { 458 if (set_vres < panel_vres) {
487 /* Load Vertical Scaling Factor */ 459 /* Load Vertical Scaling Factor */
488 switch (viaparinfo->chip_info->gfx_chip_name) { 460 switch (viaparinfo->chip_info->gfx_chip_name) {
489 case UNICHROME_CLE266: 461 case UNICHROME_CLE266:
@@ -503,6 +475,10 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
503 case UNICHROME_CX700: 475 case UNICHROME_CX700:
504 case UNICHROME_K8M890: 476 case UNICHROME_K8M890:
505 case UNICHROME_P4M890: 477 case UNICHROME_P4M890:
478 case UNICHROME_P4M900:
479 case UNICHROME_CN750:
480 case UNICHROME_VX800:
481 case UNICHROME_VX855:
506 reg_value = 482 reg_value =
507 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); 483 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
508 /* Vertical scaling enabled */ 484 /* Vertical scaling enabled */
@@ -648,9 +624,8 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
648 (mode_crt_reg, panel_crt_reg), IGA1); 624 (mode_crt_reg, panel_crt_reg), IGA1);
649 } else { 625 } else {
650 /* Expansion */ 626 /* Expansion */
651 if ((plvds_setting_info->display_method == 627 if (plvds_setting_info->display_method == LCD_EXPANDSION
652 LCD_EXPANDSION) & ((set_hres != panel_hres) 628 && (set_hres < panel_hres || set_vres < panel_vres)) {
653 || (set_vres != panel_vres))) {
654 /* expansion timing IGA2 loaded panel set timing*/ 629 /* expansion timing IGA2 loaded panel set timing*/
655 viafb_load_crtc_timing(panel_crt_reg, IGA2); 630 viafb_load_crtc_timing(panel_crt_reg, IGA2);
656 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n"); 631 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
@@ -1139,69 +1114,3 @@ bool viafb_lcd_get_mobile_state(bool *mobile)
1139 return false; 1114 return false;
1140 } 1115 }
1141} 1116}
1142
1143static void viafb_load_scaling_factor_for_p4m900(int set_hres,
1144 int set_vres, int panel_hres, int panel_vres)
1145{
1146 int h_scaling_factor;
1147 int v_scaling_factor;
1148 u8 cra2 = 0;
1149 u8 cr77 = 0;
1150 u8 cr78 = 0;
1151 u8 cr79 = 0;
1152 u8 cr9f = 0;
1153 /* Check if expansion for horizontal */
1154 if (set_hres < panel_hres) {
1155 /* Load Horizontal Scaling Factor */
1156
1157 /* For VIA_K8M800 or later chipsets. */
1158 h_scaling_factor =
1159 K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
1160 /* HSCaleFactor[1:0] at CR9F[1:0] */
1161 cr9f = h_scaling_factor & 0x0003;
1162 /* HSCaleFactor[9:2] at CR77[7:0] */
1163 cr77 = (h_scaling_factor & 0x03FC) >> 2;
1164 /* HSCaleFactor[11:10] at CR79[5:4] */
1165 cr79 = (h_scaling_factor & 0x0C00) >> 10;
1166 cr79 <<= 4;
1167
1168 /* Horizontal scaling enabled */
1169 cra2 = 0xC0;
1170
1171 DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
1172 h_scaling_factor);
1173 } else {
1174 /* Horizontal scaling disabled */
1175 cra2 = 0x00;
1176 }
1177
1178 /* Check if expansion for vertical */
1179 if (set_vres < panel_vres) {
1180 /* Load Vertical Scaling Factor */
1181
1182 /* For VIA_K8M800 or later chipsets. */
1183 v_scaling_factor =
1184 K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
1185
1186 /* Vertical scaling enabled */
1187 cra2 |= 0x08;
1188 /* VSCaleFactor[0] at CR79[3] */
1189 cr79 |= ((v_scaling_factor & 0x0001) << 3);
1190 /* VSCaleFactor[8:1] at CR78[7:0] */
1191 cr78 |= (v_scaling_factor & 0x01FE) >> 1;
1192 /* VSCaleFactor[10:9] at CR79[7:6] */
1193 cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
1194
1195 DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
1196 v_scaling_factor);
1197 } else {
1198 /* Vertical scaling disabled */
1199 cra2 |= 0x00;
1200 }
1201
1202 viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
1203 viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
1204 viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
1205 viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
1206 viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
1207}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 9762ec62b495..b348efc360b8 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -28,11 +28,6 @@
28#define VT3271_DEVICE_ID_REG 0x02 28#define VT3271_DEVICE_ID_REG 0x02
29#define VT3271_DEVICE_ID 0x71 29#define VT3271_DEVICE_ID 0x71
30 30
31#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01
32#define GET_LCD_SIZE_BY_VGA_BIOS 0x02
33#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03
34#define GET_LCD_SIZE_BY_USER_SETTING 0x04
35
36/* Definition DVI Panel ID*/ 31/* Definition DVI Panel ID*/
37/* Resolution: 640x480, Channel: single, Dithering: Enable */ 32/* Resolution: 640x480, Channel: single, Dithering: Enable */
38#define LCD_PANEL_ID0_640X480 0x00 33#define LCD_PANEL_ID0_640X480 0x00
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 7f0de7f006ad..2cbe1031b421 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -631,7 +631,6 @@
631#define CLK_25_175M 25175000 631#define CLK_25_175M 25175000
632#define CLK_26_880M 26880000 632#define CLK_26_880M 26880000
633#define CLK_29_581M 29581000 633#define CLK_29_581M 29581000
634#define CLK_31_490M 31490000
635#define CLK_31_500M 31500000 634#define CLK_31_500M 31500000
636#define CLK_31_728M 31728000 635#define CLK_31_728M 31728000
637#define CLK_32_668M 32688000 636#define CLK_32_668M 32688000
@@ -676,7 +675,6 @@
676#define CLK_119_000M 119000000 675#define CLK_119_000M 119000000
677#define CLK_121_750M 121750000 /* 121.704MHz */ 676#define CLK_121_750M 121750000 /* 121.704MHz */
678#define CLK_125_104M 125104000 677#define CLK_125_104M 125104000
679#define CLK_133_308M 133308000
680#define CLK_135_000M 135000000 678#define CLK_135_000M 135000000
681#define CLK_136_700M 136700000 679#define CLK_136_700M 136700000
682#define CLK_138_400M 138400000 680#define CLK_138_400M 138400000
@@ -699,313 +697,6 @@
699#define CLK_172_798M 172798000 697#define CLK_172_798M 172798000
700#define CLK_122_614M 122614000 698#define CLK_122_614M 122614000
701 699
702/* CLE266 PLL value
703*/
704#define CLE266_PLL_25_175M 0x0000C763
705#define CLE266_PLL_26_880M 0x0000440F
706#define CLE266_PLL_29_581M 0x00008421
707#define CLE266_PLL_31_490M 0x00004721
708#define CLE266_PLL_31_500M 0x0000C3B5
709#define CLE266_PLL_31_728M 0x0000471F
710#define CLE266_PLL_32_668M 0x0000C449
711#define CLE266_PLL_36_000M 0x0000C5E5
712#define CLE266_PLL_40_000M 0x0000C459
713#define CLE266_PLL_41_291M 0x00004417
714#define CLE266_PLL_43_163M 0x0000C579
715#define CLE266_PLL_45_250M 0x0000C57F /* 45.46MHz */
716#define CLE266_PLL_46_000M 0x0000875A
717#define CLE266_PLL_46_996M 0x0000C4E9
718#define CLE266_PLL_48_000M 0x00001443
719#define CLE266_PLL_48_875M 0x00001D63
720#define CLE266_PLL_49_500M 0x00008653
721#define CLE266_PLL_52_406M 0x0000C475
722#define CLE266_PLL_52_977M 0x00004525
723#define CLE266_PLL_56_250M 0x000047B7
724#define CLE266_PLL_60_466M 0x0000494C
725#define CLE266_PLL_61_500M 0x00001456
726#define CLE266_PLL_65_000M 0x000086ED
727#define CLE266_PLL_65_178M 0x0000855B
728#define CLE266_PLL_66_750M 0x0000844B /* 67.116MHz */
729#define CLE266_PLL_68_179M 0x00000413
730#define CLE266_PLL_69_924M 0x00001153
731#define CLE266_PLL_70_159M 0x00001462
732#define CLE266_PLL_72_000M 0x00001879
733#define CLE266_PLL_74_270M 0x00004853
734#define CLE266_PLL_78_750M 0x00004321
735#define CLE266_PLL_80_136M 0x0000051C
736#define CLE266_PLL_83_375M 0x0000C25D
737#define CLE266_PLL_83_950M 0x00000729
738#define CLE266_PLL_84_750M 0x00008576 /* 84.537MHz */
739#define CLE266_PLL_85_860M 0x00004754
740#define CLE266_PLL_88_750M 0x0000051F
741#define CLE266_PLL_94_500M 0x00000521
742#define CLE266_PLL_97_750M 0x00004652
743#define CLE266_PLL_101_000M 0x0000497F
744#define CLE266_PLL_106_500M 0x00008477 /* 106.491463 MHz */
745#define CLE266_PLL_108_000M 0x00008479
746#define CLE266_PLL_113_309M 0x00000C5F
747#define CLE266_PLL_118_840M 0x00004553
748#define CLE266_PLL_119_000M 0x00000D6C
749#define CLE266_PLL_121_750M 0x00004555 /* 121.704MHz */
750#define CLE266_PLL_125_104M 0x000006B5
751#define CLE266_PLL_133_308M 0x0000465F
752#define CLE266_PLL_135_000M 0x0000455E
753#define CLE266_PLL_136_700M 0x00000C73
754#define CLE266_PLL_138_400M 0x00000957
755#define CLE266_PLL_146_760M 0x00004567
756#define CLE266_PLL_148_500M 0x00000853
757#define CLE266_PLL_153_920M 0x00000856
758#define CLE266_PLL_156_000M 0x0000456D
759#define CLE266_PLL_157_500M 0x000005B7
760#define CLE266_PLL_162_000M 0x00004571
761#define CLE266_PLL_187_000M 0x00000976
762#define CLE266_PLL_193_295M 0x0000086C
763#define CLE266_PLL_202_500M 0x00000763
764#define CLE266_PLL_204_000M 0x00000764
765#define CLE266_PLL_218_500M 0x0000065C
766#define CLE266_PLL_234_000M 0x00000662
767#define CLE266_PLL_267_250M 0x00000670
768#define CLE266_PLL_297_500M 0x000005E6
769#define CLE266_PLL_74_481M 0x0000051A
770#define CLE266_PLL_172_798M 0x00004579
771#define CLE266_PLL_122_614M 0x0000073C
772
773/* K800 PLL value
774*/
775#define K800_PLL_25_175M 0x00539001
776#define K800_PLL_26_880M 0x001C8C80
777#define K800_PLL_29_581M 0x00409080
778#define K800_PLL_31_490M 0x006F9001
779#define K800_PLL_31_500M 0x008B9002
780#define K800_PLL_31_728M 0x00AF9003
781#define K800_PLL_32_668M 0x00909002
782#define K800_PLL_36_000M 0x009F9002
783#define K800_PLL_40_000M 0x00578C02
784#define K800_PLL_41_291M 0x00438C01
785#define K800_PLL_43_163M 0x00778C03
786#define K800_PLL_45_250M 0x007D8C83 /* 45.46MHz */
787#define K800_PLL_46_000M 0x00658C02
788#define K800_PLL_46_996M 0x00818C83
789#define K800_PLL_48_000M 0x00848C83
790#define K800_PLL_48_875M 0x00508C81
791#define K800_PLL_49_500M 0x00518C01
792#define K800_PLL_52_406M 0x00738C02
793#define K800_PLL_52_977M 0x00928C83
794#define K800_PLL_56_250M 0x007C8C02
795#define K800_PLL_60_466M 0x00A78C83
796#define K800_PLL_61_500M 0x00AA8C83
797#define K800_PLL_65_000M 0x006B8C01
798#define K800_PLL_65_178M 0x00B48C83
799#define K800_PLL_66_750M 0x00948C82 /* 67.116MHz */
800#define K800_PLL_68_179M 0x00708C01
801#define K800_PLL_69_924M 0x00C18C83
802#define K800_PLL_70_159M 0x00C28C83
803#define K800_PLL_72_000M 0x009F8C82
804#define K800_PLL_74_270M 0x00ce0c03
805#define K800_PLL_78_750M 0x00408801
806#define K800_PLL_80_136M 0x00428801
807#define K800_PLL_83_375M 0x005B0882
808#define K800_PLL_83_950M 0x00738803
809#define K800_PLL_84_750M 0x00748883 /* 84.477MHz */
810#define K800_PLL_85_860M 0x00768883
811#define K800_PLL_88_750M 0x007A8883
812#define K800_PLL_94_500M 0x00828803
813#define K800_PLL_97_750M 0x00878883
814#define K800_PLL_101_000M 0x008B8883
815#define K800_PLL_106_500M 0x00758882 /* 106.491463 MHz */
816#define K800_PLL_108_000M 0x00778882
817#define K800_PLL_113_309M 0x005D8881
818#define K800_PLL_118_840M 0x00A48883
819#define K800_PLL_119_000M 0x00838882
820#define K800_PLL_121_750M 0x00A88883 /* 121.704MHz */
821#define K800_PLL_125_104M 0x00688801
822#define K800_PLL_133_308M 0x005D8801
823#define K800_PLL_135_000M 0x001A4081
824#define K800_PLL_136_700M 0x00BD8883
825#define K800_PLL_138_400M 0x00728881
826#define K800_PLL_146_760M 0x00CC8883
827#define K800_PLL_148_500M 0x00ce0803
828#define K800_PLL_153_920M 0x00548482
829#define K800_PLL_156_000M 0x006B8483
830#define K800_PLL_157_500M 0x00142080
831#define K800_PLL_162_000M 0x006F8483
832#define K800_PLL_187_000M 0x00818483
833#define K800_PLL_193_295M 0x004F8481
834#define K800_PLL_202_500M 0x00538481
835#define K800_PLL_204_000M 0x008D8483
836#define K800_PLL_218_500M 0x00978483
837#define K800_PLL_234_000M 0x00608401
838#define K800_PLL_267_250M 0x006E8481
839#define K800_PLL_297_500M 0x00A48402
840#define K800_PLL_74_481M 0x007B8C81
841#define K800_PLL_172_798M 0x00778483
842#define K800_PLL_122_614M 0x00878882
843
844/* PLL for VT3324 */
845#define CX700_25_175M 0x008B1003
846#define CX700_26_719M 0x00931003
847#define CX700_26_880M 0x00941003
848#define CX700_29_581M 0x00A49003
849#define CX700_31_490M 0x00AE1003
850#define CX700_31_500M 0x00AE1003
851#define CX700_31_728M 0x00AF1003
852#define CX700_32_668M 0x00B51003
853#define CX700_36_000M 0x00C81003
854#define CX700_40_000M 0x006E0C03
855#define CX700_41_291M 0x00710C03
856#define CX700_43_163M 0x00770C03
857#define CX700_45_250M 0x007D0C03 /* 45.46MHz */
858#define CX700_46_000M 0x007F0C03
859#define CX700_46_996M 0x00818C83
860#define CX700_48_000M 0x00840C03
861#define CX700_48_875M 0x00508C81
862#define CX700_49_500M 0x00880C03
863#define CX700_52_406M 0x00730C02
864#define CX700_52_977M 0x00920C03
865#define CX700_56_250M 0x009B0C03
866#define CX700_60_466M 0x00460C00
867#define CX700_61_500M 0x00AA0C03
868#define CX700_65_000M 0x006B0C01
869#define CX700_65_178M 0x006B0C01
870#define CX700_66_750M 0x00940C02 /*67.116MHz */
871#define CX700_68_179M 0x00BC0C03
872#define CX700_69_924M 0x00C10C03
873#define CX700_70_159M 0x00C20C03
874#define CX700_72_000M 0x009F0C02
875#define CX700_74_270M 0x00CE0C03
876#define CX700_74_481M 0x00CE0C03
877#define CX700_78_750M 0x006C0803
878#define CX700_80_136M 0x006E0803
879#define CX700_83_375M 0x005B0882
880#define CX700_83_950M 0x00730803
881#define CX700_84_750M 0x00740803 /* 84.537Mhz */
882#define CX700_85_860M 0x00760803
883#define CX700_88_750M 0x00AC8885
884#define CX700_94_500M 0x00820803
885#define CX700_97_750M 0x00870803
886#define CX700_101_000M 0x008B0803
887#define CX700_106_500M 0x00750802
888#define CX700_108_000M 0x00950803
889#define CX700_113_309M 0x005D0801
890#define CX700_118_840M 0x00A40803
891#define CX700_119_000M 0x00830802
892#define CX700_121_750M 0x00420800 /* 121.704MHz */
893#define CX700_125_104M 0x00AD0803
894#define CX700_133_308M 0x00930802
895#define CX700_135_000M 0x00950802
896#define CX700_136_700M 0x00BD0803
897#define CX700_138_400M 0x00720801
898#define CX700_146_760M 0x00CC0803
899#define CX700_148_500M 0x00a40802
900#define CX700_153_920M 0x00540402
901#define CX700_156_000M 0x006B0403
902#define CX700_157_500M 0x006C0403
903#define CX700_162_000M 0x006F0403
904#define CX700_172_798M 0x00770403
905#define CX700_187_000M 0x00810403
906#define CX700_193_295M 0x00850403
907#define CX700_202_500M 0x008C0403
908#define CX700_204_000M 0x008D0403
909#define CX700_218_500M 0x00970403
910#define CX700_234_000M 0x00600401
911#define CX700_267_250M 0x00B90403
912#define CX700_297_500M 0x00CE0403
913#define CX700_122_614M 0x00870802
914
915/* PLL for VX855 */
916#define VX855_22_000M 0x007B1005
917#define VX855_25_175M 0x008D1005
918#define VX855_26_719M 0x00961005
919#define VX855_26_880M 0x00961005
920#define VX855_27_000M 0x00971005
921#define VX855_29_581M 0x00A51005
922#define VX855_29_829M 0x00641003
923#define VX855_31_490M 0x00B01005
924#define VX855_31_500M 0x00B01005
925#define VX855_31_728M 0x008E1004
926#define VX855_32_668M 0x00921004
927#define VX855_36_000M 0x00A11004
928#define VX855_40_000M 0x00700C05
929#define VX855_41_291M 0x00730C05
930#define VX855_43_163M 0x00790C05
931#define VX855_45_250M 0x007F0C05 /* 45.46MHz */
932#define VX855_46_000M 0x00670C04
933#define VX855_46_996M 0x00690C04
934#define VX855_48_000M 0x00860C05
935#define VX855_48_875M 0x00890C05
936#define VX855_49_500M 0x00530C03
937#define VX855_52_406M 0x00580C03
938#define VX855_52_977M 0x00940C05
939#define VX855_56_250M 0x009D0C05
940#define VX855_57_275M 0x009D8C85 /* Used by XO panel */
941#define VX855_60_466M 0x00A90C05
942#define VX855_61_500M 0x00AC0C05
943#define VX855_65_000M 0x006D0C03
944#define VX855_65_178M 0x00B60C05
945#define VX855_66_750M 0x00700C03 /*67.116MHz */
946#define VX855_67_295M 0x00BC0C05
947#define VX855_68_179M 0x00BF0C05
948#define VX855_68_369M 0x00BF0C05
949#define VX855_69_924M 0x00C30C05
950#define VX855_70_159M 0x00C30C05
951#define VX855_72_000M 0x00A10C04
952#define VX855_73_023M 0x00CC0C05
953#define VX855_74_481M 0x00D10C05
954#define VX855_78_750M 0x006E0805
955#define VX855_79_466M 0x006F0805
956#define VX855_80_136M 0x00700805
957#define VX855_81_627M 0x00720805
958#define VX855_83_375M 0x00750805
959#define VX855_83_527M 0x00750805
960#define VX855_83_950M 0x00750805
961#define VX855_84_537M 0x00760805
962#define VX855_84_750M 0x00760805 /* 84.537Mhz */
963#define VX855_85_500M 0x00760805 /* 85.909080 MHz*/
964#define VX855_85_860M 0x00760805
965#define VX855_85_909M 0x00760805
966#define VX855_88_750M 0x007C0805
967#define VX855_89_489M 0x007D0805
968#define VX855_94_500M 0x00840805
969#define VX855_96_648M 0x00870805
970#define VX855_97_750M 0x00890805
971#define VX855_101_000M 0x008D0805
972#define VX855_106_500M 0x00950805
973#define VX855_108_000M 0x00970805
974#define VX855_110_125M 0x00990805
975#define VX855_112_000M 0x009D0805
976#define VX855_113_309M 0x009F0805
977#define VX855_115_000M 0x00A10805
978#define VX855_118_840M 0x00A60805
979#define VX855_119_000M 0x00A70805
980#define VX855_121_750M 0x00AA0805 /* 121.704MHz */
981#define VX855_122_614M 0x00AC0805
982#define VX855_126_266M 0x00B10805
983#define VX855_130_250M 0x00B60805 /* 130.250 */
984#define VX855_135_000M 0x00BD0805
985#define VX855_136_700M 0x00BF0805
986#define VX855_137_750M 0x00C10805
987#define VX855_138_400M 0x00C20805
988#define VX855_144_300M 0x00CA0805
989#define VX855_146_760M 0x00CE0805
990#define VX855_148_500M 0x00D00805
991#define VX855_153_920M 0x00540402
992#define VX855_156_000M 0x006C0405
993#define VX855_156_867M 0x006E0405
994#define VX855_157_500M 0x006E0405
995#define VX855_162_000M 0x00710405
996#define VX855_172_798M 0x00790405
997#define VX855_187_000M 0x00830405
998#define VX855_193_295M 0x00870405
999#define VX855_202_500M 0x008E0405
1000#define VX855_204_000M 0x008F0405
1001#define VX855_218_500M 0x00990405
1002#define VX855_229_500M 0x00A10405
1003#define VX855_234_000M 0x00A40405
1004#define VX855_267_250M 0x00BB0405
1005#define VX855_297_500M 0x00D00405
1006#define VX855_339_500M 0x00770005
1007#define VX855_340_772M 0x00770005
1008
1009 700
1010/* Definition CRTC Timing Index */ 701/* Definition CRTC Timing Index */
1011#define H_TOTAL_INDEX 0 702#define H_TOTAL_INDEX 0
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index e8cfe8392110..66f403033111 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -64,7 +64,7 @@ static inline int viafb_mmio_read(int reg)
64 */ 64 */
65static u32 viafb_enabled_ints; 65static u32 viafb_enabled_ints;
66 66
67static void viafb_int_init(void) 67static void __devinit viafb_int_init(void)
68{ 68{
69 viafb_enabled_ints = 0; 69 viafb_enabled_ints = 0;
70 70
@@ -489,7 +489,7 @@ out_unmap:
489 return ret; 489 return ret;
490} 490}
491 491
492static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) 492static void via_pci_teardown_mmio(struct viafb_dev *vdev)
493{ 493{
494 iounmap(vdev->fbmem); 494 iounmap(vdev->fbmem);
495 iounmap(vdev->engine_mmio); 495 iounmap(vdev->engine_mmio);
@@ -548,7 +548,7 @@ static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
548 return 0; 548 return 0;
549} 549}
550 550
551static void __devexit via_teardown_subdevs(void) 551static void via_teardown_subdevs(void)
552{ 552{
553 int i; 553 int i;
554 554
@@ -613,22 +613,24 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
613static struct pci_device_id via_pci_table[] __devinitdata = { 613static struct pci_device_id via_pci_table[] __devinitdata = {
614 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), 614 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
615 .driver_data = UNICHROME_CLE266 }, 615 .driver_data = UNICHROME_CLE266 },
616 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
617 .driver_data = UNICHROME_PM800 },
618 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID), 616 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
619 .driver_data = UNICHROME_K400 }, 617 .driver_data = UNICHROME_K400 },
620 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID), 618 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
621 .driver_data = UNICHROME_K800 }, 619 .driver_data = UNICHROME_K800 },
622 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID), 620 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
621 .driver_data = UNICHROME_PM800 },
622 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN700_DID),
623 .driver_data = UNICHROME_CN700 }, 623 .driver_data = UNICHROME_CN700 },
624 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
625 .driver_data = UNICHROME_K8M890 },
626 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID), 624 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
627 .driver_data = UNICHROME_CX700 }, 625 .driver_data = UNICHROME_CX700 },
628 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
629 .driver_data = UNICHROME_P4M900 },
630 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID), 626 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
631 .driver_data = UNICHROME_CN750 }, 627 .driver_data = UNICHROME_CN750 },
628 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
629 .driver_data = UNICHROME_K8M890 },
630 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
631 .driver_data = UNICHROME_P4M890 },
632 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
633 .driver_data = UNICHROME_P4M900 },
632 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID), 634 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
633 .driver_data = UNICHROME_VX800 }, 635 .driver_data = UNICHROME_VX800 },
634 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), 636 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c
index 595516aea691..39acb37e7a1d 100644
--- a/drivers/video/via/via-gpio.c
+++ b/drivers/video/via/via-gpio.c
@@ -73,7 +73,7 @@ struct viafb_gpio_cfg {
73 struct gpio_chip gpio_chip; 73 struct gpio_chip gpio_chip;
74 struct viafb_dev *vdev; 74 struct viafb_dev *vdev;
75 struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS]; 75 struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS];
76 char *gpio_names[VIAFB_NUM_GPIOS]; 76 const char *gpio_names[VIAFB_NUM_GPIOS];
77}; 77};
78 78
79/* 79/*
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 1082541358f0..bdd0e4130f4e 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -49,11 +49,6 @@ char *viafb_active_dev;
49char *viafb_lcd_port = ""; 49char *viafb_lcd_port = "";
50char *viafb_dvi_port = ""; 50char *viafb_dvi_port = "";
51 51
52static void viafb_set_device(struct device_t active_dev);
53static int apply_device_setting(struct viafb_ioctl_setting setting_info,
54 struct fb_info *info);
55static void apply_second_mode_setting(struct fb_var_screeninfo
56 *sec_var);
57static void retrieve_device_setting(struct viafb_ioctl_setting 52static void retrieve_device_setting(struct viafb_ioctl_setting
58 *setting_info); 53 *setting_info);
59static int viafb_pan_display(struct fb_var_screeninfo *var, 54static int viafb_pan_display(struct fb_var_screeninfo *var,
@@ -221,9 +216,9 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
221 216
222 /* Adjust var according to our driver's own table */ 217 /* Adjust var according to our driver's own table */
223 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 218 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
224 if (info->var.accel_flags & FB_ACCELF_TEXT && 219 if (var->accel_flags & FB_ACCELF_TEXT &&
225 !ppar->shared->vdev->engine_mmio) 220 !ppar->shared->vdev->engine_mmio)
226 info->var.accel_flags = 0; 221 var->accel_flags = 0;
227 222
228 return 0; 223 return 0;
229} 224}
@@ -234,6 +229,7 @@ static int viafb_set_par(struct fb_info *info)
234 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL; 229 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
235 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 230 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
236 231
232 viafb_update_fix(info);
237 viapar->depth = fb_get_color_depth(&info->var, &info->fix); 233 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
238 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 234 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
239 viafbinfo->var.bits_per_pixel, viafb_refresh, 0); 235 viafbinfo->var.bits_per_pixel, viafb_refresh, 0);
@@ -257,7 +253,6 @@ static int viafb_set_par(struct fb_info *info)
257 } 253 }
258 254
259 if (vmode_entry) { 255 if (vmode_entry) {
260 viafb_update_fix(info);
261 if (viafb_dual_fb && viapar->iga_path == IGA2) 256 if (viafb_dual_fb && viapar->iga_path == IGA2)
262 viafb_bpp1 = info->var.bits_per_pixel; 257 viafb_bpp1 = info->var.bits_per_pixel;
263 else 258 else
@@ -478,13 +473,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
478 if (gpu32 & LCD_Device) 473 if (gpu32 & LCD_Device)
479 viafb_lcd_disable(); 474 viafb_lcd_disable();
480 break; 475 break;
481 case VIAFB_SET_DEVICE:
482 if (copy_from_user(&u.active_dev, (void *)argp,
483 sizeof(u.active_dev)))
484 return -EFAULT;
485 viafb_set_device(u.active_dev);
486 viafb_set_par(info);
487 break;
488 case VIAFB_GET_DEVICE: 476 case VIAFB_GET_DEVICE:
489 u.active_dev.crt = viafb_CRT_ON; 477 u.active_dev.crt = viafb_CRT_ON;
490 u.active_dev.dvi = viafb_DVI_ON; 478 u.active_dev.dvi = viafb_DVI_ON;
@@ -527,21 +515,6 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
527 515
528 break; 516 break;
529 517
530 case VIAFB_SET_DEVICE_INFO:
531 if (copy_from_user(&u.viafb_setting,
532 argp, sizeof(u.viafb_setting)))
533 return -EFAULT;
534 if (apply_device_setting(u.viafb_setting, info) < 0)
535 return -EINVAL;
536
537 break;
538
539 case VIAFB_SET_SECOND_MODE:
540 if (copy_from_user(&u.sec_var, argp, sizeof(u.sec_var)))
541 return -EFAULT;
542 apply_second_mode_setting(&u.sec_var);
543 break;
544
545 case VIAFB_GET_DEVICE_INFO: 518 case VIAFB_GET_DEVICE_INFO:
546 519
547 retrieve_device_setting(&u.viafb_setting); 520 retrieve_device_setting(&u.viafb_setting);
@@ -913,112 +886,6 @@ static int viafb_sync(struct fb_info *info)
913 return 0; 886 return 0;
914} 887}
915 888
916static void check_available_device_to_enable(int device_id)
917{
918 int device_num = 0;
919
920 /* Initialize: */
921 viafb_CRT_ON = STATE_OFF;
922 viafb_DVI_ON = STATE_OFF;
923 viafb_LCD_ON = STATE_OFF;
924 viafb_LCD2_ON = STATE_OFF;
925 viafb_DeviceStatus = None_Device;
926
927 if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
928 viafb_CRT_ON = STATE_ON;
929 device_num++;
930 viafb_DeviceStatus |= CRT_Device;
931 }
932
933 if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
934 viafb_DVI_ON = STATE_ON;
935 device_num++;
936 viafb_DeviceStatus |= DVI_Device;
937 }
938
939 if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
940 viafb_LCD_ON = STATE_ON;
941 device_num++;
942 viafb_DeviceStatus |= LCD_Device;
943 }
944
945 if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
946 viafb_LCD2_ON = STATE_ON;
947 device_num++;
948 viafb_DeviceStatus |= LCD2_Device;
949 }
950
951 if (viafb_DeviceStatus == None_Device) {
952 /* Use CRT as default active device: */
953 viafb_CRT_ON = STATE_ON;
954 viafb_DeviceStatus = CRT_Device;
955 }
956 DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
957}
958
959static void viafb_set_device(struct device_t active_dev)
960{
961 /* Check available device to enable: */
962 int device_id = None_Device;
963 if (active_dev.crt)
964 device_id |= CRT_Device;
965 if (active_dev.dvi)
966 device_id |= DVI_Device;
967 if (active_dev.lcd)
968 device_id |= LCD_Device;
969
970 check_available_device_to_enable(device_id);
971
972 /* Check property of LCD: */
973 if (viafb_LCD_ON) {
974 if (active_dev.lcd_dsp_cent) {
975 viaparinfo->lvds_setting_info->display_method =
976 viafb_lcd_dsp_method = LCD_CENTERING;
977 } else {
978 viaparinfo->lvds_setting_info->display_method =
979 viafb_lcd_dsp_method = LCD_EXPANDSION;
980 }
981
982 if (active_dev.lcd_mode == LCD_SPWG) {
983 viaparinfo->lvds_setting_info->lcd_mode =
984 viafb_lcd_mode = LCD_SPWG;
985 } else {
986 viaparinfo->lvds_setting_info->lcd_mode =
987 viafb_lcd_mode = LCD_OPENLDI;
988 }
989
990 if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
991 viafb_lcd_panel_id = active_dev.lcd_panel_id;
992 viafb_init_lcd_size();
993 }
994 }
995
996 /* Check property of mode: */
997 if (!active_dev.xres1)
998 viafb_second_xres = 640;
999 else
1000 viafb_second_xres = active_dev.xres1;
1001 if (!active_dev.yres1)
1002 viafb_second_yres = 480;
1003 else
1004 viafb_second_yres = active_dev.yres1;
1005 if (active_dev.bpp != 0)
1006 viafb_bpp = active_dev.bpp;
1007 if (active_dev.bpp1 != 0)
1008 viafb_bpp1 = active_dev.bpp1;
1009 if (active_dev.refresh != 0)
1010 viafb_refresh = active_dev.refresh;
1011 if (active_dev.refresh1 != 0)
1012 viafb_refresh1 = active_dev.refresh1;
1013 if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
1014 viafb_SAMM_ON = active_dev.samm;
1015 viafb_primary_dev = active_dev.primary_dev;
1016
1017 via_set_primary_address(0);
1018 via_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1019 viafb_set_iga_path();
1020}
1021
1022static int get_primary_device(void) 889static int get_primary_device(void)
1023{ 890{
1024 int primary_device = 0; 891 int primary_device = 0;
@@ -1060,124 +927,6 @@ static int get_primary_device(void)
1060 return primary_device; 927 return primary_device;
1061} 928}
1062 929
1063static void apply_second_mode_setting(struct fb_var_screeninfo
1064 *sec_var)
1065{
1066 u32 htotal, vtotal, long_refresh;
1067
1068 htotal = sec_var->xres + sec_var->left_margin +
1069 sec_var->right_margin + sec_var->hsync_len;
1070 vtotal = sec_var->yres + sec_var->upper_margin +
1071 sec_var->lower_margin + sec_var->vsync_len;
1072 if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
1073 /*Is 32 bytes alignment? */
1074 /*32 pixel alignment */
1075 sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
1076 }
1077
1078 htotal = sec_var->xres + sec_var->left_margin +
1079 sec_var->right_margin + sec_var->hsync_len;
1080 vtotal = sec_var->yres + sec_var->upper_margin +
1081 sec_var->lower_margin + sec_var->vsync_len;
1082 long_refresh = 1000000000UL / sec_var->pixclock * 1000;
1083 long_refresh /= (htotal * vtotal);
1084
1085 viafb_second_xres = sec_var->xres;
1086 viafb_second_yres = sec_var->yres;
1087 viafb_second_virtual_xres = sec_var->xres_virtual;
1088 viafb_second_virtual_yres = sec_var->yres_virtual;
1089 viafb_bpp1 = sec_var->bits_per_pixel;
1090 viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
1091 long_refresh);
1092}
1093
1094static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1095 struct fb_info *info)
1096{
1097 int need_set_mode = 0;
1098 DEBUG_MSG(KERN_INFO "apply_device_setting\n");
1099
1100 if (setting_info.device_flag) {
1101 need_set_mode = 1;
1102 check_available_device_to_enable(setting_info.device_status);
1103 }
1104
1105 /* Unlock LCD's operation according to LCD flag
1106 and check if the setting value is valid. */
1107 /* If the value is valid, apply the new setting value to the device. */
1108 if (viafb_LCD_ON) {
1109 if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
1110 need_set_mode = 1;
1111 if (setting_info.lcd_attributes.display_center) {
1112 /* Centering */
1113 viaparinfo->lvds_setting_info->display_method =
1114 LCD_CENTERING;
1115 viafb_lcd_dsp_method = LCD_CENTERING;
1116 viaparinfo->lvds_setting_info2->display_method =
1117 viafb_lcd_dsp_method = LCD_CENTERING;
1118 } else {
1119 /* expandsion */
1120 viaparinfo->lvds_setting_info->display_method =
1121 LCD_EXPANDSION;
1122 viafb_lcd_dsp_method = LCD_EXPANDSION;
1123 viaparinfo->lvds_setting_info2->display_method =
1124 LCD_EXPANDSION;
1125 viafb_lcd_dsp_method = LCD_EXPANDSION;
1126 }
1127 }
1128
1129 if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
1130 need_set_mode = 1;
1131 if (setting_info.lcd_attributes.lcd_mode ==
1132 LCD_SPWG) {
1133 viaparinfo->lvds_setting_info->lcd_mode =
1134 viafb_lcd_mode = LCD_SPWG;
1135 } else {
1136 viaparinfo->lvds_setting_info->lcd_mode =
1137 viafb_lcd_mode = LCD_OPENLDI;
1138 }
1139 viaparinfo->lvds_setting_info2->lcd_mode =
1140 viaparinfo->lvds_setting_info->lcd_mode;
1141 }
1142
1143 if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
1144 need_set_mode = 1;
1145 if (setting_info.lcd_attributes.panel_id <=
1146 LCD_PANEL_ID_MAXIMUM) {
1147 viafb_lcd_panel_id =
1148 setting_info.lcd_attributes.panel_id;
1149 viafb_init_lcd_size();
1150 }
1151 }
1152 }
1153
1154 if (0 != (setting_info.samm_status & OP_SAMM)) {
1155 setting_info.samm_status =
1156 setting_info.samm_status & (~OP_SAMM);
1157 if (setting_info.samm_status == 0
1158 || setting_info.samm_status == 1) {
1159 viafb_SAMM_ON = setting_info.samm_status;
1160
1161 if (viafb_SAMM_ON)
1162 viafb_primary_dev = setting_info.primary_device;
1163
1164 via_set_primary_address(0);
1165 via_set_secondary_address(viafb_SAMM_ON ?
1166 viafb_second_offset : 0);
1167 viafb_set_iga_path();
1168 }
1169 need_set_mode = 1;
1170 }
1171
1172 if (!need_set_mode) {
1173 ;
1174 } else {
1175 viafb_set_iga_path();
1176 viafb_set_par(info);
1177 }
1178 return true;
1179}
1180
1181static void retrieve_device_setting(struct viafb_ioctl_setting 930static void retrieve_device_setting(struct viafb_ioctl_setting
1182 *setting_info) 931 *setting_info)
1183{ 932{
@@ -1776,10 +1525,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1776 parse_lcd_port(); 1525 parse_lcd_port();
1777 parse_dvi_port(); 1526 parse_dvi_port();
1778 1527
1779 /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
1780 if (!viafb_SAMM_ON)
1781 viafb_dual_fb = 0;
1782
1783 viafb_init_chip_info(vdev->chip_type); 1528 viafb_init_chip_info(vdev->chip_type);
1784 /* 1529 /*
1785 * The framebuffer will have been successfully mapped by 1530 * The framebuffer will have been successfully mapped by
@@ -1823,30 +1568,13 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1823 parse_mode(viafb_mode1, &viafb_second_xres, 1568 parse_mode(viafb_mode1, &viafb_second_xres,
1824 &viafb_second_yres); 1569 &viafb_second_yres);
1825 1570
1826 if (0 == viafb_second_virtual_xres) { 1571 viafb_second_virtual_xres = viafb_second_xres;
1827 switch (viafb_second_xres) { 1572 viafb_second_virtual_yres = viafb_second_yres;
1828 case 1400:
1829 viafb_second_virtual_xres = 1408;
1830 break;
1831 default:
1832 viafb_second_virtual_xres = viafb_second_xres;
1833 break;
1834 }
1835 }
1836 if (0 == viafb_second_virtual_yres)
1837 viafb_second_virtual_yres = viafb_second_yres;
1838 } 1573 }
1839 1574
1840 default_var.xres = default_xres; 1575 default_var.xres = default_xres;
1841 default_var.yres = default_yres; 1576 default_var.yres = default_yres;
1842 switch (default_xres) { 1577 default_var.xres_virtual = default_xres;
1843 case 1400:
1844 default_var.xres_virtual = 1408;
1845 break;
1846 default:
1847 default_var.xres_virtual = default_xres;
1848 break;
1849 }
1850 default_var.yres_virtual = default_yres; 1578 default_var.yres_virtual = default_yres;
1851 default_var.bits_per_pixel = viafb_bpp; 1579 default_var.bits_per_pixel = viafb_bpp;
1852 default_var.pixclock = 1580 default_var.pixclock =
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c
index d31dc96f838a..85d76ec4c63e 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/vt8623fb.c
@@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
726 726
727 /* Prepare startup mode */ 727 /* Prepare startup mode */
728 728
729 kparam_block_sysfs_write(mode_option);
729 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); 730 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
731 kparam_unblock_sysfs_write(mode_option);
730 if (! ((rc == 1) || (rc == 2))) { 732 if (! ((rc == 1) || (rc == 2))) {
731 rc = -EINVAL; 733 rc = -EINVAL;
732 dev_err(info->device, "mode %s not found\n", mode_option); 734 dev_err(info->device, "mode %s not found\n", mode_option);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index e66b8b19ce5d..d8b12c32e3ef 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -858,9 +858,9 @@ unsigned long w100fb_gpio_read(int port)
858void w100fb_gpio_write(int port, unsigned long value) 858void w100fb_gpio_write(int port, unsigned long value)
859{ 859{
860 if (port==W100_GPIO_PORT_A) 860 if (port==W100_GPIO_PORT_A)
861 value = writel(value, remapped_regs + mmGPIO_DATA); 861 writel(value, remapped_regs + mmGPIO_DATA);
862 else 862 else
863 value = writel(value, remapped_regs + mmGPIO_DATA2); 863 writel(value, remapped_regs + mmGPIO_DATA2);
864} 864}
865EXPORT_SYMBOL(w100fb_gpio_read); 865EXPORT_SYMBOL(w100fb_gpio_read);
866EXPORT_SYMBOL(w100fb_gpio_write); 866EXPORT_SYMBOL(w100fb_gpio_write);
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index fa97d3e7c21a..7c7f42a12796 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -684,7 +684,7 @@ static struct xenbus_driver xenfb_driver = {
684 684
685static int __init xenfb_init(void) 685static int __init xenfb_init(void)
686{ 686{
687 if (!xen_domain()) 687 if (!xen_pv_domain())
688 return -ENODEV; 688 return -ENODEV;
689 689
690 /* Nothing to do if running in dom0. */ 690 /* Nothing to do if running in dom0. */
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index 574dc54e12d4..0c9ce88e95e8 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -397,7 +397,7 @@ static int xilinxfb_release(struct device *dev)
397 */ 397 */
398 398
399static int __devinit 399static int __devinit
400xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) 400xilinxfb_of_probe(struct platform_device *op, const struct of_device_id *match)
401{ 401{
402 const u32 *prop; 402 const u32 *prop;
403 u32 *p; 403 u32 *p;
@@ -477,7 +477,7 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
477 return -ENODEV; 477 return -ENODEV;
478} 478}
479 479
480static int __devexit xilinxfb_of_remove(struct of_device *op) 480static int __devexit xilinxfb_of_remove(struct platform_device *op)
481{ 481{
482 return xilinxfb_release(&op->dev); 482 return xilinxfb_release(&op->dev);
483} 483}
@@ -485,6 +485,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op)
485/* Match table for of_platform binding */ 485/* Match table for of_platform binding */
486static struct of_device_id xilinxfb_of_match[] __devinitdata = { 486static struct of_device_id xilinxfb_of_match[] __devinitdata = {
487 { .compatible = "xlnx,xps-tft-1.00.a", }, 487 { .compatible = "xlnx,xps-tft-1.00.a", },
488 { .compatible = "xlnx,xps-tft-2.00.a", },
489 { .compatible = "xlnx,xps-tft-2.01.a", },
488 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, 490 { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
489 { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", }, 491 { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", },
490 {}, 492 {},