aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 13:39:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 13:39:14 -0500
commitd33a6291c1c577ff2272edab7416a0f7308e1cef (patch)
tree9efd2f6f2fbb0586af72531110acdf9e769285ab /drivers/video
parent66dc918d42eaaa9afe42a47d07526765162017a9 (diff)
parentf00117a78341e330eecebdfe74cce345ed068802 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6: (29 commits) video: move SH_MIPI_DSI/SH_LCD_MIPI_DSI to the top of menu fbdev: Implement simple blanking in pseudocolor modes for vt8500lcdfb video: imx: Update the manufacturer's name nuc900fb: don't treat NULL clk as an error s3c2410fb: don't treat NULL clk as an error video: tidy up modedb formatting. video: matroxfb: Correct video option in comments and kernel config help. fbdev: sh_mobile_hdmi: simplify pointer handling fbdev: sh_mobile_hdmi: framebuffer notifiers have to be registered fbdev: sh_mobile_hdmi: add command line option to use the preferred EDID mode OMAP: DSS2: Introduce omap_channel as an omap_dss_device parameter, add new overlay manager. OMAP: DSS2: Use dss_features to handle DISPC bits removed on OMAP4 OMAP: DSS2: LCD2 Channel Changes for DISPC OMAP: DSS2: Change remaining DISPC functions for new omap_channel argument OMAP: DSS2: Introduce omap_channel argument to DISPC functions used by interface drivers OMAP: DSS2: Represent DISPC register defines with channel as parameter OMAP: DSS2: Add dss_features for omap4 and overlay manager related features OMAP: DSS2: Clean up DISPC color mode validation checks OMAP: DSS2: Add back authors of panel-generic.c based drivers OMAP: DSS2: remove generic DPI panel driver duplicated panel drivers ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig18
-rw-r--r--drivers/video/imxfb.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c70
-rw-r--r--drivers/video/modedb.c420
-rw-r--r--drivers/video/nuc900fb.c5
-rw-r--r--drivers/video/omap2/displays/Kconfig27
-rw-r--r--drivers/video/omap2/displays/Makefile5
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c365
-rw-r--r--drivers/video/omap2/displays/panel-generic.c174
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c325
-rw-r--r--drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c165
-rw-r--r--drivers/video/omap2/displays/panel-toppoly-tdo35s.c164
-rw-r--r--drivers/video/omap2/dss/dispc.c636
-rw-r--r--drivers/video/omap2/dss/dpi.c40
-rw-r--r--drivers/video/omap2/dss/dsi.c27
-rw-r--r--drivers/video/omap2/dss/dss.h35
-rw-r--r--drivers/video/omap2/dss/dss_features.c66
-rw-r--r--drivers/video/omap2/dss/dss_features.h10
-rw-r--r--drivers/video/omap2/dss/manager.c80
-rw-r--r--drivers/video/omap2/dss/overlay.c55
-rw-r--r--drivers/video/omap2/dss/rfbi.c20
-rw-r--r--drivers/video/omap2/dss/sdi.c24
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c5
-rw-r--r--drivers/video/s3c2410fb.c5
-rw-r--r--drivers/video/sh_mobile_hdmi.c97
-rw-r--r--drivers/video/vt8500lcdfb.c28
26 files changed, 1738 insertions, 1130 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 55dc6fb6e909..d916ac04abab 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -11,6 +11,13 @@ config HAVE_FB_ATMEL
11config HAVE_FB_IMX 11config HAVE_FB_IMX
12 bool 12 bool
13 13
14config SH_MIPI_DSI
15 tristate
16 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
17
18config SH_LCD_MIPI_DSI
19 bool
20
14source "drivers/char/agp/Kconfig" 21source "drivers/char/agp/Kconfig"
15 22
16source "drivers/gpu/vga/Kconfig" 23source "drivers/gpu/vga/Kconfig"
@@ -414,7 +421,7 @@ config FB_SA1100
414 Y here. 421 Y here.
415 422
416config FB_IMX 423config FB_IMX
417 tristate "Motorola i.MX LCD support" 424 tristate "Freescale i.MX LCD support"
418 depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2) 425 depends on FB && (HAVE_FB_IMX || ARCH_MX1 || ARCH_MX2)
419 select FB_CFB_FILLRECT 426 select FB_CFB_FILLRECT
420 select FB_CFB_COPYAREA 427 select FB_CFB_COPYAREA
@@ -1273,7 +1280,7 @@ config FB_MATROX
1273 module will be called matroxfb. 1280 module will be called matroxfb.
1274 1281
1275 You can pass several parameters to the driver at boot time or at 1282 You can pass several parameters to the driver at boot time or at
1276 module load time. The parameters look like "video=matrox:XXX", and 1283 module load time. The parameters look like "video=matroxfb:XXX", and
1277 are described in <file:Documentation/fb/matroxfb.txt>. 1284 are described in <file:Documentation/fb/matroxfb.txt>.
1278 1285
1279config FB_MATROX_MILLENIUM 1286config FB_MATROX_MILLENIUM
@@ -1990,13 +1997,6 @@ config FB_W100
1990 1997
1991 If unsure, say N. 1998 If unsure, say N.
1992 1999
1993config SH_MIPI_DSI
1994 tristate
1995 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
1996
1997config SH_LCD_MIPI_DSI
1998 bool
1999
2000config FB_SH_MOBILE_LCDC 2000config FB_SH_MOBILE_LCDC
2001 tristate "SuperH Mobile LCDC framebuffer support" 2001 tristate "SuperH Mobile LCDC framebuffer support"
2002 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK 2002 depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 1ab2c2588675..69bd4a581d4a 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -974,6 +974,6 @@ static void __exit imxfb_cleanup(void)
974module_init(imxfb_init); 974module_init(imxfb_init);
975module_exit(imxfb_cleanup); 975module_exit(imxfb_cleanup);
976 976
977MODULE_DESCRIPTION("Motorola i.MX framebuffer driver"); 977MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");
978MODULE_AUTHOR("Sascha Hauer, Pengutronix"); 978MODULE_AUTHOR("Sascha Hauer, Pengutronix");
979MODULE_LICENSE("GPL"); 979MODULE_LICENSE("GPL");
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 052dd9f0b760..a082debe824b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1247,46 +1247,46 @@ static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel;
1247}; 1247};
1248 1248
1249/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */ 1249/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
1250static unsigned int mem; /* "matrox:mem:xxxxxM" */ 1250static unsigned int mem; /* "matroxfb:mem:xxxxxM" */
1251static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */ 1251static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */
1252static int inv24; /* "matrox:inv24" */ 1252static int inv24; /* "matroxfb:inv24" */
1253static int cross4MB = -1; /* "matrox:cross4MB" */ 1253static int cross4MB = -1; /* "matroxfb:cross4MB" */
1254static int disabled; /* "matrox:disabled" */ 1254static int disabled; /* "matroxfb:disabled" */
1255static int noaccel; /* "matrox:noaccel" */ 1255static int noaccel; /* "matroxfb:noaccel" */
1256static int nopan; /* "matrox:nopan" */ 1256static int nopan; /* "matroxfb:nopan" */
1257static int no_pci_retry; /* "matrox:nopciretry" */ 1257static int no_pci_retry; /* "matroxfb:nopciretry" */
1258static int novga; /* "matrox:novga" */ 1258static int novga; /* "matroxfb:novga" */
1259static int nobios; /* "matrox:nobios" */ 1259static int nobios; /* "matroxfb:nobios" */
1260static int noinit = 1; /* "matrox:init" */ 1260static int noinit = 1; /* "matroxfb:init" */
1261static int inverse; /* "matrox:inverse" */ 1261static int inverse; /* "matroxfb:inverse" */
1262static int sgram; /* "matrox:sgram" */ 1262static int sgram; /* "matroxfb:sgram" */
1263#ifdef CONFIG_MTRR 1263#ifdef CONFIG_MTRR
1264static int mtrr = 1; /* "matrox:nomtrr" */ 1264static int mtrr = 1; /* "matroxfb:nomtrr" */
1265#endif 1265#endif
1266static int grayscale; /* "matrox:grayscale" */ 1266static int grayscale; /* "matroxfb:grayscale" */
1267static int dev = -1; /* "matrox:dev:xxxxx" */ 1267static int dev = -1; /* "matroxfb:dev:xxxxx" */
1268static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */ 1268static unsigned int vesa = ~0; /* "matroxfb:vesa:xxxxx" */
1269static int depth = -1; /* "matrox:depth:xxxxx" */ 1269static int depth = -1; /* "matroxfb:depth:xxxxx" */
1270static unsigned int xres; /* "matrox:xres:xxxxx" */ 1270static unsigned int xres; /* "matroxfb:xres:xxxxx" */
1271static unsigned int yres; /* "matrox:yres:xxxxx" */ 1271static unsigned int yres; /* "matroxfb:yres:xxxxx" */
1272static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */ 1272static unsigned int upper = ~0; /* "matroxfb:upper:xxxxx" */
1273static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */ 1273static unsigned int lower = ~0; /* "matroxfb:lower:xxxxx" */
1274static unsigned int vslen; /* "matrox:vslen:xxxxx" */ 1274static unsigned int vslen; /* "matroxfb:vslen:xxxxx" */
1275static unsigned int left = ~0; /* "matrox:left:xxxxx" */ 1275static unsigned int left = ~0; /* "matroxfb:left:xxxxx" */
1276static unsigned int right = ~0; /* "matrox:right:xxxxx" */ 1276static unsigned int right = ~0; /* "matroxfb:right:xxxxx" */
1277static unsigned int hslen; /* "matrox:hslen:xxxxx" */ 1277static unsigned int hslen; /* "matroxfb:hslen:xxxxx" */
1278static unsigned int pixclock; /* "matrox:pixclock:xxxxx" */ 1278static unsigned int pixclock; /* "matroxfb:pixclock:xxxxx" */
1279static int sync = -1; /* "matrox:sync:xxxxx" */ 1279static int sync = -1; /* "matroxfb:sync:xxxxx" */
1280static unsigned int fv; /* "matrox:fv:xxxxx" */ 1280static unsigned int fv; /* "matroxfb:fv:xxxxx" */
1281static unsigned int fh; /* "matrox:fh:xxxxxk" */ 1281static unsigned int fh; /* "matroxfb:fh:xxxxxk" */
1282static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */ 1282static unsigned int maxclk; /* "matroxfb:maxclk:xxxxM" */
1283static int dfp; /* "matrox:dfp */ 1283static int dfp; /* "matroxfb:dfp */
1284static int dfp_type = -1; /* "matrox:dfp:xxx */ 1284static int dfp_type = -1; /* "matroxfb:dfp:xxx */
1285static int memtype = -1; /* "matrox:memtype:xxx" */ 1285static int memtype = -1; /* "matroxfb:memtype:xxx" */
1286static char outputs[8]; /* "matrox:outputs:xxx" */ 1286static char outputs[8]; /* "matroxfb:outputs:xxx" */
1287 1287
1288#ifndef MODULE 1288#ifndef MODULE
1289static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ 1289static char videomode[64]; /* "matroxfb:mode:xxxxx" or "matroxfb:xxxxx" */
1290#endif 1290#endif
1291 1291
1292static int matroxfb_getmemory(struct matrox_fb_info *minfo, 1292static int matroxfb_getmemory(struct matrox_fb_info *minfo,
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index d2bb365f09b3..48c3ea8652b6 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -32,300 +32,320 @@
32const char *fb_mode_option; 32const char *fb_mode_option;
33EXPORT_SYMBOL_GPL(fb_mode_option); 33EXPORT_SYMBOL_GPL(fb_mode_option);
34 34
35 /* 35/*
36 * Standard video mode definitions (taken from XFree86) 36 * Standard video mode definitions (taken from XFree86)
37 */ 37 */
38 38
39static const struct fb_videomode modedb[] = { 39static const struct fb_videomode modedb[] = {
40 { 40
41 /* 640x400 @ 70 Hz, 31.5 kHz hsync */ 41 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
42 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, 42 { NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, 0,
43 0, FB_VMODE_NONINTERLACED 43 FB_VMODE_NONINTERLACED },
44 }, { 44
45 /* 640x480 @ 60 Hz, 31.5 kHz hsync */ 45 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
46 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 46 { NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0,
47 0, FB_VMODE_NONINTERLACED 47 FB_VMODE_NONINTERLACED },
48 }, { 48
49 /* 800x600 @ 56 Hz, 35.15 kHz hsync */ 49 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
50 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, 50 { NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, 0,
51 0, FB_VMODE_NONINTERLACED 51 FB_VMODE_NONINTERLACED },
52 }, { 52
53 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ 53 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
54 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, 54 { NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, 0,
55 0, FB_VMODE_INTERLACED 55 FB_VMODE_INTERLACED },
56 }, { 56
57 /* 640x400 @ 85 Hz, 37.86 kHz hsync */ 57 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
58 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, 58 { NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
59 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 59 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED },
60 }, { 60
61 /* 640x480 @ 72 Hz, 36.5 kHz hsync */ 61 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
62 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, 62 { NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, 0,
63 0, FB_VMODE_NONINTERLACED 63 FB_VMODE_NONINTERLACED },
64 }, { 64
65 /* 640x480 @ 75 Hz, 37.50 kHz hsync */ 65 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
66 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, 66 { NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0,
67 0, FB_VMODE_NONINTERLACED 67 FB_VMODE_NONINTERLACED },
68 }, { 68
69 /* 800x600 @ 60 Hz, 37.8 kHz hsync */ 69 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
70 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, 70 { NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
71 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 71 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
72 }, { 72 FB_VMODE_NONINTERLACED },
73
73 /* 640x480 @ 85 Hz, 43.27 kHz hsync */ 74 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
74 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, 75 { NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, 0,
75 0, FB_VMODE_NONINTERLACED 76 FB_VMODE_NONINTERLACED },
76 }, { 77
77 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ 78 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
78 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 79 { NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 0,
79 0, FB_VMODE_INTERLACED 80 FB_VMODE_INTERLACED },
80 }, {
81 /* 800x600 @ 72 Hz, 48.0 kHz hsync */ 81 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
82 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, 82 { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
83 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 83 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
84 }, { 84 FB_VMODE_NONINTERLACED },
85
85 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ 86 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
86 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, 87 { NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, 0,
87 0, FB_VMODE_NONINTERLACED 88 FB_VMODE_NONINTERLACED },
88 }, { 89
89 /* 640x480 @ 100 Hz, 53.01 kHz hsync */ 90 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
90 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, 91 { NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, 0,
91 0, FB_VMODE_NONINTERLACED 92 FB_VMODE_NONINTERLACED },
92 }, { 93
93 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ 94 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
94 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, 95 { NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, 0,
95 0, FB_VMODE_NONINTERLACED 96 FB_VMODE_NONINTERLACED },
96 }, { 97
97 /* 800x600 @ 85 Hz, 55.84 kHz hsync */ 98 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
98 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, 99 { NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, 0,
99 0, FB_VMODE_NONINTERLACED 100 FB_VMODE_NONINTERLACED },
100 }, { 101
101 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ 102 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
102 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 103 { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0,
103 0, FB_VMODE_NONINTERLACED 104 FB_VMODE_NONINTERLACED },
104 }, { 105
105 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ 106 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
106 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 107 { NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 0,
107 0, FB_VMODE_INTERLACED 108 FB_VMODE_INTERLACED },
108 }, { 109
109 /* 800x600 @ 100 Hz, 64.02 kHz hsync */ 110 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
110 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, 111 { NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, 0,
111 0, FB_VMODE_NONINTERLACED 112 FB_VMODE_NONINTERLACED },
112 }, { 113
113 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ 114 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
114 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, 115 { NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, 0,
115 0, FB_VMODE_NONINTERLACED 116 FB_VMODE_NONINTERLACED },
116 }, { 117
117 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ 118 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
118 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, 119 { NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, 0,
119 0, FB_VMODE_NONINTERLACED 120 FB_VMODE_NONINTERLACED },
120 }, { 121
121 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ 122 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
122 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 123 { NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0,
123 0, FB_VMODE_NONINTERLACED 124 FB_VMODE_NONINTERLACED },
124 }, { 125
125 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ 126 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
126 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 127 { NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 0,
127 0, FB_VMODE_NONINTERLACED 128 FB_VMODE_NONINTERLACED },
128 }, { 129
129 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ 130 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
130 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13, 131 { NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
131 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 132 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
132 }, { 133 FB_VMODE_NONINTERLACED },
134
133 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ 135 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
134 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, 136 { NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
135 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 137 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
136 }, { 138 FB_VMODE_NONINTERLACED },
139
137 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ 140 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
138 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, 141 { NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, 0,
139 0, FB_VMODE_NONINTERLACED 142 FB_VMODE_NONINTERLACED },
140 }, { 143
141 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ 144 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
142 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, 145 { NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, 0,
143 0, FB_VMODE_NONINTERLACED 146 FB_VMODE_NONINTERLACED },
144 }, { 147
145 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ 148 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
146 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, 149 { NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, 0,
147 0, FB_VMODE_NONINTERLACED 150 FB_VMODE_NONINTERLACED },
148 }, { 151
149 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ 152 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
150 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, 153 { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
151 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 154 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
152 }, { 155 FB_VMODE_NONINTERLACED },
156
153 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ 157 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
154 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, 158 { NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, 0,
155 0, FB_VMODE_NONINTERLACED 159 FB_VMODE_NONINTERLACED },
156 }, { 160
157 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ 161 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
158 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, 162 { NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, 0,
159 0, FB_VMODE_NONINTERLACED 163 FB_VMODE_NONINTERLACED },
160 }, { 164
161 /* 1024x768 @ 100Hz, 80.21 kHz hsync */ 165 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
162 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, 166 { NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, 0,
163 0, FB_VMODE_NONINTERLACED 167 FB_VMODE_NONINTERLACED },
164 }, { 168
165 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ 169 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
166 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, 170 { NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, 0,
167 0, FB_VMODE_NONINTERLACED 171 FB_VMODE_NONINTERLACED },
168 }, { 172
169 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ 173 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
170 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, 174 { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, 0,
171 0, FB_VMODE_NONINTERLACED 175 FB_VMODE_NONINTERLACED },
172 }, { 176
173 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ 177 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
174 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, 178 { NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, 0,
175 0, FB_VMODE_NONINTERLACED 179 FB_VMODE_NONINTERLACED },
176 }, { 180
177 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ 181 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
178 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, 182 { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
179 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 183 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
180 }, { 184 FB_VMODE_NONINTERLACED },
185
181 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ 186 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
182 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, 187 { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
183 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 188 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
184 }, { 189 FB_VMODE_NONINTERLACED },
190
185 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */ 191 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
186 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6, 192 { NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
187 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 193 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
188 }, { 194 FB_VMODE_NONINTERLACED },
195
189 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ 196 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
190 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, 197 { NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
191 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 198 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
192 }, { 199 FB_VMODE_NONINTERLACED },
200
193 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ 201 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
194 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, 202 { NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, 0,
195 0, FB_VMODE_NONINTERLACED 203 FB_VMODE_NONINTERLACED },
196 }, { 204
197 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ 205 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
198 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, 206 { NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
199 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 207 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
200 }, { 208 FB_VMODE_NONINTERLACED },
209
201 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ 210 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
202 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, 211 { NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
203 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 212 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
204 }, { 213 FB_VMODE_NONINTERLACED },
214
205 /* 512x384 @ 78 Hz, 31.50 kHz hsync */ 215 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
206 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, 216 { NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0,
207 0, FB_VMODE_NONINTERLACED 217 FB_VMODE_NONINTERLACED },
208 }, { 218
209 /* 512x384 @ 85 Hz, 34.38 kHz hsync */ 219 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
210 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, 220 { NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, 0,
211 0, FB_VMODE_NONINTERLACED 221 FB_VMODE_NONINTERLACED },
212 }, { 222
213 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ 223 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
214 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, 224 { NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0,
215 0, FB_VMODE_DOUBLE 225 FB_VMODE_DOUBLE },
216 }, { 226
217 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ 227 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
218 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, 228 { NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, 0,
219 0, FB_VMODE_DOUBLE 229 FB_VMODE_DOUBLE },
220 }, { 230
221 /* 320x240 @ 72 Hz, 36.5 kHz hsync */ 231 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
222 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, 232 { NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0,
223 0, FB_VMODE_DOUBLE 233 FB_VMODE_DOUBLE },
224 }, { 234
225 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ 235 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
226 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, 236 { NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, 0,
227 0, FB_VMODE_DOUBLE 237 FB_VMODE_DOUBLE },
228 }, { 238
229 /* 400x300 @ 60 Hz, 37.8 kHz hsync */ 239 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
230 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, 240 { NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, 0,
231 0, FB_VMODE_DOUBLE 241 FB_VMODE_DOUBLE },
232 }, { 242
233 /* 400x300 @ 72 Hz, 48.0 kHz hsync */ 243 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
234 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, 244 { NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, 0,
235 0, FB_VMODE_DOUBLE 245 FB_VMODE_DOUBLE },
236 }, { 246
237 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ 247 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
238 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, 248 { NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, 0,
239 0, FB_VMODE_DOUBLE 249 FB_VMODE_DOUBLE },
240 }, { 250
241 /* 480x300 @ 60 Hz, 37.8 kHz hsync */ 251 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
242 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, 252 { NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, 0,
243 0, FB_VMODE_DOUBLE 253 FB_VMODE_DOUBLE },
244 }, { 254
245 /* 480x300 @ 63 Hz, 39.6 kHz hsync */ 255 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
246 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, 256 { NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, 0,
247 0, FB_VMODE_DOUBLE 257 FB_VMODE_DOUBLE },
248 }, { 258
249 /* 480x300 @ 72 Hz, 48.0 kHz hsync */ 259 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
250 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 260 { NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0,
251 0, FB_VMODE_DOUBLE 261 FB_VMODE_DOUBLE },
252 }, { 262
253 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ 263 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
254 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, 264 { NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
255 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 265 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
256 FB_VMODE_NONINTERLACED 266 FB_VMODE_NONINTERLACED },
257 }, { 267
258 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ 268 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
259 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6, 269 { NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
260 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 270 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
261 }, { 271 FB_VMODE_NONINTERLACED },
272
262 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ 273 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
263 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 274 { NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, 0,
264 0, FB_VMODE_NONINTERLACED 275 FB_VMODE_NONINTERLACED },
265 }, { 276
266 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ 277 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
267 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, 278 { NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, 0,
268 0, FB_VMODE_NONINTERLACED 279 FB_VMODE_NONINTERLACED },
269 }, { 280
270 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ 281 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
271 NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, 282 { NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5, 0,
272 0, FB_VMODE_INTERLACED 283 FB_VMODE_INTERLACED },
273 }, { 284
274 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */ 285 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
275 NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, 286 { NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5, 0,
276 0, FB_VMODE_INTERLACED 287 FB_VMODE_INTERLACED },
277 }, { 288
278 /* 864x480 @ 60 Hz, 35.15 kHz hsync */ 289 /* 864x480 @ 60 Hz, 35.15 kHz hsync */
279 NULL, 60, 864, 480, 27777, 1, 1, 1, 1, 0, 0, 290 { NULL, 60, 864, 480, 27777, 1, 1, 1, 1, 0, 0,
280 0, FB_VMODE_NONINTERLACED 291 0, FB_VMODE_NONINTERLACED },
281 },
282}; 292};
283 293
284#ifdef CONFIG_FB_MODE_HELPERS 294#ifdef CONFIG_FB_MODE_HELPERS
285const struct fb_videomode cea_modes[64] = { 295const struct fb_videomode cea_modes[64] = {
286 /* #1: 640x480p@59.94/60Hz */ 296 /* #1: 640x480p@59.94/60Hz */
287 [1] = { 297 [1] = {
288 NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, 0, 298 NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
299 FB_VMODE_NONINTERLACED, 0,
289 }, 300 },
290 /* #3: 720x480p@59.94/60Hz */ 301 /* #3: 720x480p@59.94/60Hz */
291 [3] = { 302 [3] = {
292 NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0, FB_VMODE_NONINTERLACED, 0, 303 NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
304 FB_VMODE_NONINTERLACED, 0,
293 }, 305 },
294 /* #5: 1920x1080i@59.94/60Hz */ 306 /* #5: 1920x1080i@59.94/60Hz */
295 [5] = { 307 [5] = {
296 NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5, 308 NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
297 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED, 0, 309 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
310 FB_VMODE_INTERLACED, 0,
298 }, 311 },
299 /* #7: 720(1440)x480iH@59.94/60Hz */ 312 /* #7: 720(1440)x480iH@59.94/60Hz */
300 [7] = { 313 [7] = {
301 NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0, FB_VMODE_INTERLACED, 0, 314 NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
315 FB_VMODE_INTERLACED, 0,
302 }, 316 },
303 /* #9: 720(1440)x240pH@59.94/60Hz */ 317 /* #9: 720(1440)x240pH@59.94/60Hz */
304 [9] = { 318 [9] = {
305 NULL, 60, 1440, 240, 18554, 114, 38, 16, 4, 124, 3, 0, FB_VMODE_NONINTERLACED, 0, 319 NULL, 60, 1440, 240, 18554, 114, 38, 16, 4, 124, 3, 0,
320 FB_VMODE_NONINTERLACED, 0,
306 }, 321 },
307 /* #18: 720x576pH@50Hz */ 322 /* #18: 720x576pH@50Hz */
308 [18] = { 323 [18] = {
309 NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0, FB_VMODE_NONINTERLACED, 0, 324 NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
325 FB_VMODE_NONINTERLACED, 0,
310 }, 326 },
311 /* #19: 1280x720p@50Hz */ 327 /* #19: 1280x720p@50Hz */
312 [19] = { 328 [19] = {
313 NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5, 329 NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
314 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0, 330 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
331 FB_VMODE_NONINTERLACED, 0,
315 }, 332 },
316 /* #20: 1920x1080i@50Hz */ 333 /* #20: 1920x1080i@50Hz */
317 [20] = { 334 [20] = {
318 NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5, 335 NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
319 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED, 0, 336 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
337 FB_VMODE_INTERLACED, 0,
320 }, 338 },
321 /* #32: 1920x1080p@23.98/24Hz */ 339 /* #32: 1920x1080p@23.98/24Hz */
322 [32] = { 340 [32] = {
323 NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5, 341 NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
324 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0, 342 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
343 FB_VMODE_NONINTERLACED, 0,
325 }, 344 },
326 /* #35: (2880)x480p4x@59.94/60Hz */ 345 /* #35: (2880)x480p4x@59.94/60Hz */
327 [35] = { 346 [35] = {
328 NULL, 60, 2880, 480, 9250, 240, 64, 30, 9, 248, 6, 0, FB_VMODE_NONINTERLACED, 0, 347 NULL, 60, 2880, 480, 9250, 240, 64, 30, 9, 248, 6, 0,
348 FB_VMODE_NONINTERLACED, 0,
329 }, 349 },
330}; 350};
331 351
@@ -340,10 +360,10 @@ const struct fb_videomode vesa_modes[] = {
340 { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3, 360 { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3,
341 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 361 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
342 /* 3 640x480-60 VESA */ 362 /* 3 640x480-60 VESA */
343 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 363 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
344 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 364 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
345 /* 4 640x480-72 VESA */ 365 /* 4 640x480-72 VESA */
346 { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2, 366 { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2,
347 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 367 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
348 /* 5 640x480-75 VESA */ 368 /* 5 640x480-75 VESA */
349 { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3, 369 { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3,
@@ -426,7 +446,7 @@ const struct fb_videomode vesa_modes[] = {
426 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 446 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
427 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 447 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
428 /* 26 1600x1200-75 VESA */ 448 /* 26 1600x1200-75 VESA */
429 { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, 449 { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
430 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 450 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
431 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 451 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
432 /* 27 1600x1200-85 VESA */ 452 /* 27 1600x1200-85 VESA */
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index 81687ed26ba9..62498bd662fc 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -15,6 +15,7 @@
15 */ 15 */
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/err.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/string.h> 20#include <linux/string.h>
20#include <linux/mm.h> 21#include <linux/mm.h>
@@ -597,9 +598,9 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev)
597 } 598 }
598 599
599 fbi->clk = clk_get(&pdev->dev, NULL); 600 fbi->clk = clk_get(&pdev->dev, NULL);
600 if (!fbi->clk || IS_ERR(fbi->clk)) { 601 if (IS_ERR(fbi->clk)) {
601 printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n"); 602 printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
602 ret = -ENOENT; 603 ret = PTR_ERR(fbi->clk);
603 goto release_irq; 604 goto release_irq;
604 } 605 }
605 606
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 12327bbfdbbb..940cab394c2e 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -1,11 +1,13 @@
1menu "OMAP2/3 Display Device Drivers" 1menu "OMAP2/3 Display Device Drivers"
2 depends on OMAP2_DSS 2 depends on OMAP2_DSS
3 3
4config PANEL_GENERIC 4config PANEL_GENERIC_DPI
5 tristate "Generic Panel" 5 tristate "Generic DPI Panel"
6 help 6 help
7 Generic panel driver. 7 Generic DPI panel driver.
8 Used for DVI output for Beagle and OMAP3 SDP. 8 Supports DVI output for Beagle and OMAP3 SDP.
9 Supports LCD Panel used in TI SDP3430 and EVM boards,
10 OMAP3517 EVM boards and CM-T35.
9 11
10config PANEL_SHARP_LS037V7DW01 12config PANEL_SHARP_LS037V7DW01
11 tristate "Sharp LS037V7DW01 LCD Panel" 13 tristate "Sharp LS037V7DW01 LCD Panel"
@@ -14,11 +16,12 @@ config PANEL_SHARP_LS037V7DW01
14 help 16 help
15 LCD Panel used in TI's SDP3430 and EVM boards 17 LCD Panel used in TI's SDP3430 and EVM boards
16 18
17config PANEL_SHARP_LQ043T1DG01 19config PANEL_NEC_NL8048HL11_01B
18 tristate "Sharp LQ043T1DG01 LCD Panel" 20 tristate "NEC NL8048HL11-01B Panel"
19 depends on OMAP2_DSS 21 depends on OMAP2_DSS
20 help 22 help
21 LCD Panel used in TI's OMAP3517 EVM boards 23 This NEC NL8048HL11-01B panel is TFT LCD
24 used in the Zoom2/3/3630 sdp boards.
22 25
23config PANEL_TAAL 26config PANEL_TAAL
24 tristate "Taal DSI Panel" 27 tristate "Taal DSI Panel"
@@ -26,12 +29,6 @@ config PANEL_TAAL
26 help 29 help
27 Taal DSI command mode panel from TPO. 30 Taal DSI command mode panel from TPO.
28 31
29config PANEL_TOPPOLY_TDO35S
30 tristate "Toppoly TDO35S LCD Panel support"
31 depends on OMAP2_DSS
32 help
33 LCD Panel used in CM-T35
34
35config PANEL_TPO_TD043MTEA1 32config PANEL_TPO_TD043MTEA1
36 tristate "TPO TD043MTEA1 LCD Panel" 33 tristate "TPO TD043MTEA1 LCD Panel"
37 depends on OMAP2_DSS && SPI 34 depends on OMAP2_DSS && SPI
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index aa386095d7c4..861f0255ec6b 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,8 +1,7 @@
1obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 2obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
3obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o 3obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
4 4
5obj-$(CONFIG_PANEL_TAAL) += panel-taal.o 5obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
6obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o
7obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o 6obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
8obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o 7obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
new file mode 100644
index 000000000000..07eb30ee59c8
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -0,0 +1,365 @@
1/*
2 * Generic DPI Panels support
3 *
4 * Copyright (C) 2010 Canonical Ltd.
5 * Author: Bryan Wu <bryan.wu@canonical.com>
6 *
7 * LCD panel driver for Sharp LQ043T1DG01
8 *
9 * Copyright (C) 2009 Texas Instruments Inc
10 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
11 *
12 * LCD panel driver for Toppoly TDO35S
13 *
14 * Copyright (C) 2009 CompuLab, Ltd.
15 * Author: Mike Rapoport <mike@compulab.co.il>
16 *
17 * Copyright (C) 2008 Nokia Corporation
18 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
19 *
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License version 2 as published by
22 * the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful, but WITHOUT
25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27 * more details.
28 *
29 * You should have received a copy of the GNU General Public License along with
30 * this program. If not, see <http://www.gnu.org/licenses/>.
31 */
32
33#include <linux/module.h>
34#include <linux/delay.h>
35#include <linux/slab.h>
36
37#include <plat/panel-generic-dpi.h>
38
39struct panel_config {
40 struct omap_video_timings timings;
41
42 int acbi; /* ac-bias pin transitions per interrupt */
43 /* Unit: line clocks */
44 int acb; /* ac-bias pin frequency */
45
46 enum omap_panel_config config;
47
48 int power_on_delay;
49 int power_off_delay;
50
51 /*
52 * Used to match device to panel configuration
53 * when use generic panel driver
54 */
55 const char *name;
56};
57
58/* Panel configurations */
59static struct panel_config generic_dpi_panels[] = {
60 /* Generic Panel */
61 {
62 {
63 .x_res = 640,
64 .y_res = 480,
65
66 .pixel_clock = 23500,
67
68 .hfp = 48,
69 .hsw = 32,
70 .hbp = 80,
71
72 .vfp = 3,
73 .vsw = 4,
74 .vbp = 7,
75 },
76 .acbi = 0x0,
77 .acb = 0x0,
78 .config = OMAP_DSS_LCD_TFT,
79 .power_on_delay = 0,
80 .power_off_delay = 0,
81 .name = "generic",
82 },
83
84 /* Sharp LQ043T1DG01 */
85 {
86 {
87 .x_res = 480,
88 .y_res = 272,
89
90 .pixel_clock = 9000,
91
92 .hsw = 42,
93 .hfp = 3,
94 .hbp = 2,
95
96 .vsw = 11,
97 .vfp = 3,
98 .vbp = 2,
99 },
100 .acbi = 0x0,
101 .acb = 0x0,
102 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
103 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
104 .power_on_delay = 50,
105 .power_off_delay = 100,
106 .name = "sharp_lq",
107 },
108
109 /* Sharp LS037V7DW01 */
110 {
111 {
112 .x_res = 480,
113 .y_res = 640,
114
115 .pixel_clock = 19200,
116
117 .hsw = 2,
118 .hfp = 1,
119 .hbp = 28,
120
121 .vsw = 1,
122 .vfp = 1,
123 .vbp = 1,
124 },
125 .acbi = 0x0,
126 .acb = 0x28,
127 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
128 OMAP_DSS_LCD_IHS,
129 .power_on_delay = 50,
130 .power_off_delay = 100,
131 .name = "sharp_ls",
132 },
133
134 /* Toppoly TDO35S */
135 {
136 {
137 .x_res = 480,
138 .y_res = 640,
139
140 .pixel_clock = 26000,
141
142 .hfp = 104,
143 .hsw = 8,
144 .hbp = 8,
145
146 .vfp = 4,
147 .vsw = 2,
148 .vbp = 2,
149 },
150 .acbi = 0x0,
151 .acb = 0x0,
152 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
153 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC |
154 OMAP_DSS_LCD_ONOFF,
155 .power_on_delay = 0,
156 .power_off_delay = 0,
157 .name = "toppoly_tdo35s",
158 },
159};
160
161struct panel_drv_data {
162
163 struct omap_dss_device *dssdev;
164
165 struct panel_config *panel_config;
166};
167
168static inline struct panel_generic_dpi_data
169*get_panel_data(const struct omap_dss_device *dssdev)
170{
171 return (struct panel_generic_dpi_data *) dssdev->data;
172}
173
174static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
175{
176 int r;
177 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
178 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
179 struct panel_config *panel_config = drv_data->panel_config;
180
181 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
182 return 0;
183
184 r = omapdss_dpi_display_enable(dssdev);
185 if (r)
186 goto err0;
187
188 /* wait couple of vsyncs until enabling the LCD */
189 if (panel_config->power_on_delay)
190 msleep(panel_config->power_on_delay);
191
192 if (panel_data->platform_enable) {
193 r = panel_data->platform_enable(dssdev);
194 if (r)
195 goto err1;
196 }
197
198 return 0;
199err1:
200 omapdss_dpi_display_disable(dssdev);
201err0:
202 return r;
203}
204
205static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
206{
207 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
208 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
209 struct panel_config *panel_config = drv_data->panel_config;
210
211 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
212 return;
213
214 if (panel_data->platform_disable)
215 panel_data->platform_disable(dssdev);
216
217 /* wait couple of vsyncs after disabling the LCD */
218 if (panel_config->power_off_delay)
219 msleep(panel_config->power_off_delay);
220
221 omapdss_dpi_display_disable(dssdev);
222}
223
224static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
225{
226 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
227 struct panel_config *panel_config = NULL;
228 struct panel_drv_data *drv_data = NULL;
229 int i;
230
231 dev_dbg(&dssdev->dev, "probe\n");
232
233 if (!panel_data || !panel_data->name)
234 return -EINVAL;
235
236 for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) {
237 if (strcmp(panel_data->name, generic_dpi_panels[i].name) == 0) {
238 panel_config = &generic_dpi_panels[i];
239 break;
240 }
241 }
242
243 if (!panel_config)
244 return -EINVAL;
245
246 dssdev->panel.config = panel_config->config;
247 dssdev->panel.timings = panel_config->timings;
248 dssdev->panel.acb = panel_config->acb;
249 dssdev->panel.acbi = panel_config->acbi;
250
251 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
252 if (!drv_data)
253 return -ENOMEM;
254
255 drv_data->dssdev = dssdev;
256 drv_data->panel_config = panel_config;
257
258 dev_set_drvdata(&dssdev->dev, drv_data);
259
260 return 0;
261}
262
263static void generic_dpi_panel_remove(struct omap_dss_device *dssdev)
264{
265 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
266
267 dev_dbg(&dssdev->dev, "remove\n");
268
269 kfree(drv_data);
270
271 dev_set_drvdata(&dssdev->dev, NULL);
272}
273
274static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
275{
276 int r = 0;
277
278 r = generic_dpi_panel_power_on(dssdev);
279 if (r)
280 return r;
281
282 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
283
284 return 0;
285}
286
287static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
288{
289 generic_dpi_panel_power_off(dssdev);
290
291 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
292}
293
294static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
295{
296 generic_dpi_panel_power_off(dssdev);
297
298 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
299
300 return 0;
301}
302
303static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
304{
305 int r = 0;
306
307 r = generic_dpi_panel_power_on(dssdev);
308 if (r)
309 return r;
310
311 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
312
313 return 0;
314}
315
316static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
317 struct omap_video_timings *timings)
318{
319 dpi_set_timings(dssdev, timings);
320}
321
322static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
323 struct omap_video_timings *timings)
324{
325 *timings = dssdev->panel.timings;
326}
327
328static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
329 struct omap_video_timings *timings)
330{
331 return dpi_check_timings(dssdev, timings);
332}
333
334static struct omap_dss_driver dpi_driver = {
335 .probe = generic_dpi_panel_probe,
336 .remove = generic_dpi_panel_remove,
337
338 .enable = generic_dpi_panel_enable,
339 .disable = generic_dpi_panel_disable,
340 .suspend = generic_dpi_panel_suspend,
341 .resume = generic_dpi_panel_resume,
342
343 .set_timings = generic_dpi_panel_set_timings,
344 .get_timings = generic_dpi_panel_get_timings,
345 .check_timings = generic_dpi_panel_check_timings,
346
347 .driver = {
348 .name = "generic_dpi_panel",
349 .owner = THIS_MODULE,
350 },
351};
352
353static int __init generic_dpi_panel_drv_init(void)
354{
355 return omap_dss_register_driver(&dpi_driver);
356}
357
358static void __exit generic_dpi_panel_drv_exit(void)
359{
360 omap_dss_unregister_driver(&dpi_driver);
361}
362
363module_init(generic_dpi_panel_drv_init);
364module_exit(generic_dpi_panel_drv_exit);
365MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
deleted file mode 100644
index 395a68de3990..000000000000
--- a/drivers/video/omap2/displays/panel-generic.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * Generic panel support
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22
23#include <plat/display.h>
24
25static struct omap_video_timings generic_panel_timings = {
26 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
27 .x_res = 640,
28 .y_res = 480,
29 .pixel_clock = 23500,
30 .hfp = 48,
31 .hsw = 32,
32 .hbp = 80,
33 .vfp = 3,
34 .vsw = 4,
35 .vbp = 7,
36};
37
38static int generic_panel_power_on(struct omap_dss_device *dssdev)
39{
40 int r;
41
42 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
43 return 0;
44
45 r = omapdss_dpi_display_enable(dssdev);
46 if (r)
47 goto err0;
48
49 if (dssdev->platform_enable) {
50 r = dssdev->platform_enable(dssdev);
51 if (r)
52 goto err1;
53 }
54
55 return 0;
56err1:
57 omapdss_dpi_display_disable(dssdev);
58err0:
59 return r;
60}
61
62static void generic_panel_power_off(struct omap_dss_device *dssdev)
63{
64 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
65 return;
66
67 if (dssdev->platform_disable)
68 dssdev->platform_disable(dssdev);
69
70 omapdss_dpi_display_disable(dssdev);
71}
72
73static int generic_panel_probe(struct omap_dss_device *dssdev)
74{
75 dssdev->panel.config = OMAP_DSS_LCD_TFT;
76 dssdev->panel.timings = generic_panel_timings;
77
78 return 0;
79}
80
81static void generic_panel_remove(struct omap_dss_device *dssdev)
82{
83}
84
85static int generic_panel_enable(struct omap_dss_device *dssdev)
86{
87 int r = 0;
88
89 r = generic_panel_power_on(dssdev);
90 if (r)
91 return r;
92
93 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
94
95 return 0;
96}
97
98static void generic_panel_disable(struct omap_dss_device *dssdev)
99{
100 generic_panel_power_off(dssdev);
101
102 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
103}
104
105static int generic_panel_suspend(struct omap_dss_device *dssdev)
106{
107 generic_panel_power_off(dssdev);
108 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
109 return 0;
110}
111
112static int generic_panel_resume(struct omap_dss_device *dssdev)
113{
114 int r = 0;
115
116 r = generic_panel_power_on(dssdev);
117 if (r)
118 return r;
119
120 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
121
122 return 0;
123}
124
125static void generic_panel_set_timings(struct omap_dss_device *dssdev,
126 struct omap_video_timings *timings)
127{
128 dpi_set_timings(dssdev, timings);
129}
130
131static void generic_panel_get_timings(struct omap_dss_device *dssdev,
132 struct omap_video_timings *timings)
133{
134 *timings = dssdev->panel.timings;
135}
136
137static int generic_panel_check_timings(struct omap_dss_device *dssdev,
138 struct omap_video_timings *timings)
139{
140 return dpi_check_timings(dssdev, timings);
141}
142
143static struct omap_dss_driver generic_driver = {
144 .probe = generic_panel_probe,
145 .remove = generic_panel_remove,
146
147 .enable = generic_panel_enable,
148 .disable = generic_panel_disable,
149 .suspend = generic_panel_suspend,
150 .resume = generic_panel_resume,
151
152 .set_timings = generic_panel_set_timings,
153 .get_timings = generic_panel_get_timings,
154 .check_timings = generic_panel_check_timings,
155
156 .driver = {
157 .name = "generic_panel",
158 .owner = THIS_MODULE,
159 },
160};
161
162static int __init generic_panel_drv_init(void)
163{
164 return omap_dss_register_driver(&generic_driver);
165}
166
167static void __exit generic_panel_drv_exit(void)
168{
169 omap_dss_unregister_driver(&generic_driver);
170}
171
172module_init(generic_panel_drv_init);
173module_exit(generic_panel_drv_exit);
174MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
new file mode 100644
index 000000000000..925e0fadff54
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -0,0 +1,325 @@
1/*
2 * Support for NEC-nl8048hl11-01b panel driver
3 *
4 * Copyright (C) 2010 Texas Instruments Inc.
5 * Author: Erik Gilling <konkers@android.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/spi/spi.h>
22#include <linux/backlight.h>
23#include <linux/fb.h>
24
25#include <plat/display.h>
26
27#define LCD_XRES 800
28#define LCD_YRES 480
29/*
30 * NEC PIX Clock Ratings
31 * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz
32 */
33#define LCD_PIXEL_CLOCK 23800
34
35struct nec_8048_data {
36 struct backlight_device *bl;
37};
38
39static const struct {
40 unsigned char addr;
41 unsigned char dat;
42} nec_8048_init_seq[] = {
43 { 3, 0x01 }, { 0, 0x00 }, { 1, 0x01 }, { 4, 0x00 }, { 5, 0x14 },
44 { 6, 0x24 }, { 16, 0xD7 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x55 },
45 { 20, 0x01 }, { 21, 0x70 }, { 22, 0x1E }, { 23, 0x25 }, { 24, 0x25 },
46 { 25, 0x02 }, { 26, 0x02 }, { 27, 0xA0 }, { 32, 0x2F }, { 33, 0x0F },
47 { 34, 0x0F }, { 35, 0x0F }, { 36, 0x0F }, { 37, 0x0F }, { 38, 0x0F },
48 { 39, 0x00 }, { 40, 0x02 }, { 41, 0x02 }, { 42, 0x02 }, { 43, 0x0F },
49 { 44, 0x0F }, { 45, 0x0F }, { 46, 0x0F }, { 47, 0x0F }, { 48, 0x0F },
50 { 49, 0x0F }, { 50, 0x00 }, { 51, 0x02 }, { 52, 0x02 }, { 53, 0x02 },
51 { 80, 0x0C }, { 83, 0x42 }, { 84, 0x42 }, { 85, 0x41 }, { 86, 0x14 },
52 { 89, 0x88 }, { 90, 0x01 }, { 91, 0x00 }, { 92, 0x02 }, { 93, 0x0C },
53 { 94, 0x1C }, { 95, 0x27 }, { 98, 0x49 }, { 99, 0x27 }, { 102, 0x76 },
54 { 103, 0x27 }, { 112, 0x01 }, { 113, 0x0E }, { 114, 0x02 },
55 { 115, 0x0C }, { 118, 0x0C }, { 121, 0x30 }, { 130, 0x00 },
56 { 131, 0x00 }, { 132, 0xFC }, { 134, 0x00 }, { 136, 0x00 },
57 { 138, 0x00 }, { 139, 0x00 }, { 140, 0x00 }, { 141, 0xFC },
58 { 143, 0x00 }, { 145, 0x00 }, { 147, 0x00 }, { 148, 0x00 },
59 { 149, 0x00 }, { 150, 0xFC }, { 152, 0x00 }, { 154, 0x00 },
60 { 156, 0x00 }, { 157, 0x00 }, { 2, 0x00 },
61};
62
63/*
64 * NEC NL8048HL11-01B Manual
65 * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below
66 */
67
68static struct omap_video_timings nec_8048_panel_timings = {
69 /* 800 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
70 .x_res = LCD_XRES,
71 .y_res = LCD_YRES,
72 .pixel_clock = LCD_PIXEL_CLOCK,
73 .hfp = 6,
74 .hsw = 1,
75 .hbp = 4,
76 .vfp = 3,
77 .vsw = 1,
78 .vbp = 4,
79};
80
81static int nec_8048_bl_update_status(struct backlight_device *bl)
82{
83 struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev);
84 int level;
85
86 if (!dssdev->set_backlight)
87 return -EINVAL;
88
89 if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
90 bl->props.power == FB_BLANK_UNBLANK)
91 level = bl->props.brightness;
92 else
93 level = 0;
94
95 return dssdev->set_backlight(dssdev, level);
96}
97
98static int nec_8048_bl_get_brightness(struct backlight_device *bl)
99{
100 if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
101 bl->props.power == FB_BLANK_UNBLANK)
102 return bl->props.brightness;
103
104 return 0;
105}
106
107static const struct backlight_ops nec_8048_bl_ops = {
108 .get_brightness = nec_8048_bl_get_brightness,
109 .update_status = nec_8048_bl_update_status,
110};
111
112static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
113{
114 struct backlight_device *bl;
115 struct nec_8048_data *necd;
116 struct backlight_properties props;
117 int r;
118
119 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
120 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_RF |
121 OMAP_DSS_LCD_ONOFF;
122 dssdev->panel.timings = nec_8048_panel_timings;
123
124 necd = kzalloc(sizeof(*necd), GFP_KERNEL);
125 if (!necd)
126 return -ENOMEM;
127
128 dev_set_drvdata(&dssdev->dev, necd);
129
130 memset(&props, 0, sizeof(struct backlight_properties));
131 props.max_brightness = 255;
132
133 bl = backlight_device_register("nec-8048", &dssdev->dev, dssdev,
134 &nec_8048_bl_ops, &props);
135 if (IS_ERR(bl)) {
136 r = PTR_ERR(bl);
137 kfree(necd);
138 return r;
139 }
140 necd->bl = bl;
141
142 bl->props.fb_blank = FB_BLANK_UNBLANK;
143 bl->props.power = FB_BLANK_UNBLANK;
144 bl->props.max_brightness = dssdev->max_backlight_level;
145 bl->props.brightness = dssdev->max_backlight_level;
146
147 r = nec_8048_bl_update_status(bl);
148 if (r < 0)
149 dev_err(&dssdev->dev, "failed to set lcd brightness\n");
150
151 return 0;
152}
153
154static void nec_8048_panel_remove(struct omap_dss_device *dssdev)
155{
156 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
157 struct backlight_device *bl = necd->bl;
158
159 bl->props.power = FB_BLANK_POWERDOWN;
160 nec_8048_bl_update_status(bl);
161 backlight_device_unregister(bl);
162
163 kfree(necd);
164}
165
166static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
167{
168 int r = 0;
169 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
170 struct backlight_device *bl = necd->bl;
171
172 if (dssdev->platform_enable) {
173 r = dssdev->platform_enable(dssdev);
174 if (r)
175 return r;
176 }
177
178 r = nec_8048_bl_update_status(bl);
179 if (r < 0)
180 dev_err(&dssdev->dev, "failed to set lcd brightness\n");
181
182 r = omapdss_dpi_display_enable(dssdev);
183
184 return r;
185}
186
187static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
188{
189 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
190 struct backlight_device *bl = necd->bl;
191
192 omapdss_dpi_display_disable(dssdev);
193
194 bl->props.brightness = 0;
195 nec_8048_bl_update_status(bl);
196
197 if (dssdev->platform_disable)
198 dssdev->platform_disable(dssdev);
199}
200
201static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
202{
203 nec_8048_panel_disable(dssdev);
204 return 0;
205}
206
207static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
208{
209 return nec_8048_panel_enable(dssdev);
210}
211
212static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
213{
214 return 16;
215}
216
217static struct omap_dss_driver nec_8048_driver = {
218 .probe = nec_8048_panel_probe,
219 .remove = nec_8048_panel_remove,
220 .enable = nec_8048_panel_enable,
221 .disable = nec_8048_panel_disable,
222 .suspend = nec_8048_panel_suspend,
223 .resume = nec_8048_panel_resume,
224 .get_recommended_bpp = nec_8048_recommended_bpp,
225
226 .driver = {
227 .name = "NEC_8048_panel",
228 .owner = THIS_MODULE,
229 },
230};
231
232static int nec_8048_spi_send(struct spi_device *spi, unsigned char reg_addr,
233 unsigned char reg_data)
234{
235 int ret = 0;
236 unsigned int cmd = 0, data = 0;
237
238 cmd = 0x0000 | reg_addr; /* register address write */
239 data = 0x0100 | reg_data ; /* register data write */
240 data = (cmd << 16) | data;
241
242 ret = spi_write(spi, (unsigned char *)&data, 4);
243 if (ret)
244 pr_err("error in spi_write %x\n", data);
245
246 return ret;
247}
248
249static int init_nec_8048_wvga_lcd(struct spi_device *spi)
250{
251 unsigned int i;
252 /* Initialization Sequence */
253 /* nec_8048_spi_send(spi, REG, VAL) */
254 for (i = 0; i < (ARRAY_SIZE(nec_8048_init_seq) - 1); i++)
255 nec_8048_spi_send(spi, nec_8048_init_seq[i].addr,
256 nec_8048_init_seq[i].dat);
257 udelay(20);
258 nec_8048_spi_send(spi, nec_8048_init_seq[i].addr,
259 nec_8048_init_seq[i].dat);
260 return 0;
261}
262
263static int nec_8048_spi_probe(struct spi_device *spi)
264{
265 spi->mode = SPI_MODE_0;
266 spi->bits_per_word = 32;
267 spi_setup(spi);
268
269 init_nec_8048_wvga_lcd(spi);
270
271 return omap_dss_register_driver(&nec_8048_driver);
272}
273
274static int nec_8048_spi_remove(struct spi_device *spi)
275{
276 omap_dss_unregister_driver(&nec_8048_driver);
277
278 return 0;
279}
280
281static int nec_8048_spi_suspend(struct spi_device *spi, pm_message_t mesg)
282{
283 nec_8048_spi_send(spi, 2, 0x01);
284 mdelay(40);
285
286 return 0;
287}
288
289static int nec_8048_spi_resume(struct spi_device *spi)
290{
291 /* reinitialize the panel */
292 spi_setup(spi);
293 nec_8048_spi_send(spi, 2, 0x00);
294 init_nec_8048_wvga_lcd(spi);
295
296 return 0;
297}
298
299static struct spi_driver nec_8048_spi_driver = {
300 .probe = nec_8048_spi_probe,
301 .remove = __devexit_p(nec_8048_spi_remove),
302 .suspend = nec_8048_spi_suspend,
303 .resume = nec_8048_spi_resume,
304 .driver = {
305 .name = "nec_8048_spi",
306 .bus = &spi_bus_type,
307 .owner = THIS_MODULE,
308 },
309};
310
311static int __init nec_8048_lcd_init(void)
312{
313 return spi_register_driver(&nec_8048_spi_driver);
314}
315
316static void __exit nec_8048_lcd_exit(void)
317{
318 return spi_unregister_driver(&nec_8048_spi_driver);
319}
320
321module_init(nec_8048_lcd_init);
322module_exit(nec_8048_lcd_exit);
323MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
324MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver");
325MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
deleted file mode 100644
index 0c6896cea2d0..000000000000
--- a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * LCD panel driver for Sharp LQ043T1DG01
3 *
4 * Copyright (C) 2009 Texas Instruments Inc
5 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/err.h>
24
25#include <plat/display.h>
26
27static struct omap_video_timings sharp_lq_timings = {
28 .x_res = 480,
29 .y_res = 272,
30
31 .pixel_clock = 9000,
32
33 .hsw = 42,
34 .hfp = 3,
35 .hbp = 2,
36
37 .vsw = 11,
38 .vfp = 3,
39 .vbp = 2,
40};
41
42static int sharp_lq_panel_power_on(struct omap_dss_device *dssdev)
43{
44 int r;
45
46 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
47 return 0;
48
49 r = omapdss_dpi_display_enable(dssdev);
50 if (r)
51 goto err0;
52
53 /* wait couple of vsyncs until enabling the LCD */
54 msleep(50);
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void sharp_lq_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 /* wait at least 5 vsyncs after disabling the LCD */
78 msleep(100);
79
80 omapdss_dpi_display_disable(dssdev);
81}
82
83static int sharp_lq_panel_probe(struct omap_dss_device *dssdev)
84{
85
86 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
87 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO;
88 dssdev->panel.acb = 0x0;
89 dssdev->panel.timings = sharp_lq_timings;
90
91 return 0;
92}
93
94static void sharp_lq_panel_remove(struct omap_dss_device *dssdev)
95{
96}
97
98static int sharp_lq_panel_enable(struct omap_dss_device *dssdev)
99{
100 int r = 0;
101
102 r = sharp_lq_panel_power_on(dssdev);
103 if (r)
104 return r;
105
106 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
107
108 return 0;
109}
110
111static void sharp_lq_panel_disable(struct omap_dss_device *dssdev)
112{
113 sharp_lq_panel_power_off(dssdev);
114
115 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
116}
117
118static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev)
119{
120 sharp_lq_panel_power_off(dssdev);
121 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
122 return 0;
123}
124
125static int sharp_lq_panel_resume(struct omap_dss_device *dssdev)
126{
127 int r = 0;
128
129 r = sharp_lq_panel_power_on(dssdev);
130 if (r)
131 return r;
132
133 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
134
135 return 0;
136}
137
138static struct omap_dss_driver sharp_lq_driver = {
139 .probe = sharp_lq_panel_probe,
140 .remove = sharp_lq_panel_remove,
141
142 .enable = sharp_lq_panel_enable,
143 .disable = sharp_lq_panel_disable,
144 .suspend = sharp_lq_panel_suspend,
145 .resume = sharp_lq_panel_resume,
146
147 .driver = {
148 .name = "sharp_lq_panel",
149 .owner = THIS_MODULE,
150 },
151};
152
153static int __init sharp_lq_panel_drv_init(void)
154{
155 return omap_dss_register_driver(&sharp_lq_driver);
156}
157
158static void __exit sharp_lq_panel_drv_exit(void)
159{
160 omap_dss_unregister_driver(&sharp_lq_driver);
161}
162
163module_init(sharp_lq_panel_drv_init);
164module_exit(sharp_lq_panel_drv_exit);
165MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
deleted file mode 100644
index 526e906c8a6c..000000000000
--- a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * LCD panel driver for Toppoly TDO35S
3 *
4 * Copyright (C) 2009 CompuLab, Ltd.
5 * Author: Mike Rapoport <mike@compulab.co.il>
6 *
7 * Based on generic panel support
8 * Copyright (C) 2008 Nokia Corporation
9 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published by
13 * the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <linux/module.h>
25#include <linux/delay.h>
26
27#include <plat/display.h>
28
29static struct omap_video_timings toppoly_tdo_panel_timings = {
30 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
31 .x_res = 480,
32 .y_res = 640,
33
34 .pixel_clock = 26000,
35
36 .hfp = 104,
37 .hsw = 8,
38 .hbp = 8,
39
40 .vfp = 4,
41 .vsw = 2,
42 .vbp = 2,
43};
44
45static int toppoly_tdo_panel_power_on(struct omap_dss_device *dssdev)
46{
47 int r;
48
49 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
50 return 0;
51
52 r = omapdss_dpi_display_enable(dssdev);
53 if (r)
54 goto err0;
55
56 if (dssdev->platform_enable) {
57 r = dssdev->platform_enable(dssdev);
58 if (r)
59 goto err1;
60 }
61
62 return 0;
63err1:
64 omapdss_dpi_display_disable(dssdev);
65err0:
66 return r;
67}
68
69static void toppoly_tdo_panel_power_off(struct omap_dss_device *dssdev)
70{
71 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
72 return;
73
74 if (dssdev->platform_disable)
75 dssdev->platform_disable(dssdev);
76
77 omapdss_dpi_display_disable(dssdev);
78}
79
80static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev)
81{
82 dssdev->panel.config = OMAP_DSS_LCD_TFT |
83 OMAP_DSS_LCD_IVS |
84 OMAP_DSS_LCD_IHS |
85 OMAP_DSS_LCD_IPC |
86 OMAP_DSS_LCD_ONOFF;
87
88 dssdev->panel.timings = toppoly_tdo_panel_timings;
89
90 return 0;
91}
92
93static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev)
94{
95}
96
97static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev)
98{
99 int r = 0;
100
101 r = toppoly_tdo_panel_power_on(dssdev);
102 if (r)
103 return r;
104
105 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
106
107 return 0;
108}
109
110static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev)
111{
112 toppoly_tdo_panel_power_off(dssdev);
113
114 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
115}
116
117static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev)
118{
119 toppoly_tdo_panel_power_off(dssdev);
120 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
121 return 0;
122}
123
124static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev)
125{
126 int r = 0;
127
128 r = toppoly_tdo_panel_power_on(dssdev);
129 if (r)
130 return r;
131
132 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
133
134 return 0;
135}
136
137static struct omap_dss_driver generic_driver = {
138 .probe = toppoly_tdo_panel_probe,
139 .remove = toppoly_tdo_panel_remove,
140
141 .enable = toppoly_tdo_panel_enable,
142 .disable = toppoly_tdo_panel_disable,
143 .suspend = toppoly_tdo_panel_suspend,
144 .resume = toppoly_tdo_panel_resume,
145
146 .driver = {
147 .name = "toppoly_tdo35s_panel",
148 .owner = THIS_MODULE,
149 },
150};
151
152static int __init toppoly_tdo_panel_drv_init(void)
153{
154 return omap_dss_register_driver(&generic_driver);
155}
156
157static void __exit toppoly_tdo_panel_drv_exit(void)
158{
159 omap_dss_unregister_driver(&generic_driver);
160}
161
162module_init(toppoly_tdo_panel_drv_init);
163module_exit(toppoly_tdo_panel_drv_exit);
164MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fa40fa59a9ac..9f8c69f16e61 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -44,34 +44,40 @@
44/* DISPC */ 44/* DISPC */
45#define DISPC_BASE 0x48050400 45#define DISPC_BASE 0x48050400
46 46
47#define DISPC_SZ_REGS SZ_1K 47#define DISPC_SZ_REGS SZ_4K
48 48
49struct dispc_reg { u16 idx; }; 49struct dispc_reg { u16 idx; };
50 50
51#define DISPC_REG(idx) ((const struct dispc_reg) { idx }) 51#define DISPC_REG(idx) ((const struct dispc_reg) { idx })
52 52
53/* DISPC common */ 53/*
54 * DISPC common registers and
55 * DISPC channel registers , ch = 0 for LCD, ch = 1 for
56 * DIGIT, and ch = 2 for LCD2
57 */
54#define DISPC_REVISION DISPC_REG(0x0000) 58#define DISPC_REVISION DISPC_REG(0x0000)
55#define DISPC_SYSCONFIG DISPC_REG(0x0010) 59#define DISPC_SYSCONFIG DISPC_REG(0x0010)
56#define DISPC_SYSSTATUS DISPC_REG(0x0014) 60#define DISPC_SYSSTATUS DISPC_REG(0x0014)
57#define DISPC_IRQSTATUS DISPC_REG(0x0018) 61#define DISPC_IRQSTATUS DISPC_REG(0x0018)
58#define DISPC_IRQENABLE DISPC_REG(0x001C) 62#define DISPC_IRQENABLE DISPC_REG(0x001C)
59#define DISPC_CONTROL DISPC_REG(0x0040) 63#define DISPC_CONTROL DISPC_REG(0x0040)
64#define DISPC_CONTROL2 DISPC_REG(0x0238)
60#define DISPC_CONFIG DISPC_REG(0x0044) 65#define DISPC_CONFIG DISPC_REG(0x0044)
66#define DISPC_CONFIG2 DISPC_REG(0x0620)
61#define DISPC_CAPABLE DISPC_REG(0x0048) 67#define DISPC_CAPABLE DISPC_REG(0x0048)
62#define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C) 68#define DISPC_DEFAULT_COLOR(ch) DISPC_REG(ch == 0 ? 0x004C : \
63#define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050) 69 (ch == 1 ? 0x0050 : 0x03AC))
64#define DISPC_TRANS_COLOR0 DISPC_REG(0x0054) 70#define DISPC_TRANS_COLOR(ch) DISPC_REG(ch == 0 ? 0x0054 : \
65#define DISPC_TRANS_COLOR1 DISPC_REG(0x0058) 71 (ch == 1 ? 0x0058 : 0x03B0))
66#define DISPC_LINE_STATUS DISPC_REG(0x005C) 72#define DISPC_LINE_STATUS DISPC_REG(0x005C)
67#define DISPC_LINE_NUMBER DISPC_REG(0x0060) 73#define DISPC_LINE_NUMBER DISPC_REG(0x0060)
68#define DISPC_TIMING_H DISPC_REG(0x0064) 74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
69#define DISPC_TIMING_V DISPC_REG(0x0068) 75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
70#define DISPC_POL_FREQ DISPC_REG(0x006C) 76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
71#define DISPC_DIVISOR DISPC_REG(0x0070) 77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
72#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
73#define DISPC_SIZE_DIG DISPC_REG(0x0078) 79#define DISPC_SIZE_DIG DISPC_REG(0x0078)
74#define DISPC_SIZE_LCD DISPC_REG(0x007C) 80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
75 81
76/* DISPC GFX plane */ 82/* DISPC GFX plane */
77#define DISPC_GFX_BA0 DISPC_REG(0x0080) 83#define DISPC_GFX_BA0 DISPC_REG(0x0080)
@@ -86,13 +92,12 @@ struct dispc_reg { u16 idx; };
86#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4) 92#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
87#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8) 93#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
88 94
89#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4) 95#define DISPC_DATA_CYCLE1(ch) DISPC_REG(ch != 2 ? 0x01D4 : 0x03C0)
90#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8) 96#define DISPC_DATA_CYCLE2(ch) DISPC_REG(ch != 2 ? 0x01D8 : 0x03C4)
91#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC) 97#define DISPC_DATA_CYCLE3(ch) DISPC_REG(ch != 2 ? 0x01DC : 0x03C8)
92 98#define DISPC_CPR_COEF_R(ch) DISPC_REG(ch != 2 ? 0x0220 : 0x03BC)
93#define DISPC_CPR_COEF_R DISPC_REG(0x0220) 99#define DISPC_CPR_COEF_G(ch) DISPC_REG(ch != 2 ? 0x0224 : 0x03B8)
94#define DISPC_CPR_COEF_G DISPC_REG(0x0224) 100#define DISPC_CPR_COEF_B(ch) DISPC_REG(ch != 2 ? 0x0228 : 0x03B4)
95#define DISPC_CPR_COEF_B DISPC_REG(0x0228)
96 101
97#define DISPC_GFX_PRELOAD DISPC_REG(0x022C) 102#define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
98 103
@@ -217,18 +222,29 @@ void dispc_save_context(void)
217 SR(IRQENABLE); 222 SR(IRQENABLE);
218 SR(CONTROL); 223 SR(CONTROL);
219 SR(CONFIG); 224 SR(CONFIG);
220 SR(DEFAULT_COLOR0); 225 SR(DEFAULT_COLOR(0));
221 SR(DEFAULT_COLOR1); 226 SR(DEFAULT_COLOR(1));
222 SR(TRANS_COLOR0); 227 SR(TRANS_COLOR(0));
223 SR(TRANS_COLOR1); 228 SR(TRANS_COLOR(1));
224 SR(LINE_NUMBER); 229 SR(LINE_NUMBER);
225 SR(TIMING_H); 230 SR(TIMING_H(0));
226 SR(TIMING_V); 231 SR(TIMING_V(0));
227 SR(POL_FREQ); 232 SR(POL_FREQ(0));
228 SR(DIVISOR); 233 SR(DIVISOR(0));
229 SR(GLOBAL_ALPHA); 234 SR(GLOBAL_ALPHA);
230 SR(SIZE_DIG); 235 SR(SIZE_DIG);
231 SR(SIZE_LCD); 236 SR(SIZE_LCD(0));
237 if (dss_has_feature(FEAT_MGR_LCD2)) {
238 SR(CONTROL2);
239 SR(DEFAULT_COLOR(2));
240 SR(TRANS_COLOR(2));
241 SR(SIZE_LCD(2));
242 SR(TIMING_H(2));
243 SR(TIMING_V(2));
244 SR(POL_FREQ(2));
245 SR(DIVISOR(2));
246 SR(CONFIG2);
247 }
232 248
233 SR(GFX_BA0); 249 SR(GFX_BA0);
234 SR(GFX_BA1); 250 SR(GFX_BA1);
@@ -241,13 +257,22 @@ void dispc_save_context(void)
241 SR(GFX_WINDOW_SKIP); 257 SR(GFX_WINDOW_SKIP);
242 SR(GFX_TABLE_BA); 258 SR(GFX_TABLE_BA);
243 259
244 SR(DATA_CYCLE1); 260 SR(DATA_CYCLE1(0));
245 SR(DATA_CYCLE2); 261 SR(DATA_CYCLE2(0));
246 SR(DATA_CYCLE3); 262 SR(DATA_CYCLE3(0));
247 263
248 SR(CPR_COEF_R); 264 SR(CPR_COEF_R(0));
249 SR(CPR_COEF_G); 265 SR(CPR_COEF_G(0));
250 SR(CPR_COEF_B); 266 SR(CPR_COEF_B(0));
267 if (dss_has_feature(FEAT_MGR_LCD2)) {
268 SR(CPR_COEF_B(2));
269 SR(CPR_COEF_G(2));
270 SR(CPR_COEF_R(2));
271
272 SR(DATA_CYCLE1(2));
273 SR(DATA_CYCLE2(2));
274 SR(DATA_CYCLE3(2));
275 }
251 276
252 SR(GFX_PRELOAD); 277 SR(GFX_PRELOAD);
253 278
@@ -356,18 +381,28 @@ void dispc_restore_context(void)
356 /*RR(IRQENABLE);*/ 381 /*RR(IRQENABLE);*/
357 /*RR(CONTROL);*/ 382 /*RR(CONTROL);*/
358 RR(CONFIG); 383 RR(CONFIG);
359 RR(DEFAULT_COLOR0); 384 RR(DEFAULT_COLOR(0));
360 RR(DEFAULT_COLOR1); 385 RR(DEFAULT_COLOR(1));
361 RR(TRANS_COLOR0); 386 RR(TRANS_COLOR(0));
362 RR(TRANS_COLOR1); 387 RR(TRANS_COLOR(1));
363 RR(LINE_NUMBER); 388 RR(LINE_NUMBER);
364 RR(TIMING_H); 389 RR(TIMING_H(0));
365 RR(TIMING_V); 390 RR(TIMING_V(0));
366 RR(POL_FREQ); 391 RR(POL_FREQ(0));
367 RR(DIVISOR); 392 RR(DIVISOR(0));
368 RR(GLOBAL_ALPHA); 393 RR(GLOBAL_ALPHA);
369 RR(SIZE_DIG); 394 RR(SIZE_DIG);
370 RR(SIZE_LCD); 395 RR(SIZE_LCD(0));
396 if (dss_has_feature(FEAT_MGR_LCD2)) {
397 RR(DEFAULT_COLOR(2));
398 RR(TRANS_COLOR(2));
399 RR(SIZE_LCD(2));
400 RR(TIMING_H(2));
401 RR(TIMING_V(2));
402 RR(POL_FREQ(2));
403 RR(DIVISOR(2));
404 RR(CONFIG2);
405 }
371 406
372 RR(GFX_BA0); 407 RR(GFX_BA0);
373 RR(GFX_BA1); 408 RR(GFX_BA1);
@@ -380,13 +415,22 @@ void dispc_restore_context(void)
380 RR(GFX_WINDOW_SKIP); 415 RR(GFX_WINDOW_SKIP);
381 RR(GFX_TABLE_BA); 416 RR(GFX_TABLE_BA);
382 417
383 RR(DATA_CYCLE1); 418 RR(DATA_CYCLE1(0));
384 RR(DATA_CYCLE2); 419 RR(DATA_CYCLE2(0));
385 RR(DATA_CYCLE3); 420 RR(DATA_CYCLE3(0));
386 421
387 RR(CPR_COEF_R); 422 RR(CPR_COEF_R(0));
388 RR(CPR_COEF_G); 423 RR(CPR_COEF_G(0));
389 RR(CPR_COEF_B); 424 RR(CPR_COEF_B(0));
425 if (dss_has_feature(FEAT_MGR_LCD2)) {
426 RR(DATA_CYCLE1(2));
427 RR(DATA_CYCLE2(2));
428 RR(DATA_CYCLE3(2));
429
430 RR(CPR_COEF_B(2));
431 RR(CPR_COEF_G(2));
432 RR(CPR_COEF_R(2));
433 }
390 434
391 RR(GFX_PRELOAD); 435 RR(GFX_PRELOAD);
392 436
@@ -490,7 +534,8 @@ void dispc_restore_context(void)
490 534
491 /* enable last, because LCD & DIGIT enable are here */ 535 /* enable last, because LCD & DIGIT enable are here */
492 RR(CONTROL); 536 RR(CONTROL);
493 537 if (dss_has_feature(FEAT_MGR_LCD2))
538 RR(CONTROL2);
494 /* clear spurious SYNC_LOST_DIGIT interrupts */ 539 /* clear spurious SYNC_LOST_DIGIT interrupts */
495 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 540 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
496 541
@@ -516,42 +561,63 @@ bool dispc_go_busy(enum omap_channel channel)
516{ 561{
517 int bit; 562 int bit;
518 563
519 if (channel == OMAP_DSS_CHANNEL_LCD) 564 if (channel == OMAP_DSS_CHANNEL_LCD ||
565 channel == OMAP_DSS_CHANNEL_LCD2)
520 bit = 5; /* GOLCD */ 566 bit = 5; /* GOLCD */
521 else 567 else
522 bit = 6; /* GODIGIT */ 568 bit = 6; /* GODIGIT */
523 569
524 return REG_GET(DISPC_CONTROL, bit, bit) == 1; 570 if (channel == OMAP_DSS_CHANNEL_LCD2)
571 return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
572 else
573 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
525} 574}
526 575
527void dispc_go(enum omap_channel channel) 576void dispc_go(enum omap_channel channel)
528{ 577{
529 int bit; 578 int bit;
579 bool enable_bit, go_bit;
530 580
531 enable_clocks(1); 581 enable_clocks(1);
532 582
533 if (channel == OMAP_DSS_CHANNEL_LCD) 583 if (channel == OMAP_DSS_CHANNEL_LCD ||
584 channel == OMAP_DSS_CHANNEL_LCD2)
534 bit = 0; /* LCDENABLE */ 585 bit = 0; /* LCDENABLE */
535 else 586 else
536 bit = 1; /* DIGITALENABLE */ 587 bit = 1; /* DIGITALENABLE */
537 588
538 /* if the channel is not enabled, we don't need GO */ 589 /* if the channel is not enabled, we don't need GO */
539 if (REG_GET(DISPC_CONTROL, bit, bit) == 0) 590 if (channel == OMAP_DSS_CHANNEL_LCD2)
591 enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
592 else
593 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
594
595 if (!enable_bit)
540 goto end; 596 goto end;
541 597
542 if (channel == OMAP_DSS_CHANNEL_LCD) 598 if (channel == OMAP_DSS_CHANNEL_LCD ||
599 channel == OMAP_DSS_CHANNEL_LCD2)
543 bit = 5; /* GOLCD */ 600 bit = 5; /* GOLCD */
544 else 601 else
545 bit = 6; /* GODIGIT */ 602 bit = 6; /* GODIGIT */
546 603
547 if (REG_GET(DISPC_CONTROL, bit, bit) == 1) { 604 if (channel == OMAP_DSS_CHANNEL_LCD2)
605 go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
606 else
607 go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
608
609 if (go_bit) {
548 DSSERR("GO bit not down for channel %d\n", channel); 610 DSSERR("GO bit not down for channel %d\n", channel);
549 goto end; 611 goto end;
550 } 612 }
551 613
552 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT"); 614 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" :
615 (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
553 616
554 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 617 if (channel == OMAP_DSS_CHANNEL_LCD2)
618 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
619 else
620 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
555end: 621end:
556 enable_clocks(0); 622 enable_clocks(0);
557} 623}
@@ -773,13 +839,26 @@ static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
773 dispc_write_reg(vsi_reg[plane-1], val); 839 dispc_write_reg(vsi_reg[plane-1], val);
774} 840}
775 841
842static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
843{
844 if (!dss_has_feature(FEAT_PRE_MULT_ALPHA))
845 return;
846
847 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
848 plane == OMAP_DSS_VIDEO1)
849 return;
850
851 REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 28, 28);
852}
853
776static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) 854static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
777{ 855{
778 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 856 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
779 return; 857 return;
780 858
781 BUG_ON(!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) && 859 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
782 plane == OMAP_DSS_VIDEO1); 860 plane == OMAP_DSS_VIDEO1)
861 return;
783 862
784 if (plane == OMAP_DSS_GFX) 863 if (plane == OMAP_DSS_GFX)
785 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0); 864 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0);
@@ -851,6 +930,7 @@ static void _dispc_set_channel_out(enum omap_plane plane,
851{ 930{
852 int shift; 931 int shift;
853 u32 val; 932 u32 val;
933 int chan = 0, chan2 = 0;
854 934
855 switch (plane) { 935 switch (plane) {
856 case OMAP_DSS_GFX: 936 case OMAP_DSS_GFX:
@@ -866,7 +946,29 @@ static void _dispc_set_channel_out(enum omap_plane plane,
866 } 946 }
867 947
868 val = dispc_read_reg(dispc_reg_att[plane]); 948 val = dispc_read_reg(dispc_reg_att[plane]);
869 val = FLD_MOD(val, channel, shift, shift); 949 if (dss_has_feature(FEAT_MGR_LCD2)) {
950 switch (channel) {
951 case OMAP_DSS_CHANNEL_LCD:
952 chan = 0;
953 chan2 = 0;
954 break;
955 case OMAP_DSS_CHANNEL_DIGIT:
956 chan = 1;
957 chan2 = 0;
958 break;
959 case OMAP_DSS_CHANNEL_LCD2:
960 chan = 0;
961 chan2 = 1;
962 break;
963 default:
964 BUG();
965 }
966
967 val = FLD_MOD(val, chan, shift, shift);
968 val = FLD_MOD(val, chan2, 31, 30);
969 } else {
970 val = FLD_MOD(val, channel, shift, shift);
971 }
870 dispc_write_reg(dispc_reg_att[plane], val); 972 dispc_write_reg(dispc_reg_att[plane], val);
871} 973}
872 974
@@ -923,13 +1025,13 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
923 enable_clocks(0); 1025 enable_clocks(0);
924} 1026}
925 1027
926void dispc_set_lcd_size(u16 width, u16 height) 1028void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
927{ 1029{
928 u32 val; 1030 u32 val;
929 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1031 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
930 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1032 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
931 enable_clocks(1); 1033 enable_clocks(1);
932 dispc_write_reg(DISPC_SIZE_LCD, val); 1034 dispc_write_reg(DISPC_SIZE_LCD(channel), val);
933 enable_clocks(0); 1035 enable_clocks(0);
934} 1036}
935 1037
@@ -1426,12 +1528,13 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
1426 } 1528 }
1427} 1529}
1428 1530
1429static unsigned long calc_fclk_five_taps(u16 width, u16 height, 1531static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1430 u16 out_width, u16 out_height, enum omap_color_mode color_mode) 1532 u16 height, u16 out_width, u16 out_height,
1533 enum omap_color_mode color_mode)
1431{ 1534{
1432 u32 fclk = 0; 1535 u32 fclk = 0;
1433 /* FIXME venc pclk? */ 1536 /* FIXME venc pclk? */
1434 u64 tmp, pclk = dispc_pclk_rate(); 1537 u64 tmp, pclk = dispc_pclk_rate(channel);
1435 1538
1436 if (height > out_height) { 1539 if (height > out_height) {
1437 /* FIXME get real display PPL */ 1540 /* FIXME get real display PPL */
@@ -1463,8 +1566,8 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height,
1463 return fclk; 1566 return fclk;
1464} 1567}
1465 1568
1466static unsigned long calc_fclk(u16 width, u16 height, 1569static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1467 u16 out_width, u16 out_height) 1570 u16 height, u16 out_width, u16 out_height)
1468{ 1571{
1469 unsigned int hf, vf; 1572 unsigned int hf, vf;
1470 1573
@@ -1488,7 +1591,7 @@ static unsigned long calc_fclk(u16 width, u16 height,
1488 vf = 1; 1591 vf = 1;
1489 1592
1490 /* FIXME venc pclk? */ 1593 /* FIXME venc pclk? */
1491 return dispc_pclk_rate() * vf * hf; 1594 return dispc_pclk_rate(channel) * vf * hf;
1492} 1595}
1493 1596
1494void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) 1597void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
@@ -1507,7 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1507 bool ilace, 1610 bool ilace,
1508 enum omap_dss_rotation_type rotation_type, 1611 enum omap_dss_rotation_type rotation_type,
1509 u8 rotation, int mirror, 1612 u8 rotation, int mirror,
1510 u8 global_alpha) 1613 u8 global_alpha, u8 pre_mult_alpha,
1614 enum omap_channel channel)
1511{ 1615{
1512 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; 1616 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1513 bool five_taps = 0; 1617 bool five_taps = 0;
@@ -1536,29 +1640,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
1536 height, pos_y, out_height); 1640 height, pos_y, out_height);
1537 } 1641 }
1538 1642
1643 if (!dss_feat_color_mode_supported(plane, color_mode))
1644 return -EINVAL;
1645
1539 if (plane == OMAP_DSS_GFX) { 1646 if (plane == OMAP_DSS_GFX) {
1540 if (width != out_width || height != out_height) 1647 if (width != out_width || height != out_height)
1541 return -EINVAL; 1648 return -EINVAL;
1542
1543 switch (color_mode) {
1544 case OMAP_DSS_COLOR_ARGB16:
1545 case OMAP_DSS_COLOR_ARGB32:
1546 case OMAP_DSS_COLOR_RGBA32:
1547 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
1548 return -EINVAL;
1549 case OMAP_DSS_COLOR_RGBX32:
1550 if (cpu_is_omap24xx())
1551 return -EINVAL;
1552 /* fall through */
1553 case OMAP_DSS_COLOR_RGB12U:
1554 case OMAP_DSS_COLOR_RGB16:
1555 case OMAP_DSS_COLOR_RGB24P:
1556 case OMAP_DSS_COLOR_RGB24U:
1557 break;
1558
1559 default:
1560 return -EINVAL;
1561 }
1562 } else { 1649 } else {
1563 /* video plane */ 1650 /* video plane */
1564 1651
@@ -1572,42 +1659,16 @@ static int _dispc_setup_plane(enum omap_plane plane,
1572 out_height > height * 8) 1659 out_height > height * 8)
1573 return -EINVAL; 1660 return -EINVAL;
1574 1661
1575 switch (color_mode) { 1662 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1576 case OMAP_DSS_COLOR_RGBX32: 1663 color_mode == OMAP_DSS_COLOR_UYVY)
1577 case OMAP_DSS_COLOR_RGB12U:
1578 if (cpu_is_omap24xx())
1579 return -EINVAL;
1580 /* fall through */
1581 case OMAP_DSS_COLOR_RGB16:
1582 case OMAP_DSS_COLOR_RGB24P:
1583 case OMAP_DSS_COLOR_RGB24U:
1584 break;
1585
1586 case OMAP_DSS_COLOR_ARGB16:
1587 case OMAP_DSS_COLOR_ARGB32:
1588 case OMAP_DSS_COLOR_RGBA32:
1589 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
1590 return -EINVAL;
1591 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
1592 plane == OMAP_DSS_VIDEO1)
1593 return -EINVAL;
1594 break;
1595
1596 case OMAP_DSS_COLOR_YUV2:
1597 case OMAP_DSS_COLOR_UYVY:
1598 cconv = 1; 1664 cconv = 1;
1599 break;
1600
1601 default:
1602 return -EINVAL;
1603 }
1604 1665
1605 /* Must use 5-tap filter? */ 1666 /* Must use 5-tap filter? */
1606 five_taps = height > out_height * 2; 1667 five_taps = height > out_height * 2;
1607 1668
1608 if (!five_taps) { 1669 if (!five_taps) {
1609 fclk = calc_fclk(width, height, 1670 fclk = calc_fclk(channel, width, height, out_width,
1610 out_width, out_height); 1671 out_height);
1611 1672
1612 /* Try 5-tap filter if 3-tap fclk is too high */ 1673 /* Try 5-tap filter if 3-tap fclk is too high */
1613 if (cpu_is_omap34xx() && height > out_height && 1674 if (cpu_is_omap34xx() && height > out_height &&
@@ -1621,7 +1682,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1621 } 1682 }
1622 1683
1623 if (five_taps) 1684 if (five_taps)
1624 fclk = calc_fclk_five_taps(width, height, 1685 fclk = calc_fclk_five_taps(channel, width, height,
1625 out_width, out_height, color_mode); 1686 out_width, out_height, color_mode);
1626 1687
1627 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1688 DSSDBG("required fclk rate = %lu Hz\n", fclk);
@@ -1693,8 +1754,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1693 1754
1694 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode); 1755 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
1695 1756
1696 if (plane != OMAP_DSS_VIDEO1) 1757 _dispc_set_pre_mult_alpha(plane, pre_mult_alpha);
1697 _dispc_setup_global_alpha(plane, global_alpha); 1758 _dispc_setup_global_alpha(plane, global_alpha);
1698 1759
1699 return 0; 1760 return 0;
1700} 1761}
@@ -1710,36 +1771,44 @@ static void dispc_disable_isr(void *data, u32 mask)
1710 complete(compl); 1771 complete(compl);
1711} 1772}
1712 1773
1713static void _enable_lcd_out(bool enable) 1774static void _enable_lcd_out(enum omap_channel channel, bool enable)
1714{ 1775{
1715 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1776 if (channel == OMAP_DSS_CHANNEL_LCD2)
1777 REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
1778 else
1779 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1716} 1780}
1717 1781
1718static void dispc_enable_lcd_out(bool enable) 1782static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
1719{ 1783{
1720 struct completion frame_done_completion; 1784 struct completion frame_done_completion;
1721 bool is_on; 1785 bool is_on;
1722 int r; 1786 int r;
1787 u32 irq;
1723 1788
1724 enable_clocks(1); 1789 enable_clocks(1);
1725 1790
1726 /* When we disable LCD output, we need to wait until frame is done. 1791 /* When we disable LCD output, we need to wait until frame is done.
1727 * Otherwise the DSS is still working, and turning off the clocks 1792 * Otherwise the DSS is still working, and turning off the clocks
1728 * prevents DSS from going to OFF mode */ 1793 * prevents DSS from going to OFF mode */
1729 is_on = REG_GET(DISPC_CONTROL, 0, 0); 1794 is_on = channel == OMAP_DSS_CHANNEL_LCD2 ?
1795 REG_GET(DISPC_CONTROL2, 0, 0) :
1796 REG_GET(DISPC_CONTROL, 0, 0);
1797
1798 irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 :
1799 DISPC_IRQ_FRAMEDONE;
1730 1800
1731 if (!enable && is_on) { 1801 if (!enable && is_on) {
1732 init_completion(&frame_done_completion); 1802 init_completion(&frame_done_completion);
1733 1803
1734 r = omap_dispc_register_isr(dispc_disable_isr, 1804 r = omap_dispc_register_isr(dispc_disable_isr,
1735 &frame_done_completion, 1805 &frame_done_completion, irq);
1736 DISPC_IRQ_FRAMEDONE);
1737 1806
1738 if (r) 1807 if (r)
1739 DSSERR("failed to register FRAMEDONE isr\n"); 1808 DSSERR("failed to register FRAMEDONE isr\n");
1740 } 1809 }
1741 1810
1742 _enable_lcd_out(enable); 1811 _enable_lcd_out(channel, enable);
1743 1812
1744 if (!enable && is_on) { 1813 if (!enable && is_on) {
1745 if (!wait_for_completion_timeout(&frame_done_completion, 1814 if (!wait_for_completion_timeout(&frame_done_completion,
@@ -1747,8 +1816,7 @@ static void dispc_enable_lcd_out(bool enable)
1747 DSSERR("timeout waiting for FRAME DONE\n"); 1816 DSSERR("timeout waiting for FRAME DONE\n");
1748 1817
1749 r = omap_dispc_unregister_isr(dispc_disable_isr, 1818 r = omap_dispc_unregister_isr(dispc_disable_isr,
1750 &frame_done_completion, 1819 &frame_done_completion, irq);
1751 DISPC_IRQ_FRAMEDONE);
1752 1820
1753 if (r) 1821 if (r)
1754 DSSERR("failed to unregister FRAMEDONE isr\n"); 1822 DSSERR("failed to unregister FRAMEDONE isr\n");
@@ -1818,6 +1886,8 @@ static void dispc_enable_digit_out(bool enable)
1818 unsigned long flags; 1886 unsigned long flags;
1819 spin_lock_irqsave(&dispc.irq_lock, flags); 1887 spin_lock_irqsave(&dispc.irq_lock, flags);
1820 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 1888 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
1889 if (dss_has_feature(FEAT_MGR_LCD2))
1890 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
1821 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 1891 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
1822 _omap_dispc_set_irqs(); 1892 _omap_dispc_set_irqs();
1823 spin_unlock_irqrestore(&dispc.irq_lock, flags); 1893 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -1832,14 +1902,17 @@ bool dispc_is_channel_enabled(enum omap_channel channel)
1832 return !!REG_GET(DISPC_CONTROL, 0, 0); 1902 return !!REG_GET(DISPC_CONTROL, 0, 0);
1833 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 1903 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1834 return !!REG_GET(DISPC_CONTROL, 1, 1); 1904 return !!REG_GET(DISPC_CONTROL, 1, 1);
1905 else if (channel == OMAP_DSS_CHANNEL_LCD2)
1906 return !!REG_GET(DISPC_CONTROL2, 0, 0);
1835 else 1907 else
1836 BUG(); 1908 BUG();
1837} 1909}
1838 1910
1839void dispc_enable_channel(enum omap_channel channel, bool enable) 1911void dispc_enable_channel(enum omap_channel channel, bool enable)
1840{ 1912{
1841 if (channel == OMAP_DSS_CHANNEL_LCD) 1913 if (channel == OMAP_DSS_CHANNEL_LCD ||
1842 dispc_enable_lcd_out(enable); 1914 channel == OMAP_DSS_CHANNEL_LCD2)
1915 dispc_enable_lcd_out(channel, enable);
1843 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 1916 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1844 dispc_enable_digit_out(enable); 1917 dispc_enable_digit_out(enable);
1845 else 1918 else
@@ -1848,6 +1921,9 @@ void dispc_enable_channel(enum omap_channel channel, bool enable)
1848 1921
1849void dispc_lcd_enable_signal_polarity(bool act_high) 1922void dispc_lcd_enable_signal_polarity(bool act_high)
1850{ 1923{
1924 if (!dss_has_feature(FEAT_LCDENABLEPOL))
1925 return;
1926
1851 enable_clocks(1); 1927 enable_clocks(1);
1852 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); 1928 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
1853 enable_clocks(0); 1929 enable_clocks(0);
@@ -1855,6 +1931,9 @@ void dispc_lcd_enable_signal_polarity(bool act_high)
1855 1931
1856void dispc_lcd_enable_signal(bool enable) 1932void dispc_lcd_enable_signal(bool enable)
1857{ 1933{
1934 if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
1935 return;
1936
1858 enable_clocks(1); 1937 enable_clocks(1);
1859 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); 1938 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
1860 enable_clocks(0); 1939 enable_clocks(0);
@@ -1862,20 +1941,27 @@ void dispc_lcd_enable_signal(bool enable)
1862 1941
1863void dispc_pck_free_enable(bool enable) 1942void dispc_pck_free_enable(bool enable)
1864{ 1943{
1944 if (!dss_has_feature(FEAT_PCKFREEENABLE))
1945 return;
1946
1865 enable_clocks(1); 1947 enable_clocks(1);
1866 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 1948 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
1867 enable_clocks(0); 1949 enable_clocks(0);
1868} 1950}
1869 1951
1870void dispc_enable_fifohandcheck(bool enable) 1952void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
1871{ 1953{
1872 enable_clocks(1); 1954 enable_clocks(1);
1873 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); 1955 if (channel == OMAP_DSS_CHANNEL_LCD2)
1956 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
1957 else
1958 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
1874 enable_clocks(0); 1959 enable_clocks(0);
1875} 1960}
1876 1961
1877 1962
1878void dispc_set_lcd_display_type(enum omap_lcd_display_type type) 1963void dispc_set_lcd_display_type(enum omap_channel channel,
1964 enum omap_lcd_display_type type)
1879{ 1965{
1880 int mode; 1966 int mode;
1881 1967
@@ -1894,7 +1980,10 @@ void dispc_set_lcd_display_type(enum omap_lcd_display_type type)
1894 } 1980 }
1895 1981
1896 enable_clocks(1); 1982 enable_clocks(1);
1897 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); 1983 if (channel == OMAP_DSS_CHANNEL_LCD2)
1984 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
1985 else
1986 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
1898 enable_clocks(0); 1987 enable_clocks(0);
1899} 1988}
1900 1989
@@ -1908,25 +1997,21 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
1908 1997
1909void dispc_set_default_color(enum omap_channel channel, u32 color) 1998void dispc_set_default_color(enum omap_channel channel, u32 color)
1910{ 1999{
1911 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1912 DISPC_DEFAULT_COLOR1 };
1913
1914 enable_clocks(1); 2000 enable_clocks(1);
1915 dispc_write_reg(def_reg[channel], color); 2001 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
1916 enable_clocks(0); 2002 enable_clocks(0);
1917} 2003}
1918 2004
1919u32 dispc_get_default_color(enum omap_channel channel) 2005u32 dispc_get_default_color(enum omap_channel channel)
1920{ 2006{
1921 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1922 DISPC_DEFAULT_COLOR1 };
1923 u32 l; 2007 u32 l;
1924 2008
1925 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && 2009 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
1926 channel != OMAP_DSS_CHANNEL_LCD); 2010 channel != OMAP_DSS_CHANNEL_LCD &&
2011 channel != OMAP_DSS_CHANNEL_LCD2);
1927 2012
1928 enable_clocks(1); 2013 enable_clocks(1);
1929 l = dispc_read_reg(def_reg[channel]); 2014 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
1930 enable_clocks(0); 2015 enable_clocks(0);
1931 2016
1932 return l; 2017 return l;
@@ -1936,16 +2021,15 @@ void dispc_set_trans_key(enum omap_channel ch,
1936 enum omap_dss_trans_key_type type, 2021 enum omap_dss_trans_key_type type,
1937 u32 trans_key) 2022 u32 trans_key)
1938{ 2023{
1939 const struct dispc_reg tr_reg[] = {
1940 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1941
1942 enable_clocks(1); 2024 enable_clocks(1);
1943 if (ch == OMAP_DSS_CHANNEL_LCD) 2025 if (ch == OMAP_DSS_CHANNEL_LCD)
1944 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); 2026 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
1945 else /* OMAP_DSS_CHANNEL_DIGIT */ 2027 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1946 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); 2028 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
2029 else /* OMAP_DSS_CHANNEL_LCD2 */
2030 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
1947 2031
1948 dispc_write_reg(tr_reg[ch], trans_key); 2032 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
1949 enable_clocks(0); 2033 enable_clocks(0);
1950} 2034}
1951 2035
@@ -1953,21 +2037,20 @@ void dispc_get_trans_key(enum omap_channel ch,
1953 enum omap_dss_trans_key_type *type, 2037 enum omap_dss_trans_key_type *type,
1954 u32 *trans_key) 2038 u32 *trans_key)
1955{ 2039{
1956 const struct dispc_reg tr_reg[] = {
1957 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1958
1959 enable_clocks(1); 2040 enable_clocks(1);
1960 if (type) { 2041 if (type) {
1961 if (ch == OMAP_DSS_CHANNEL_LCD) 2042 if (ch == OMAP_DSS_CHANNEL_LCD)
1962 *type = REG_GET(DISPC_CONFIG, 11, 11); 2043 *type = REG_GET(DISPC_CONFIG, 11, 11);
1963 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2044 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1964 *type = REG_GET(DISPC_CONFIG, 13, 13); 2045 *type = REG_GET(DISPC_CONFIG, 13, 13);
2046 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2047 *type = REG_GET(DISPC_CONFIG2, 11, 11);
1965 else 2048 else
1966 BUG(); 2049 BUG();
1967 } 2050 }
1968 2051
1969 if (trans_key) 2052 if (trans_key)
1970 *trans_key = dispc_read_reg(tr_reg[ch]); 2053 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
1971 enable_clocks(0); 2054 enable_clocks(0);
1972} 2055}
1973 2056
@@ -1976,8 +2059,10 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
1976 enable_clocks(1); 2059 enable_clocks(1);
1977 if (ch == OMAP_DSS_CHANNEL_LCD) 2060 if (ch == OMAP_DSS_CHANNEL_LCD)
1978 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2061 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
1979 else /* OMAP_DSS_CHANNEL_DIGIT */ 2062 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1980 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); 2063 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2064 else /* OMAP_DSS_CHANNEL_LCD2 */
2065 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
1981 enable_clocks(0); 2066 enable_clocks(0);
1982} 2067}
1983void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2068void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
@@ -1988,8 +2073,10 @@ void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
1988 enable_clocks(1); 2073 enable_clocks(1);
1989 if (ch == OMAP_DSS_CHANNEL_LCD) 2074 if (ch == OMAP_DSS_CHANNEL_LCD)
1990 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2075 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
1991 else /* OMAP_DSS_CHANNEL_DIGIT */ 2076 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1992 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2077 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
2078 else /* OMAP_DSS_CHANNEL_LCD2 */
2079 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
1993 enable_clocks(0); 2080 enable_clocks(0);
1994} 2081}
1995bool dispc_alpha_blending_enabled(enum omap_channel ch) 2082bool dispc_alpha_blending_enabled(enum omap_channel ch)
@@ -2003,13 +2090,14 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
2003 if (ch == OMAP_DSS_CHANNEL_LCD) 2090 if (ch == OMAP_DSS_CHANNEL_LCD)
2004 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2091 enabled = REG_GET(DISPC_CONFIG, 18, 18);
2005 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2092 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2006 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2093 enabled = REG_GET(DISPC_CONFIG, 19, 19);
2094 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2095 enabled = REG_GET(DISPC_CONFIG2, 18, 18);
2007 else 2096 else
2008 BUG(); 2097 BUG();
2009 enable_clocks(0); 2098 enable_clocks(0);
2010 2099
2011 return enabled; 2100 return enabled;
2012
2013} 2101}
2014 2102
2015 2103
@@ -2022,6 +2110,8 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2022 enabled = REG_GET(DISPC_CONFIG, 10, 10); 2110 enabled = REG_GET(DISPC_CONFIG, 10, 10);
2023 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2111 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2024 enabled = REG_GET(DISPC_CONFIG, 12, 12); 2112 enabled = REG_GET(DISPC_CONFIG, 12, 12);
2113 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2114 enabled = REG_GET(DISPC_CONFIG2, 10, 10);
2025 else 2115 else
2026 BUG(); 2116 BUG();
2027 enable_clocks(0); 2117 enable_clocks(0);
@@ -2030,7 +2120,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2030} 2120}
2031 2121
2032 2122
2033void dispc_set_tft_data_lines(u8 data_lines) 2123void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2034{ 2124{
2035 int code; 2125 int code;
2036 2126
@@ -2053,11 +2143,15 @@ void dispc_set_tft_data_lines(u8 data_lines)
2053 } 2143 }
2054 2144
2055 enable_clocks(1); 2145 enable_clocks(1);
2056 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2146 if (channel == OMAP_DSS_CHANNEL_LCD2)
2147 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2148 else
2149 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2057 enable_clocks(0); 2150 enable_clocks(0);
2058} 2151}
2059 2152
2060void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) 2153void dispc_set_parallel_interface_mode(enum omap_channel channel,
2154 enum omap_parallel_interface_mode mode)
2061{ 2155{
2062 u32 l; 2156 u32 l;
2063 int stallmode; 2157 int stallmode;
@@ -2087,13 +2181,17 @@ void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
2087 2181
2088 enable_clocks(1); 2182 enable_clocks(1);
2089 2183
2090 l = dispc_read_reg(DISPC_CONTROL); 2184 if (channel == OMAP_DSS_CHANNEL_LCD2) {
2091 2185 l = dispc_read_reg(DISPC_CONTROL2);
2092 l = FLD_MOD(l, stallmode, 11, 11); 2186 l = FLD_MOD(l, stallmode, 11, 11);
2093 l = FLD_MOD(l, gpout0, 15, 15); 2187 dispc_write_reg(DISPC_CONTROL2, l);
2094 l = FLD_MOD(l, gpout1, 16, 16); 2188 } else {
2095 2189 l = dispc_read_reg(DISPC_CONTROL);
2096 dispc_write_reg(DISPC_CONTROL, l); 2190 l = FLD_MOD(l, stallmode, 11, 11);
2191 l = FLD_MOD(l, gpout0, 15, 15);
2192 l = FLD_MOD(l, gpout1, 16, 16);
2193 dispc_write_reg(DISPC_CONTROL, l);
2194 }
2097 2195
2098 enable_clocks(0); 2196 enable_clocks(0);
2099} 2197}
@@ -2129,8 +2227,8 @@ bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
2129 timings->vfp, timings->vbp); 2227 timings->vfp, timings->vbp);
2130} 2228}
2131 2229
2132static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, 2230static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
2133 int vsw, int vfp, int vbp) 2231 int hfp, int hbp, int vsw, int vfp, int vbp)
2134{ 2232{
2135 u32 timing_h, timing_v; 2233 u32 timing_h, timing_v;
2136 2234
@@ -2149,13 +2247,14 @@ static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
2149 } 2247 }
2150 2248
2151 enable_clocks(1); 2249 enable_clocks(1);
2152 dispc_write_reg(DISPC_TIMING_H, timing_h); 2250 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2153 dispc_write_reg(DISPC_TIMING_V, timing_v); 2251 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2154 enable_clocks(0); 2252 enable_clocks(0);
2155} 2253}
2156 2254
2157/* change name to mode? */ 2255/* change name to mode? */
2158void dispc_set_lcd_timings(struct omap_video_timings *timings) 2256void dispc_set_lcd_timings(enum omap_channel channel,
2257 struct omap_video_timings *timings)
2159{ 2258{
2160 unsigned xtot, ytot; 2259 unsigned xtot, ytot;
2161 unsigned long ht, vt; 2260 unsigned long ht, vt;
@@ -2165,10 +2264,11 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2165 timings->vfp, timings->vbp)) 2264 timings->vfp, timings->vbp))
2166 BUG(); 2265 BUG();
2167 2266
2168 _dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp, 2267 _dispc_set_lcd_timings(channel, timings->hsw, timings->hfp,
2169 timings->vsw, timings->vfp, timings->vbp); 2268 timings->hbp, timings->vsw, timings->vfp,
2269 timings->vbp);
2170 2270
2171 dispc_set_lcd_size(timings->x_res, timings->y_res); 2271 dispc_set_lcd_size(channel, timings->x_res, timings->y_res);
2172 2272
2173 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; 2273 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
2174 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; 2274 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
@@ -2176,7 +2276,8 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2176 ht = (timings->pixel_clock * 1000) / xtot; 2276 ht = (timings->pixel_clock * 1000) / xtot;
2177 vt = (timings->pixel_clock * 1000) / xtot / ytot; 2277 vt = (timings->pixel_clock * 1000) / xtot / ytot;
2178 2278
2179 DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res); 2279 DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res,
2280 timings->y_res);
2180 DSSDBG("pck %u\n", timings->pixel_clock); 2281 DSSDBG("pck %u\n", timings->pixel_clock);
2181 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2282 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2182 timings->hsw, timings->hfp, timings->hbp, 2283 timings->hsw, timings->hfp, timings->hbp,
@@ -2185,21 +2286,23 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2185 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2286 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2186} 2287}
2187 2288
2188static void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div) 2289static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2290 u16 pck_div)
2189{ 2291{
2190 BUG_ON(lck_div < 1); 2292 BUG_ON(lck_div < 1);
2191 BUG_ON(pck_div < 2); 2293 BUG_ON(pck_div < 2);
2192 2294
2193 enable_clocks(1); 2295 enable_clocks(1);
2194 dispc_write_reg(DISPC_DIVISOR, 2296 dispc_write_reg(DISPC_DIVISOR(channel),
2195 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2196 enable_clocks(0); 2298 enable_clocks(0);
2197} 2299}
2198 2300
2199static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) 2301static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div)
2200{ 2303{
2201 u32 l; 2304 u32 l;
2202 l = dispc_read_reg(DISPC_DIVISOR); 2305 l = dispc_read_reg(DISPC_DIVISOR(channel));
2203 *lck_div = FLD_GET(l, 23, 16); 2306 *lck_div = FLD_GET(l, 23, 16);
2204 *pck_div = FLD_GET(l, 7, 0); 2307 *pck_div = FLD_GET(l, 7, 0);
2205} 2308}
@@ -2219,13 +2322,13 @@ unsigned long dispc_fclk_rate(void)
2219 return r; 2322 return r;
2220} 2323}
2221 2324
2222unsigned long dispc_lclk_rate(void) 2325unsigned long dispc_lclk_rate(enum omap_channel channel)
2223{ 2326{
2224 int lcd; 2327 int lcd;
2225 unsigned long r; 2328 unsigned long r;
2226 u32 l; 2329 u32 l;
2227 2330
2228 l = dispc_read_reg(DISPC_DIVISOR); 2331 l = dispc_read_reg(DISPC_DIVISOR(channel));
2229 2332
2230 lcd = FLD_GET(l, 23, 16); 2333 lcd = FLD_GET(l, 23, 16);
2231 2334
@@ -2234,13 +2337,13 @@ unsigned long dispc_lclk_rate(void)
2234 return r / lcd; 2337 return r / lcd;
2235} 2338}
2236 2339
2237unsigned long dispc_pclk_rate(void) 2340unsigned long dispc_pclk_rate(enum omap_channel channel)
2238{ 2341{
2239 int lcd, pcd; 2342 int lcd, pcd;
2240 unsigned long r; 2343 unsigned long r;
2241 u32 l; 2344 u32 l;
2242 2345
2243 l = dispc_read_reg(DISPC_DIVISOR); 2346 l = dispc_read_reg(DISPC_DIVISOR(channel));
2244 2347
2245 lcd = FLD_GET(l, 23, 16); 2348 lcd = FLD_GET(l, 23, 16);
2246 pcd = FLD_GET(l, 7, 0); 2349 pcd = FLD_GET(l, 7, 0);
@@ -2256,8 +2359,6 @@ void dispc_dump_clocks(struct seq_file *s)
2256 2359
2257 enable_clocks(1); 2360 enable_clocks(1);
2258 2361
2259 dispc_get_lcd_divisor(&lcd, &pcd);
2260
2261 seq_printf(s, "- DISPC -\n"); 2362 seq_printf(s, "- DISPC -\n");
2262 2363
2263 seq_printf(s, "dispc fclk source = %s\n", 2364 seq_printf(s, "dispc fclk source = %s\n",
@@ -2265,9 +2366,25 @@ void dispc_dump_clocks(struct seq_file *s)
2265 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2366 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2266 2367
2267 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2268 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", dispc_lclk_rate(), lcd);
2269 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", dispc_pclk_rate(), pcd);
2270 2369
2370 seq_printf(s, "- LCD1 -\n");
2371
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2375 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2376 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2377 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2378 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n");
2380
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2384 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
2385 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2386 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2387 }
2271 enable_clocks(0); 2388 enable_clocks(0);
2272} 2389}
2273 2390
@@ -2309,6 +2426,12 @@ void dispc_dump_irqs(struct seq_file *s)
2309 PIS(SYNC_LOST); 2426 PIS(SYNC_LOST);
2310 PIS(SYNC_LOST_DIGIT); 2427 PIS(SYNC_LOST_DIGIT);
2311 PIS(WAKEUP); 2428 PIS(WAKEUP);
2429 if (dss_has_feature(FEAT_MGR_LCD2)) {
2430 PIS(FRAMEDONE2);
2431 PIS(VSYNC2);
2432 PIS(ACBIAS_COUNT_STAT2);
2433 PIS(SYNC_LOST2);
2434 }
2312#undef PIS 2435#undef PIS
2313} 2436}
2314#endif 2437#endif
@@ -2327,19 +2450,30 @@ void dispc_dump_regs(struct seq_file *s)
2327 DUMPREG(DISPC_CONTROL); 2450 DUMPREG(DISPC_CONTROL);
2328 DUMPREG(DISPC_CONFIG); 2451 DUMPREG(DISPC_CONFIG);
2329 DUMPREG(DISPC_CAPABLE); 2452 DUMPREG(DISPC_CAPABLE);
2330 DUMPREG(DISPC_DEFAULT_COLOR0); 2453 DUMPREG(DISPC_DEFAULT_COLOR(0));
2331 DUMPREG(DISPC_DEFAULT_COLOR1); 2454 DUMPREG(DISPC_DEFAULT_COLOR(1));
2332 DUMPREG(DISPC_TRANS_COLOR0); 2455 DUMPREG(DISPC_TRANS_COLOR(0));
2333 DUMPREG(DISPC_TRANS_COLOR1); 2456 DUMPREG(DISPC_TRANS_COLOR(1));
2334 DUMPREG(DISPC_LINE_STATUS); 2457 DUMPREG(DISPC_LINE_STATUS);
2335 DUMPREG(DISPC_LINE_NUMBER); 2458 DUMPREG(DISPC_LINE_NUMBER);
2336 DUMPREG(DISPC_TIMING_H); 2459 DUMPREG(DISPC_TIMING_H(0));
2337 DUMPREG(DISPC_TIMING_V); 2460 DUMPREG(DISPC_TIMING_V(0));
2338 DUMPREG(DISPC_POL_FREQ); 2461 DUMPREG(DISPC_POL_FREQ(0));
2339 DUMPREG(DISPC_DIVISOR); 2462 DUMPREG(DISPC_DIVISOR(0));
2340 DUMPREG(DISPC_GLOBAL_ALPHA); 2463 DUMPREG(DISPC_GLOBAL_ALPHA);
2341 DUMPREG(DISPC_SIZE_DIG); 2464 DUMPREG(DISPC_SIZE_DIG);
2342 DUMPREG(DISPC_SIZE_LCD); 2465 DUMPREG(DISPC_SIZE_LCD(0));
2466 if (dss_has_feature(FEAT_MGR_LCD2)) {
2467 DUMPREG(DISPC_CONTROL2);
2468 DUMPREG(DISPC_CONFIG2);
2469 DUMPREG(DISPC_DEFAULT_COLOR(2));
2470 DUMPREG(DISPC_TRANS_COLOR(2));
2471 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2));
2475 DUMPREG(DISPC_SIZE_LCD(2));
2476 }
2343 2477
2344 DUMPREG(DISPC_GFX_BA0); 2478 DUMPREG(DISPC_GFX_BA0);
2345 DUMPREG(DISPC_GFX_BA1); 2479 DUMPREG(DISPC_GFX_BA1);
@@ -2353,13 +2487,22 @@ void dispc_dump_regs(struct seq_file *s)
2353 DUMPREG(DISPC_GFX_WINDOW_SKIP); 2487 DUMPREG(DISPC_GFX_WINDOW_SKIP);
2354 DUMPREG(DISPC_GFX_TABLE_BA); 2488 DUMPREG(DISPC_GFX_TABLE_BA);
2355 2489
2356 DUMPREG(DISPC_DATA_CYCLE1); 2490 DUMPREG(DISPC_DATA_CYCLE1(0));
2357 DUMPREG(DISPC_DATA_CYCLE2); 2491 DUMPREG(DISPC_DATA_CYCLE2(0));
2358 DUMPREG(DISPC_DATA_CYCLE3); 2492 DUMPREG(DISPC_DATA_CYCLE3(0));
2359 2493
2360 DUMPREG(DISPC_CPR_COEF_R); 2494 DUMPREG(DISPC_CPR_COEF_R(0));
2361 DUMPREG(DISPC_CPR_COEF_G); 2495 DUMPREG(DISPC_CPR_COEF_G(0));
2362 DUMPREG(DISPC_CPR_COEF_B); 2496 DUMPREG(DISPC_CPR_COEF_B(0));
2497 if (dss_has_feature(FEAT_MGR_LCD2)) {
2498 DUMPREG(DISPC_DATA_CYCLE1(2));
2499 DUMPREG(DISPC_DATA_CYCLE2(2));
2500 DUMPREG(DISPC_DATA_CYCLE3(2));
2501
2502 DUMPREG(DISPC_CPR_COEF_R(2));
2503 DUMPREG(DISPC_CPR_COEF_G(2));
2504 DUMPREG(DISPC_CPR_COEF_B(2));
2505 }
2363 2506
2364 DUMPREG(DISPC_GFX_PRELOAD); 2507 DUMPREG(DISPC_GFX_PRELOAD);
2365 2508
@@ -2458,8 +2601,8 @@ void dispc_dump_regs(struct seq_file *s)
2458#undef DUMPREG 2601#undef DUMPREG
2459} 2602}
2460 2603
2461static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc, 2604static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
2462 bool ihs, bool ivs, u8 acbi, u8 acb) 2605 bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, u8 acb)
2463{ 2606{
2464 u32 l = 0; 2607 u32 l = 0;
2465 2608
@@ -2476,13 +2619,14 @@ static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
2476 l |= FLD_VAL(acb, 7, 0); 2619 l |= FLD_VAL(acb, 7, 0);
2477 2620
2478 enable_clocks(1); 2621 enable_clocks(1);
2479 dispc_write_reg(DISPC_POL_FREQ, l); 2622 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2480 enable_clocks(0); 2623 enable_clocks(0);
2481} 2624}
2482 2625
2483void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb) 2626void dispc_set_pol_freq(enum omap_channel channel,
2627 enum omap_panel_config config, u8 acbi, u8 acb)
2484{ 2628{
2485 _dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0, 2629 _dispc_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
2486 (config & OMAP_DSS_LCD_RF) != 0, 2630 (config & OMAP_DSS_LCD_RF) != 0,
2487 (config & OMAP_DSS_LCD_IEO) != 0, 2631 (config & OMAP_DSS_LCD_IEO) != 0,
2488 (config & OMAP_DSS_LCD_IPC) != 0, 2632 (config & OMAP_DSS_LCD_IPC) != 0,
@@ -2551,24 +2695,26 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
2551 return 0; 2695 return 0;
2552} 2696}
2553 2697
2554int dispc_set_clock_div(struct dispc_clock_info *cinfo) 2698int dispc_set_clock_div(enum omap_channel channel,
2699 struct dispc_clock_info *cinfo)
2555{ 2700{
2556 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 2701 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
2557 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 2702 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
2558 2703
2559 dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div); 2704 dispc_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
2560 2705
2561 return 0; 2706 return 0;
2562} 2707}
2563 2708
2564int dispc_get_clock_div(struct dispc_clock_info *cinfo) 2709int dispc_get_clock_div(enum omap_channel channel,
2710 struct dispc_clock_info *cinfo)
2565{ 2711{
2566 unsigned long fck; 2712 unsigned long fck;
2567 2713
2568 fck = dispc_fclk_rate(); 2714 fck = dispc_fclk_rate();
2569 2715
2570 cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16); 2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16);
2571 cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0); 2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0);
2572 2718
2573 cinfo->lck = fck / cinfo->lck_div; 2719 cinfo->lck = fck / cinfo->lck_div;
2574 cinfo->pck = cinfo->lck / cinfo->pck_div; 2720 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2708,6 +2854,8 @@ static void print_irq_status(u32 status)
2708 PIS(VID2_FIFO_UNDERFLOW); 2854 PIS(VID2_FIFO_UNDERFLOW);
2709 PIS(SYNC_LOST); 2855 PIS(SYNC_LOST);
2710 PIS(SYNC_LOST_DIGIT); 2856 PIS(SYNC_LOST_DIGIT);
2857 if (dss_has_feature(FEAT_MGR_LCD2))
2858 PIS(SYNC_LOST2);
2711#undef PIS 2859#undef PIS
2712 2860
2713 printk("\n"); 2861 printk("\n");
@@ -2926,6 +3074,45 @@ static void dispc_error_worker(struct work_struct *work)
2926 } 3074 }
2927 } 3075 }
2928 3076
3077 if (errors & DISPC_IRQ_SYNC_LOST2) {
3078 struct omap_overlay_manager *manager = NULL;
3079 bool enable = false;
3080
3081 DSSERR("SYNC_LOST for LCD2, disabling LCD2\n");
3082
3083 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3084 struct omap_overlay_manager *mgr;
3085 mgr = omap_dss_get_overlay_manager(i);
3086
3087 if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
3088 manager = mgr;
3089 enable = mgr->device->state ==
3090 OMAP_DSS_DISPLAY_ACTIVE;
3091 mgr->device->driver->disable(mgr->device);
3092 break;
3093 }
3094 }
3095
3096 if (manager) {
3097 struct omap_dss_device *dssdev = manager->device;
3098 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3099 struct omap_overlay *ovl;
3100 ovl = omap_dss_get_overlay(i);
3101
3102 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3103 continue;
3104
3105 if (ovl->id != 0 && ovl->manager == manager)
3106 dispc_enable_plane(ovl->id, 0);
3107 }
3108
3109 dispc_go(manager->id);
3110 mdelay(50);
3111 if (enable)
3112 dssdev->driver->enable(dssdev);
3113 }
3114 }
3115
2929 if (errors & DISPC_IRQ_OCP_ERR) { 3116 if (errors & DISPC_IRQ_OCP_ERR) {
2930 DSSERR("OCP_ERR\n"); 3117 DSSERR("OCP_ERR\n");
2931 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3118 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
@@ -3033,6 +3220,8 @@ static void _omap_dispc_initialize_irq(void)
3033 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); 3220 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
3034 3221
3035 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3222 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3223 if (dss_has_feature(FEAT_MGR_LCD2))
3224 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3036 3225
3037 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, 3226 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3038 * so clear it */ 3227 * so clear it */
@@ -3065,7 +3254,8 @@ static void _omap_dispc_initial_config(void)
3065 dispc_write_reg(DISPC_SYSCONFIG, l); 3254 dispc_write_reg(DISPC_SYSCONFIG, l);
3066 3255
3067 /* FUNCGATED */ 3256 /* FUNCGATED */
3068 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3257 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
3069 3259
3070 /* L3 firewall setting: enable access to OCM RAM */ 3260 /* L3 firewall setting: enable access to OCM RAM */
3071 /* XXX this should be somewhere in plat-omap */ 3261 /* XXX this should be somewhere in plat-omap */
@@ -3139,17 +3329,18 @@ int dispc_setup_plane(enum omap_plane plane,
3139 enum omap_color_mode color_mode, 3329 enum omap_color_mode color_mode,
3140 bool ilace, 3330 bool ilace,
3141 enum omap_dss_rotation_type rotation_type, 3331 enum omap_dss_rotation_type rotation_type,
3142 u8 rotation, bool mirror, u8 global_alpha) 3332 u8 rotation, bool mirror, u8 global_alpha,
3333 u8 pre_mult_alpha, enum omap_channel channel)
3143{ 3334{
3144 int r = 0; 3335 int r = 0;
3145 3336
3146 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 3337 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
3147 "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n", 3338 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
3148 plane, paddr, screen_width, pos_x, pos_y, 3339 plane, paddr, screen_width, pos_x, pos_y,
3149 width, height, 3340 width, height,
3150 out_width, out_height, 3341 out_width, out_height,
3151 ilace, color_mode, 3342 ilace, color_mode,
3152 rotation, mirror); 3343 rotation, mirror, channel);
3153 3344
3154 enable_clocks(1); 3345 enable_clocks(1);
3155 3346
@@ -3161,7 +3352,8 @@ int dispc_setup_plane(enum omap_plane plane,
3161 color_mode, ilace, 3352 color_mode, ilace,
3162 rotation_type, 3353 rotation_type,
3163 rotation, mirror, 3354 rotation, mirror,
3164 global_alpha); 3355 global_alpha,
3356 pre_mult_alpha, channel);
3165 3357
3166 enable_clocks(0); 3358 enable_clocks(0);
3167 3359
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 960e977a8bf0..75fb0a515430 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -40,8 +40,9 @@ static struct {
40} dpi; 40} dpi;
41 41
42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
43static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, 43static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
44 unsigned long *fck, int *lck_div, int *pck_div) 44 unsigned long pck_req, unsigned long *fck, int *lck_div,
45 int *pck_div)
45{ 46{
46 struct dsi_clock_info dsi_cinfo; 47 struct dsi_clock_info dsi_cinfo;
47 struct dispc_clock_info dispc_cinfo; 48 struct dispc_clock_info dispc_cinfo;
@@ -58,7 +59,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
58 59
59 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); 60 dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK);
60 61
61 r = dispc_set_clock_div(&dispc_cinfo); 62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
62 if (r) 63 if (r)
63 return r; 64 return r;
64 65
@@ -69,8 +70,9 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
69 return 0; 70 return 0;
70} 71}
71#else 72#else
72static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req, 73static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
73 unsigned long *fck, int *lck_div, int *pck_div) 74 unsigned long pck_req, unsigned long *fck, int *lck_div,
75 int *pck_div)
74{ 76{
75 struct dss_clock_info dss_cinfo; 77 struct dss_clock_info dss_cinfo;
76 struct dispc_clock_info dispc_cinfo; 78 struct dispc_clock_info dispc_cinfo;
@@ -84,7 +86,7 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
84 if (r) 86 if (r)
85 return r; 87 return r;
86 88
87 r = dispc_set_clock_div(&dispc_cinfo); 89 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
88 if (r) 90 if (r)
89 return r; 91 return r;
90 92
@@ -107,17 +109,17 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
107 109
108 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 110 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
109 111
110 dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, 112 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
111 dssdev->panel.acb); 113 dssdev->panel.acbi, dssdev->panel.acb);
112 114
113 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 115 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
114 116
115#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 117#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
116 r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000, 118 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck,
117 &fck, &lck_div, &pck_div); 119 &lck_div, &pck_div);
118#else 120#else
119 r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000, 121 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck,
120 &fck, &lck_div, &pck_div); 122 &lck_div, &pck_div);
121#endif 123#endif
122 if (r) 124 if (r)
123 goto err0; 125 goto err0;
@@ -132,7 +134,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
132 t->pixel_clock = pck; 134 t->pixel_clock = pck;
133 } 135 }
134 136
135 dispc_set_lcd_timings(t); 137 dispc_set_lcd_timings(dssdev->manager->id, t);
136 138
137err0: 139err0:
138 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); 140 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
@@ -145,10 +147,12 @@ static int dpi_basic_init(struct omap_dss_device *dssdev)
145 147
146 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 148 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
147 149
148 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); 150 dispc_set_parallel_interface_mode(dssdev->manager->id,
149 dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT : 151 OMAP_DSS_PARALLELMODE_BYPASS);
150 OMAP_DSS_LCD_DISPLAY_STN); 152 dispc_set_lcd_display_type(dssdev->manager->id, is_tft ?
151 dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines); 153 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
154 dispc_set_tft_data_lines(dssdev->manager->id,
155 dssdev->phy.dpi.data_lines);
152 156
153 return 0; 157 return 0;
154} 158}
@@ -234,7 +238,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
234 dssdev->panel.timings = *timings; 238 dssdev->panel.timings = *timings;
235 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 239 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
236 dpi_set_mode(dssdev); 240 dpi_set_mode(dssdev);
237 dispc_go(OMAP_DSS_CHANNEL_LCD); 241 dispc_go(dssdev->manager->id);
238 } 242 }
239} 243}
240EXPORT_SYMBOL(dpi_set_timings); 244EXPORT_SYMBOL(dpi_set_timings);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index aa4f7a5fae29..ddf3a0560822 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -792,7 +792,8 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
792} 792}
793 793
794/* calculate clock rates using dividers in cinfo */ 794/* calculate clock rates using dividers in cinfo */
795static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo) 795static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
796 struct dsi_clock_info *cinfo)
796{ 797{
797 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX) 798 if (cinfo->regn == 0 || cinfo->regn > REGN_MAX)
798 return -EINVAL; 799 return -EINVAL;
@@ -812,7 +813,7 @@ static int dsi_calc_clock_rates(struct dsi_clock_info *cinfo)
812 * with DSS2_FCK source also */ 813 * with DSS2_FCK source also */
813 cinfo->highfreq = 0; 814 cinfo->highfreq = 0;
814 } else { 815 } else {
815 cinfo->clkin = dispc_pclk_rate(); 816 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id);
816 817
817 if (cinfo->clkin < 32000000) 818 if (cinfo->clkin < 32000000)
818 cinfo->highfreq = 0; 819 cinfo->highfreq = 0;
@@ -1206,8 +1207,8 @@ void dsi_dump_clocks(struct seq_file *s)
1206 1207
1207 seq_printf(s, "VP_CLK\t\t%lu\n" 1208 seq_printf(s, "VP_CLK\t\t%lu\n"
1208 "VP_PCLK\t\t%lu\n", 1209 "VP_PCLK\t\t%lu\n",
1209 dispc_lclk_rate(), 1210 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD),
1210 dispc_pclk_rate()); 1211 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD));
1211 1212
1212 enable_clocks(0); 1213 enable_clocks(0);
1213} 1214}
@@ -2888,7 +2889,7 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
2888 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 2889 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
2889 dss_setup_partial_planes(dssdev, x, y, w, h, 2890 dss_setup_partial_planes(dssdev, x, y, w, h,
2890 enlarge_update_area); 2891 enlarge_update_area);
2891 dispc_set_lcd_size(*w, *h); 2892 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
2892 } 2893 }
2893 2894
2894 return 0; 2895 return 0;
@@ -2947,12 +2948,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
2947 return r; 2948 return r;
2948 } 2949 }
2949 2950
2950 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 2951 dispc_set_lcd_display_type(dssdev->manager->id,
2952 OMAP_DSS_LCD_DISPLAY_TFT);
2951 2953
2952 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI); 2954 dispc_set_parallel_interface_mode(dssdev->manager->id,
2953 dispc_enable_fifohandcheck(1); 2955 OMAP_DSS_PARALLELMODE_DSI);
2956 dispc_enable_fifohandcheck(dssdev->manager->id, 1);
2954 2957
2955 dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); 2958 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
2956 2959
2957 { 2960 {
2958 struct omap_video_timings timings = { 2961 struct omap_video_timings timings = {
@@ -2964,7 +2967,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
2964 .vbp = 0, 2967 .vbp = 0,
2965 }; 2968 };
2966 2969
2967 dispc_set_lcd_timings(&timings); 2970 dispc_set_lcd_timings(dssdev->manager->id, &timings);
2968 } 2971 }
2969 2972
2970 return 0; 2973 return 0;
@@ -2987,7 +2990,7 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
2987 cinfo.regm = dssdev->phy.dsi.div.regm; 2990 cinfo.regm = dssdev->phy.dsi.div.regm;
2988 cinfo.regm3 = dssdev->phy.dsi.div.regm3; 2991 cinfo.regm3 = dssdev->phy.dsi.div.regm3;
2989 cinfo.regm4 = dssdev->phy.dsi.div.regm4; 2992 cinfo.regm4 = dssdev->phy.dsi.div.regm4;
2990 r = dsi_calc_clock_rates(&cinfo); 2993 r = dsi_calc_clock_rates(dssdev, &cinfo);
2991 if (r) { 2994 if (r) {
2992 DSSERR("Failed to calc dsi clocks\n"); 2995 DSSERR("Failed to calc dsi clocks\n");
2993 return r; 2996 return r;
@@ -3019,7 +3022,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3019 return r; 3022 return r;
3020 } 3023 }
3021 3024
3022 r = dispc_set_clock_div(&dispc_cinfo); 3025 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
3023 if (r) { 3026 if (r) {
3024 DSSERR("Failed to set dispc clocks\n"); 3027 DSSERR("Failed to set dispc clocks\n");
3025 return r; 3028 return r;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5c7940d5f282..b394951120ac 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -333,9 +333,9 @@ void dispc_disable_sidle(void);
333void dispc_lcd_enable_signal_polarity(bool act_high); 333void dispc_lcd_enable_signal_polarity(bool act_high);
334void dispc_lcd_enable_signal(bool enable); 334void dispc_lcd_enable_signal(bool enable);
335void dispc_pck_free_enable(bool enable); 335void dispc_pck_free_enable(bool enable);
336void dispc_enable_fifohandcheck(bool enable); 336void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
337 337
338void dispc_set_lcd_size(u16 width, u16 height); 338void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
339void dispc_set_digit_size(u16 width, u16 height); 339void dispc_set_digit_size(u16 width, u16 height);
340u32 dispc_get_plane_fifo_size(enum omap_plane plane); 340u32 dispc_get_plane_fifo_size(enum omap_plane plane);
341void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); 341void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
@@ -359,7 +359,8 @@ int dispc_setup_plane(enum omap_plane plane,
359 bool ilace, 359 bool ilace,
360 enum omap_dss_rotation_type rotation_type, 360 enum omap_dss_rotation_type rotation_type,
361 u8 rotation, bool mirror, 361 u8 rotation, bool mirror,
362 u8 global_alpha); 362 u8 global_alpha, u8 pre_mult_alpha,
363 enum omap_channel channel);
363 364
364bool dispc_go_busy(enum omap_channel channel); 365bool dispc_go_busy(enum omap_channel channel);
365void dispc_go(enum omap_channel channel); 366void dispc_go(enum omap_channel channel);
@@ -368,9 +369,11 @@ bool dispc_is_channel_enabled(enum omap_channel channel);
368int dispc_enable_plane(enum omap_plane plane, bool enable); 369int dispc_enable_plane(enum omap_plane plane, bool enable);
369void dispc_enable_replication(enum omap_plane plane, bool enable); 370void dispc_enable_replication(enum omap_plane plane, bool enable);
370 371
371void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode); 372void dispc_set_parallel_interface_mode(enum omap_channel channel,
372void dispc_set_tft_data_lines(u8 data_lines); 373 enum omap_parallel_interface_mode mode);
373void dispc_set_lcd_display_type(enum omap_lcd_display_type type); 374void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
375void dispc_set_lcd_display_type(enum omap_channel channel,
376 enum omap_lcd_display_type type);
374void dispc_set_loadmode(enum omap_dss_load_mode mode); 377void dispc_set_loadmode(enum omap_dss_load_mode mode);
375 378
376void dispc_set_default_color(enum omap_channel channel, u32 color); 379void dispc_set_default_color(enum omap_channel channel, u32 color);
@@ -387,17 +390,21 @@ bool dispc_trans_key_enabled(enum omap_channel ch);
387bool dispc_alpha_blending_enabled(enum omap_channel ch); 390bool dispc_alpha_blending_enabled(enum omap_channel ch);
388 391
389bool dispc_lcd_timings_ok(struct omap_video_timings *timings); 392bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
390void dispc_set_lcd_timings(struct omap_video_timings *timings); 393void dispc_set_lcd_timings(enum omap_channel channel,
394 struct omap_video_timings *timings);
391unsigned long dispc_fclk_rate(void); 395unsigned long dispc_fclk_rate(void);
392unsigned long dispc_lclk_rate(void); 396unsigned long dispc_lclk_rate(enum omap_channel channel);
393unsigned long dispc_pclk_rate(void); 397unsigned long dispc_pclk_rate(enum omap_channel channel);
394void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb); 398void dispc_set_pol_freq(enum omap_channel channel,
399 enum omap_panel_config config, u8 acbi, u8 acb);
395void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 400void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
396 struct dispc_clock_info *cinfo); 401 struct dispc_clock_info *cinfo);
397int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 402int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
398 struct dispc_clock_info *cinfo); 403 struct dispc_clock_info *cinfo);
399int dispc_set_clock_div(struct dispc_clock_info *cinfo); 404int dispc_set_clock_div(enum omap_channel channel,
400int dispc_get_clock_div(struct dispc_clock_info *cinfo); 405 struct dispc_clock_info *cinfo);
406int dispc_get_clock_div(enum omap_channel channel,
407 struct dispc_clock_info *cinfo);
401 408
402 409
403/* VENC */ 410/* VENC */
@@ -424,8 +431,8 @@ void rfbi_dump_regs(struct seq_file *s);
424 431
425int rfbi_configure(int rfbi_module, int bpp, int lines); 432int rfbi_configure(int rfbi_module, int bpp, int lines);
426void rfbi_enable_rfbi(bool enable); 433void rfbi_enable_rfbi(bool enable);
427void rfbi_transfer_area(u16 width, u16 height, 434void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
428 void (callback)(void *data), void *data); 435 u16 height, void (callback)(void *data), void *data);
429void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); 436void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
430unsigned long rfbi_get_max_tx_rate(void); 437unsigned long rfbi_get_max_tx_rate(void);
431int rfbi_init_display(struct omap_dss_device *display); 438int rfbi_init_display(struct omap_dss_device *display);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 867f68de125f..cf3ef696e141 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -82,6 +82,18 @@ static const enum omap_display_type omap3_dss_supported_displays[] = {
82 OMAP_DISPLAY_TYPE_VENC, 82 OMAP_DISPLAY_TYPE_VENC,
83}; 83};
84 84
85static const enum omap_display_type omap4_dss_supported_displays[] = {
86 /* OMAP_DSS_CHANNEL_LCD */
87 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
88
89 /* OMAP_DSS_CHANNEL_DIGIT */
90 OMAP_DISPLAY_TYPE_VENC,
91
92 /* OMAP_DSS_CHANNEL_LCD2 */
93 OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
94 OMAP_DISPLAY_TYPE_DSI,
95};
96
85static const enum omap_color_mode omap2_dss_supported_color_modes[] = { 97static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
86 /* OMAP_DSS_GFX */ 98 /* OMAP_DSS_GFX */
87 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | 99 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -127,6 +139,10 @@ static struct omap_dss_features omap2_dss_features = {
127 .reg_fields = omap2_dss_reg_fields, 139 .reg_fields = omap2_dss_reg_fields,
128 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 140 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
129 141
142 .has_feature =
143 FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL |
144 FEAT_PCKFREEENABLE | FEAT_FUNCGATED,
145
130 .num_mgrs = 2, 146 .num_mgrs = 2,
131 .num_ovls = 3, 147 .num_ovls = 3,
132 .supported_displays = omap2_dss_supported_displays, 148 .supported_displays = omap2_dss_supported_displays,
@@ -134,11 +150,29 @@ static struct omap_dss_features omap2_dss_features = {
134}; 150};
135 151
136/* OMAP3 DSS Features */ 152/* OMAP3 DSS Features */
137static struct omap_dss_features omap3_dss_features = { 153static struct omap_dss_features omap3430_dss_features = {
154 .reg_fields = omap3_dss_reg_fields,
155 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
156
157 .has_feature =
158 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
159 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
160 FEAT_FUNCGATED,
161
162 .num_mgrs = 2,
163 .num_ovls = 3,
164 .supported_displays = omap3_dss_supported_displays,
165 .supported_color_modes = omap3_dss_supported_color_modes,
166};
167
168static struct omap_dss_features omap3630_dss_features = {
138 .reg_fields = omap3_dss_reg_fields, 169 .reg_fields = omap3_dss_reg_fields,
139 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 170 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
140 171
141 .has_feature = FEAT_GLOBAL_ALPHA, 172 .has_feature =
173 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
174 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
175 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED,
142 176
143 .num_mgrs = 2, 177 .num_mgrs = 2,
144 .num_ovls = 3, 178 .num_ovls = 3,
@@ -146,6 +180,21 @@ static struct omap_dss_features omap3_dss_features = {
146 .supported_color_modes = omap3_dss_supported_color_modes, 180 .supported_color_modes = omap3_dss_supported_color_modes,
147}; 181};
148 182
183/* OMAP4 DSS Features */
184static struct omap_dss_features omap4_dss_features = {
185 .reg_fields = omap3_dss_reg_fields,
186 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
187
188 .has_feature =
189 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
190 FEAT_MGR_LCD2,
191
192 .num_mgrs = 3,
193 .num_ovls = 3,
194 .supported_displays = omap4_dss_supported_displays,
195 .supported_color_modes = omap3_dss_supported_color_modes,
196};
197
149/* Functions returning values related to a DSS feature */ 198/* Functions returning values related to a DSS feature */
150int dss_feat_get_num_mgrs(void) 199int dss_feat_get_num_mgrs(void)
151{ 200{
@@ -167,6 +216,13 @@ enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
167 return omap_current_dss_features->supported_color_modes[plane]; 216 return omap_current_dss_features->supported_color_modes[plane];
168} 217}
169 218
219bool dss_feat_color_mode_supported(enum omap_plane plane,
220 enum omap_color_mode color_mode)
221{
222 return omap_current_dss_features->supported_color_modes[plane] &
223 color_mode;
224}
225
170/* DSS has_feature check */ 226/* DSS has_feature check */
171bool dss_has_feature(enum dss_feat_id id) 227bool dss_has_feature(enum dss_feat_id id)
172{ 228{
@@ -186,6 +242,10 @@ void dss_features_init(void)
186{ 242{
187 if (cpu_is_omap24xx()) 243 if (cpu_is_omap24xx())
188 omap_current_dss_features = &omap2_dss_features; 244 omap_current_dss_features = &omap2_dss_features;
245 else if (cpu_is_omap3630())
246 omap_current_dss_features = &omap3630_dss_features;
247 else if (cpu_is_omap34xx())
248 omap_current_dss_features = &omap3430_dss_features;
189 else 249 else
190 omap_current_dss_features = &omap3_dss_features; 250 omap_current_dss_features = &omap4_dss_features;
191} 251}
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index cb231eaa9b31..b9c70be92588 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -20,13 +20,19 @@
20#ifndef __OMAP2_DSS_FEATURES_H 20#ifndef __OMAP2_DSS_FEATURES_H
21#define __OMAP2_DSS_FEATURES_H 21#define __OMAP2_DSS_FEATURES_H
22 22
23#define MAX_DSS_MANAGERS 2 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25 25
26/* DSS has feature id */ 26/* DSS has feature id */
27enum dss_feat_id { 27enum dss_feat_id {
28 FEAT_GLOBAL_ALPHA = 1 << 0, 28 FEAT_GLOBAL_ALPHA = 1 << 0,
29 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1, 29 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
30 FEAT_PRE_MULT_ALPHA = 1 << 2,
31 FEAT_LCDENABLEPOL = 1 << 3,
32 FEAT_LCDENABLESIGNAL = 1 << 4,
33 FEAT_PCKFREEENABLE = 1 << 5,
34 FEAT_FUNCGATED = 1 << 6,
35 FEAT_MGR_LCD2 = 1 << 7,
30}; 36};
31 37
32/* DSS register field id */ 38/* DSS register field id */
@@ -43,6 +49,8 @@ int dss_feat_get_num_mgrs(void);
43int dss_feat_get_num_ovls(void); 49int dss_feat_get_num_ovls(void);
44enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 50enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
45enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 51enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
52bool dss_feat_color_mode_supported(enum omap_plane plane,
53 enum omap_color_mode color_mode);
46 54
47bool dss_has_feature(enum dss_feat_id id); 55bool dss_has_feature(enum dss_feat_id id);
48void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 56void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 545e9b9a4d92..172d4e697309 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -406,6 +406,7 @@ struct overlay_cache_data {
406 u16 out_width; /* if 0, out_width == width */ 406 u16 out_width; /* if 0, out_width == width */
407 u16 out_height; /* if 0, out_height == height */ 407 u16 out_height; /* if 0, out_height == height */
408 u8 global_alpha; 408 u8 global_alpha;
409 u8 pre_mult_alpha;
409 410
410 enum omap_channel channel; 411 enum omap_channel channel;
411 bool replication; 412 bool replication;
@@ -512,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
512 unsigned long timeout = msecs_to_jiffies(500); 513 unsigned long timeout = msecs_to_jiffies(500);
513 u32 irq; 514 u32 irq;
514 515
515 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
516 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
517 else 518 } else {
518 irq = DISPC_IRQ_VSYNC; 519 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
519 520 irq = DISPC_IRQ_VSYNC;
521 else
522 irq = DISPC_IRQ_VSYNC2;
523 }
520 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 524 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
521} 525}
522 526
@@ -524,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
524{ 528{
525 unsigned long timeout = msecs_to_jiffies(500); 529 unsigned long timeout = msecs_to_jiffies(500);
526 struct manager_cache_data *mc; 530 struct manager_cache_data *mc;
527 enum omap_channel channel;
528 u32 irq; 531 u32 irq;
529 int r; 532 int r;
530 int i; 533 int i;
@@ -535,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
535 538
536 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
537 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
538 channel = OMAP_DSS_CHANNEL_DIGIT;
539 } else { 541 } else {
540 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
541 enum omap_dss_update_mode mode; 543 enum omap_dss_update_mode mode;
@@ -543,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
543 if (mode != OMAP_DSS_UPDATE_AUTO) 545 if (mode != OMAP_DSS_UPDATE_AUTO)
544 return 0; 546 return 0;
545 547
546 irq = DISPC_IRQ_FRAMEDONE; 548 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
549 DISPC_IRQ_FRAMEDONE
550 : DISPC_IRQ_FRAMEDONE2;
547 } else { 551 } else {
548 irq = DISPC_IRQ_VSYNC; 552 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
553 DISPC_IRQ_VSYNC
554 : DISPC_IRQ_VSYNC2;
549 } 555 }
550 channel = OMAP_DSS_CHANNEL_LCD;
551 } 556 }
552 557
553 mc = &dss_cache.manager_cache[mgr->id]; 558 mc = &dss_cache.manager_cache[mgr->id];
@@ -594,7 +599,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
594int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 599int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
595{ 600{
596 unsigned long timeout = msecs_to_jiffies(500); 601 unsigned long timeout = msecs_to_jiffies(500);
597 enum omap_channel channel;
598 struct overlay_cache_data *oc; 602 struct overlay_cache_data *oc;
599 struct omap_dss_device *dssdev; 603 struct omap_dss_device *dssdev;
600 u32 irq; 604 u32 irq;
@@ -611,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
611 615
612 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
613 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
614 channel = OMAP_DSS_CHANNEL_DIGIT;
615 } else { 618 } else {
616 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
617 enum omap_dss_update_mode mode; 620 enum omap_dss_update_mode mode;
@@ -619,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
619 if (mode != OMAP_DSS_UPDATE_AUTO) 622 if (mode != OMAP_DSS_UPDATE_AUTO)
620 return 0; 623 return 0;
621 624
622 irq = DISPC_IRQ_FRAMEDONE; 625 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
626 DISPC_IRQ_FRAMEDONE
627 : DISPC_IRQ_FRAMEDONE2;
623 } else { 628 } else {
624 irq = DISPC_IRQ_VSYNC; 629 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
630 DISPC_IRQ_VSYNC
631 : DISPC_IRQ_VSYNC2;
625 } 632 }
626 channel = OMAP_DSS_CHANNEL_LCD;
627 } 633 }
628 634
629 oc = &dss_cache.overlay_cache[ovl->id]; 635 oc = &dss_cache.overlay_cache[ovl->id];
@@ -842,7 +848,9 @@ static int configure_overlay(enum omap_plane plane)
842 c->rotation_type, 848 c->rotation_type,
843 c->rotation, 849 c->rotation,
844 c->mirror, 850 c->mirror,
845 c->global_alpha); 851 c->global_alpha,
852 c->pre_mult_alpha,
853 c->channel);
846 854
847 if (r) { 855 if (r) {
848 /* this shouldn't happen */ 856 /* this shouldn't happen */
@@ -894,10 +902,10 @@ static int configure_dispc(void)
894 r = 0; 902 r = 0;
895 busy = false; 903 busy = false;
896 904
897 mgr_busy[0] = dispc_go_busy(0); 905 for (i = 0; i < num_mgrs; i++) {
898 mgr_busy[1] = dispc_go_busy(1); 906 mgr_busy[i] = dispc_go_busy(i);
899 mgr_go[0] = false; 907 mgr_go[i] = false;
900 mgr_go[1] = false; 908 }
901 909
902 /* Commit overlay settings */ 910 /* Commit overlay settings */
903 for (i = 0; i < num_ovls; ++i) { 911 for (i = 0; i < num_ovls; ++i) {
@@ -1156,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1156 const int num_mgrs = dss_feat_get_num_mgrs(); 1164 const int num_mgrs = dss_feat_get_num_mgrs();
1157 int i, r; 1165 int i, r;
1158 bool mgr_busy[MAX_DSS_MANAGERS]; 1166 bool mgr_busy[MAX_DSS_MANAGERS];
1167 u32 irq_mask;
1159 1168
1160 mgr_busy[0] = dispc_go_busy(0); 1169 for (i = 0; i < num_mgrs; i++)
1161 mgr_busy[1] = dispc_go_busy(1); 1170 mgr_busy[i] = dispc_go_busy(i);
1162 1171
1163 spin_lock(&dss_cache.lock); 1172 spin_lock(&dss_cache.lock);
1164 1173
@@ -1179,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1179 goto end; 1188 goto end;
1180 1189
1181 /* re-read busy flags */ 1190 /* re-read busy flags */
1182 mgr_busy[0] = dispc_go_busy(0); 1191 for (i = 0; i < num_mgrs; i++)
1183 mgr_busy[1] = dispc_go_busy(1); 1192 mgr_busy[i] = dispc_go_busy(i);
1184 1193
1185 /* keep running as long as there are busy managers, so that 1194 /* keep running as long as there are busy managers, so that
1186 * we can collect overlay-applied information */ 1195 * we can collect overlay-applied information */
@@ -1189,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1189 goto end; 1198 goto end;
1190 } 1199 }
1191 1200
1192 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, 1201 irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1193 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1202 DISPC_IRQ_EVSYNC_EVEN;
1194 DISPC_IRQ_EVSYNC_EVEN); 1203 if (dss_has_feature(FEAT_MGR_LCD2))
1204 irq_mask |= DISPC_IRQ_VSYNC2;
1205
1206 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
1195 dss_cache.irq_enabled = false; 1207 dss_cache.irq_enabled = false;
1196 1208
1197end: 1209end:
@@ -1265,6 +1277,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1265 oc->out_width = ovl->info.out_width; 1277 oc->out_width = ovl->info.out_width;
1266 oc->out_height = ovl->info.out_height; 1278 oc->out_height = ovl->info.out_height;
1267 oc->global_alpha = ovl->info.global_alpha; 1279 oc->global_alpha = ovl->info.global_alpha;
1280 oc->pre_mult_alpha = ovl->info.pre_mult_alpha;
1268 1281
1269 oc->replication = 1282 oc->replication =
1270 dss_use_replication(dssdev, ovl->info.color_mode); 1283 dss_use_replication(dssdev, ovl->info.color_mode);
@@ -1383,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1383 r = 0; 1396 r = 0;
1384 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
1385 if (!dss_cache.irq_enabled) { 1398 if (!dss_cache.irq_enabled) {
1386 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, 1399 u32 mask;
1387 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1400
1388 DISPC_IRQ_EVSYNC_EVEN); 1401 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1402 DISPC_IRQ_EVSYNC_EVEN;
1403 if (dss_has_feature(FEAT_MGR_LCD2))
1404 mask |= DISPC_IRQ_VSYNC2;
1405
1406 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
1389 dss_cache.irq_enabled = true; 1407 dss_cache.irq_enabled = true;
1390 } 1408 }
1391 configure_dispc(); 1409 configure_dispc();
@@ -1477,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1477 mgr->name = "tv"; 1495 mgr->name = "tv";
1478 mgr->id = OMAP_DSS_CHANNEL_DIGIT; 1496 mgr->id = OMAP_DSS_CHANNEL_DIGIT;
1479 break; 1497 break;
1498 case 2:
1499 mgr->name = "lcd2";
1500 mgr->id = OMAP_DSS_CHANNEL_LCD2;
1501 break;
1480 } 1502 }
1481 1503
1482 mgr->set_device = &omap_dss_set_device; 1504 mgr->set_device = &omap_dss_set_device;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 75642c22cac7..456efef03c20 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -257,6 +257,43 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
257 return size; 257 return size;
258} 258}
259 259
260static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
261 char *buf)
262{
263 return snprintf(buf, PAGE_SIZE, "%d\n",
264 ovl->info.pre_mult_alpha);
265}
266
267static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
268 const char *buf, size_t size)
269{
270 int r;
271 struct omap_overlay_info info;
272
273 ovl->get_overlay_info(ovl, &info);
274
275 /* only GFX and Video2 plane support pre alpha multiplied
276 * set zero for Video1 plane
277 */
278 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
279 ovl->id == OMAP_DSS_VIDEO1)
280 info.pre_mult_alpha = 0;
281 else
282 info.pre_mult_alpha = simple_strtoul(buf, NULL, 10);
283
284 r = ovl->set_overlay_info(ovl, &info);
285 if (r)
286 return r;
287
288 if (ovl->manager) {
289 r = ovl->manager->apply(ovl->manager);
290 if (r)
291 return r;
292 }
293
294 return size;
295}
296
260struct overlay_attribute { 297struct overlay_attribute {
261 struct attribute attr; 298 struct attribute attr;
262 ssize_t (*show)(struct omap_overlay *, char *); 299 ssize_t (*show)(struct omap_overlay *, char *);
@@ -280,6 +317,9 @@ static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
280 overlay_enabled_show, overlay_enabled_store); 317 overlay_enabled_show, overlay_enabled_store);
281static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, 318static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
282 overlay_global_alpha_show, overlay_global_alpha_store); 319 overlay_global_alpha_show, overlay_global_alpha_store);
320static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
321 overlay_pre_mult_alpha_show,
322 overlay_pre_mult_alpha_store);
283 323
284static struct attribute *overlay_sysfs_attrs[] = { 324static struct attribute *overlay_sysfs_attrs[] = {
285 &overlay_attr_name.attr, 325 &overlay_attr_name.attr,
@@ -290,6 +330,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
290 &overlay_attr_output_size.attr, 330 &overlay_attr_output_size.attr,
291 &overlay_attr_enabled.attr, 331 &overlay_attr_enabled.attr,
292 &overlay_attr_global_alpha.attr, 332 &overlay_attr_global_alpha.attr,
333 &overlay_attr_pre_mult_alpha.attr,
293 NULL 334 NULL
294}; 335};
295 336
@@ -623,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
623 int i; 664 int i;
624 struct omap_overlay_manager *lcd_mgr; 665 struct omap_overlay_manager *lcd_mgr;
625 struct omap_overlay_manager *tv_mgr; 666 struct omap_overlay_manager *tv_mgr;
667 struct omap_overlay_manager *lcd2_mgr = NULL;
626 struct omap_overlay_manager *mgr = NULL; 668 struct omap_overlay_manager *mgr = NULL;
627 669
628 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); 670 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
629 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); 671 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
630 672 if (dss_has_feature(FEAT_MGR_LCD2))
631 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 673 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
674
675 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
676 if (!lcd2_mgr->device || force) {
677 if (lcd2_mgr->device)
678 lcd2_mgr->unset_device(lcd2_mgr);
679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr;
681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
632 if (!lcd_mgr->device || force) { 683 if (!lcd_mgr->device || force) {
633 if (lcd_mgr->device) 684 if (lcd_mgr->device)
634 lcd_mgr->unset_device(lcd_mgr); 685 lcd_mgr->unset_device(lcd_mgr);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index bbe62464e92d..10a2ffe02882 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -301,8 +301,8 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
301} 301}
302EXPORT_SYMBOL(omap_rfbi_write_pixels); 302EXPORT_SYMBOL(omap_rfbi_write_pixels);
303 303
304void rfbi_transfer_area(u16 width, u16 height, 304void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
305 void (callback)(void *data), void *data) 305 u16 height, void (*callback)(void *data), void *data)
306{ 306{
307 u32 l; 307 u32 l;
308 308
@@ -311,9 +311,9 @@ void rfbi_transfer_area(u16 width, u16 height,
311 311
312 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 312 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
313 313
314 dispc_set_lcd_size(width, height); 314 dispc_set_lcd_size(dssdev->manager->id, width, height);
315 315
316 dispc_enable_channel(OMAP_DSS_CHANNEL_LCD, true); 316 dispc_enable_channel(dssdev->manager->id, true);
317 317
318 rfbi.framedone_callback = callback; 318 rfbi.framedone_callback = callback;
319 rfbi.framedone_callback_data = data; 319 rfbi.framedone_callback_data = data;
@@ -887,7 +887,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
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, true); 889 dss_setup_partial_planes(dssdev, x, y, w, h, true);
890 dispc_set_lcd_size(*w, *h); 890 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
891 } 891 }
892 892
893 return 0; 893 return 0;
@@ -899,7 +899,7 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
899 void (*callback)(void *), void *data) 899 void (*callback)(void *), void *data)
900{ 900{
901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 901 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
902 rfbi_transfer_area(w, h, callback, data); 902 rfbi_transfer_area(dssdev, w, h, callback, data);
903 } else { 903 } else {
904 struct omap_overlay *ovl; 904 struct omap_overlay *ovl;
905 void __iomem *addr; 905 void __iomem *addr;
@@ -1018,11 +1018,13 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
1018 goto err1; 1018 goto err1;
1019 } 1019 }
1020 1020
1021 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 1021 dispc_set_lcd_display_type(dssdev->manager->id,
1022 OMAP_DSS_LCD_DISPLAY_TFT);
1022 1023
1023 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI); 1024 dispc_set_parallel_interface_mode(dssdev->manager->id,
1025 OMAP_DSS_PARALLELMODE_RFBI);
1024 1026
1025 dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); 1027 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
1026 1028
1027 rfbi_configure(dssdev->phy.rfbi.channel, 1029 rfbi_configure(dssdev->phy.rfbi.channel,
1028 dssdev->ctrl.pixel_size, 1030 dssdev->ctrl.pixel_size,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index ee07a3cc22ef..b64adf7dfc88 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -35,12 +35,16 @@ static struct {
35 struct regulator *vdds_sdi_reg; 35 struct regulator *vdds_sdi_reg;
36} sdi; 36} sdi;
37 37
38static void sdi_basic_init(void) 38static void sdi_basic_init(struct omap_dss_device *dssdev)
39
39{ 40{
40 dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); 41 dispc_set_parallel_interface_mode(dssdev->manager->id,
42 OMAP_DSS_PARALLELMODE_BYPASS);
43
44 dispc_set_lcd_display_type(dssdev->manager->id,
45 OMAP_DSS_LCD_DISPLAY_TFT);
41 46
42 dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); 47 dispc_set_tft_data_lines(dssdev->manager->id, 24);
43 dispc_set_tft_data_lines(24);
44 dispc_lcd_enable_signal_polarity(1); 48 dispc_lcd_enable_signal_polarity(1);
45} 49}
46 50
@@ -68,20 +72,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
68 if (!sdi.skip_init) 72 if (!sdi.skip_init)
69 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 73 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
70 74
71 sdi_basic_init(); 75 sdi_basic_init(dssdev);
72 76
73 /* 15.5.9.1.2 */ 77 /* 15.5.9.1.2 */
74 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; 78 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
75 79
76 dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, 80 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
77 dssdev->panel.acb); 81 dssdev->panel.acbi, dssdev->panel.acb);
78 82
79 if (!sdi.skip_init) { 83 if (!sdi.skip_init) {
80 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 84 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
81 &dss_cinfo, &dispc_cinfo); 85 &dss_cinfo, &dispc_cinfo);
82 } else { 86 } else {
83 r = dss_get_clock_div(&dss_cinfo); 87 r = dss_get_clock_div(&dss_cinfo);
84 r = dispc_get_clock_div(&dispc_cinfo); 88 r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo);
85 } 89 }
86 90
87 if (r) 91 if (r)
@@ -102,13 +106,13 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
102 } 106 }
103 107
104 108
105 dispc_set_lcd_timings(t); 109 dispc_set_lcd_timings(dssdev->manager->id, t);
106 110
107 r = dss_set_clock_div(&dss_cinfo); 111 r = dss_set_clock_div(&dss_cinfo);
108 if (r) 112 if (r)
109 goto err2; 113 goto err2;
110 114
111 r = dispc_set_clock_div(&dispc_cinfo); 115 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
112 if (r) 116 if (r)
113 goto err2; 117 goto err2;
114 118
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 6a704f176c22..4fdab8e9c496 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2132,8 +2132,9 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2132 char *str, *options, *this_opt; 2132 char *str, *options, *this_opt;
2133 int r = 0; 2133 int r = 0;
2134 2134
2135 str = kmalloc(strlen(def_mode) + 1, GFP_KERNEL); 2135 str = kstrdup(def_mode, GFP_KERNEL);
2136 strcpy(str, def_mode); 2136 if (!str)
2137 return -ENOMEM;
2137 options = str; 2138 options = str;
2138 2139
2139 while (!r && (this_opt = strsep(&options, ",")) != NULL) { 2140 while (!r && (this_opt = strsep(&options, ",")) != NULL) {
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 46b430978bcc..61c819e35f7f 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/err.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/string.h> 18#include <linux/string.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
@@ -918,9 +919,9 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
918 } 919 }
919 920
920 info->clk = clk_get(NULL, "lcd"); 921 info->clk = clk_get(NULL, "lcd");
921 if (!info->clk || IS_ERR(info->clk)) { 922 if (IS_ERR(info->clk)) {
922 printk(KERN_ERR "failed to get lcd clock source\n"); 923 printk(KERN_ERR "failed to get lcd clock source\n");
923 ret = -ENOENT; 924 ret = PTR_ERR(info->clk);
924 goto release_irq; 925 goto release_irq;
925 } 926 }
926 927
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index e7594e145c96..74d9f546a2e8 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -222,6 +222,7 @@ struct sh_hdmi {
222 struct delayed_work edid_work; 222 struct delayed_work edid_work;
223 struct fb_var_screeninfo var; 223 struct fb_var_screeninfo var;
224 struct fb_monspecs monspec; 224 struct fb_monspecs monspec;
225 struct notifier_block notifier;
225}; 226};
226 227
227static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) 228static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
@@ -738,7 +739,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
738 struct fb_modelist *modelist = NULL; 739 struct fb_modelist *modelist = NULL;
739 unsigned int f_width = 0, f_height = 0, f_refresh = 0; 740 unsigned int f_width = 0, f_height = 0, f_refresh = 0;
740 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */ 741 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
741 bool exact_match = false; 742 bool scanning = false, preferred_bad = false;
742 u8 edid[128]; 743 u8 edid[128];
743 char *forced; 744 char *forced;
744 int i; 745 int i;
@@ -801,6 +802,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
801 if (i < 2) { 802 if (i < 2) {
802 f_width = 0; 803 f_width = 0;
803 f_height = 0; 804 f_height = 0;
805 } else {
806 /* The user wants us to use the EDID data */
807 scanning = true;
804 } 808 }
805 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n", 809 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
806 f_width, f_height, f_refresh); 810 f_width, f_height, f_refresh);
@@ -808,37 +812,56 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
808 812
809 /* Walk monitor modes to find the best or the exact match */ 813 /* Walk monitor modes to find the best or the exact match */
810 for (i = 0, mode = hdmi->monspec.modedb; 814 for (i = 0, mode = hdmi->monspec.modedb;
811 f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; 815 i < hdmi->monspec.modedb_len && scanning;
812 i++, mode++) { 816 i++, mode++) {
813 unsigned long rate_error; 817 unsigned long rate_error;
814 818
815 /* No interest in unmatching modes */ 819 if (!f_width && !f_height) {
816 if (f_width != mode->xres || f_height != mode->yres) 820 /*
821 * A parameter string "video=sh_mobile_lcdc:0x0" means
822 * use the preferred EDID mode. If it is rejected by
823 * .fb_check_var(), keep looking, until an acceptable
824 * one is found.
825 */
826 if ((mode->flag & FB_MODE_IS_FIRST) || preferred_bad)
827 scanning = false;
828 else
829 continue;
830 } else if (f_width != mode->xres || f_height != mode->yres) {
831 /* No interest in unmatching modes */
817 continue; 832 continue;
833 }
818 834
819 rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate); 835 rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate);
820 836
821 if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) 837 if (scanning) {
822 /* 838 if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
823 * Exact match if either the refresh rate matches or it 839 /*
824 * hasn't been specified and we've found a mode, for 840 * Exact match if either the refresh rate
825 * which we can configure the clock precisely 841 * matches or it hasn't been specified and we've
826 */ 842 * found a mode, for which we can configure the
827 exact_match = true; 843 * clock precisely
828 else if (found && found_rate_error <= rate_error) 844 */
829 /* 845 scanning = false;
830 * We otherwise search for the closest matching clock 846 else if (found && found_rate_error <= rate_error)
831 * rate - either if no refresh rate has been specified 847 /*
832 * or we cannot find an exactly matching one 848 * We otherwise search for the closest matching
833 */ 849 * clock rate - either if no refresh rate has
834 continue; 850 * been specified or we cannot find an exactly
851 * matching one
852 */
853 continue;
854 }
835 855
836 /* Check if supported: sufficient fb memory, supported clock-rate */ 856 /* Check if supported: sufficient fb memory, supported clock-rate */
837 fb_videomode_to_var(var, mode); 857 fb_videomode_to_var(var, mode);
838 858
859 var->bits_per_pixel = info->var.bits_per_pixel;
860
839 if (info && info->fbops->fb_check_var && 861 if (info && info->fbops->fb_check_var &&
840 info->fbops->fb_check_var(var, info)) { 862 info->fbops->fb_check_var(var, info)) {
841 exact_match = false; 863 scanning = true;
864 preferred_bad = true;
842 continue; 865 continue;
843 } 866 }
844 867
@@ -856,9 +879,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
856 * driver, and passing ->info with HDMI platform data. 879 * driver, and passing ->info with HDMI platform data.
857 */ 880 */
858 if (info && !found) { 881 if (info && !found) {
859 modelist = hdmi->info->modelist.next && 882 modelist = info->modelist.next &&
860 !list_empty(&hdmi->info->modelist) ? 883 !list_empty(&info->modelist) ?
861 list_entry(hdmi->info->modelist.next, 884 list_entry(info->modelist.next,
862 struct fb_modelist, list) : 885 struct fb_modelist, list) :
863 NULL; 886 NULL;
864 887
@@ -1101,6 +1124,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
1101 mutex_lock(&hdmi->mutex); 1124 mutex_lock(&hdmi->mutex);
1102 1125
1103 if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) { 1126 if (hdmi->hp_state == HDMI_HOTPLUG_CONNECTED) {
1127 struct fb_info *info = hdmi->info;
1104 unsigned long parent_rate = 0, hdmi_rate; 1128 unsigned long parent_rate = 0, hdmi_rate;
1105 1129
1106 /* A device has been plugged in */ 1130 /* A device has been plugged in */
@@ -1122,22 +1146,21 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
1122 /* Switched to another (d) power-save mode */ 1146 /* Switched to another (d) power-save mode */
1123 msleep(10); 1147 msleep(10);
1124 1148
1125 if (!hdmi->info) 1149 if (!info)
1126 goto out; 1150 goto out;
1127 1151
1128 ch = hdmi->info->par; 1152 ch = info->par;
1129 1153
1130 acquire_console_sem(); 1154 acquire_console_sem();
1131 1155
1132 /* HDMI plug in */ 1156 /* HDMI plug in */
1133 if (!sh_hdmi_must_reconfigure(hdmi) && 1157 if (!sh_hdmi_must_reconfigure(hdmi) &&
1134 hdmi->info->state == FBINFO_STATE_RUNNING) { 1158 info->state == FBINFO_STATE_RUNNING) {
1135 /* 1159 /*
1136 * First activation with the default monitor - just turn 1160 * First activation with the default monitor - just turn
1137 * on, if we run a resume here, the logo disappears 1161 * on, if we run a resume here, the logo disappears
1138 */ 1162 */
1139 if (lock_fb_info(hdmi->info)) { 1163 if (lock_fb_info(info)) {
1140 struct fb_info *info = hdmi->info;
1141 info->var.width = hdmi->var.width; 1164 info->var.width = hdmi->var.width;
1142 info->var.height = hdmi->var.height; 1165 info->var.height = hdmi->var.height;
1143 sh_hdmi_display_on(hdmi, info); 1166 sh_hdmi_display_on(hdmi, info);
@@ -1145,7 +1168,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
1145 } 1168 }
1146 } else { 1169 } else {
1147 /* New monitor or have to wake up */ 1170 /* New monitor or have to wake up */
1148 fb_set_suspend(hdmi->info, 0); 1171 fb_set_suspend(info, 0);
1149 } 1172 }
1150 1173
1151 release_console_sem(); 1174 release_console_sem();
@@ -1176,13 +1199,6 @@ out:
1176} 1199}
1177 1200
1178static int sh_hdmi_notify(struct notifier_block *nb, 1201static int sh_hdmi_notify(struct notifier_block *nb,
1179 unsigned long action, void *data);
1180
1181static struct notifier_block sh_hdmi_notifier = {
1182 .notifier_call = sh_hdmi_notify,
1183};
1184
1185static int sh_hdmi_notify(struct notifier_block *nb,
1186 unsigned long action, void *data) 1202 unsigned long action, void *data)
1187{ 1203{
1188 struct fb_event *event = data; 1204 struct fb_event *event = data;
@@ -1191,7 +1207,7 @@ static int sh_hdmi_notify(struct notifier_block *nb,
1191 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1207 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1192 struct sh_hdmi *hdmi = board_cfg->board_data; 1208 struct sh_hdmi *hdmi = board_cfg->board_data;
1193 1209
1194 if (nb != &sh_hdmi_notifier || !hdmi || hdmi->info != info) 1210 if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
1195 return NOTIFY_DONE; 1211 return NOTIFY_DONE;
1196 1212
1197 switch(action) { 1213 switch(action) {
@@ -1210,11 +1226,11 @@ static int sh_hdmi_notify(struct notifier_block *nb,
1210 * temporarily, synchronise with the work queue and re-acquire 1226 * temporarily, synchronise with the work queue and re-acquire
1211 * the info->lock. 1227 * the info->lock.
1212 */ 1228 */
1213 unlock_fb_info(hdmi->info); 1229 unlock_fb_info(info);
1214 mutex_lock(&hdmi->mutex); 1230 mutex_lock(&hdmi->mutex);
1215 hdmi->info = NULL; 1231 hdmi->info = NULL;
1216 mutex_unlock(&hdmi->mutex); 1232 mutex_unlock(&hdmi->mutex);
1217 lock_fb_info(hdmi->info); 1233 lock_fb_info(info);
1218 return NOTIFY_OK; 1234 return NOTIFY_OK;
1219 } 1235 }
1220 return NOTIFY_DONE; 1236 return NOTIFY_DONE;
@@ -1312,6 +1328,9 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
1312 goto ecodec; 1328 goto ecodec;
1313 } 1329 }
1314 1330
1331 hdmi->notifier.notifier_call = sh_hdmi_notify;
1332 fb_register_client(&hdmi->notifier);
1333
1315 return 0; 1334 return 0;
1316 1335
1317ecodec: 1336ecodec:
@@ -1342,6 +1361,8 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
1342 1361
1343 snd_soc_unregister_codec(&pdev->dev); 1362 snd_soc_unregister_codec(&pdev->dev);
1344 1363
1364 fb_unregister_client(&hdmi->notifier);
1365
1345 board_cfg->display_on = NULL; 1366 board_cfg->display_on = NULL;
1346 board_cfg->display_off = NULL; 1367 board_cfg->display_off = NULL;
1347 board_cfg->board_data = NULL; 1368 board_cfg->board_data = NULL;
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 7617f12e4fd7..0e120d67eb65 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -215,6 +215,33 @@ static int vt8500lcd_pan_display(struct fb_var_screeninfo *var,
215 return 0; 215 return 0;
216} 216}
217 217
218/*
219 * vt8500lcd_blank():
220 * Blank the display by setting all palette values to zero. Note,
221 * True Color modes do not really use the palette, so this will not
222 * blank the display in all modes.
223 */
224static int vt8500lcd_blank(int blank, struct fb_info *info)
225{
226 int i;
227
228 switch (blank) {
229 case FB_BLANK_POWERDOWN:
230 case FB_BLANK_VSYNC_SUSPEND:
231 case FB_BLANK_HSYNC_SUSPEND:
232 case FB_BLANK_NORMAL:
233 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
234 info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
235 for (i = 0; i < 256; i++)
236 vt8500lcd_setcolreg(i, 0, 0, 0, 0, info);
237 case FB_BLANK_UNBLANK:
238 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
239 info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
240 fb_set_cmap(&info->cmap, info);
241 }
242 return 0;
243}
244
218static struct fb_ops vt8500lcd_ops = { 245static struct fb_ops vt8500lcd_ops = {
219 .owner = THIS_MODULE, 246 .owner = THIS_MODULE,
220 .fb_set_par = vt8500lcd_set_par, 247 .fb_set_par = vt8500lcd_set_par,
@@ -225,6 +252,7 @@ static struct fb_ops vt8500lcd_ops = {
225 .fb_sync = wmt_ge_sync, 252 .fb_sync = wmt_ge_sync,
226 .fb_ioctl = vt8500lcd_ioctl, 253 .fb_ioctl = vt8500lcd_ioctl,
227 .fb_pan_display = vt8500lcd_pan_display, 254 .fb_pan_display = vt8500lcd_pan_display,
255 .fb_blank = vt8500lcd_blank,
228}; 256};
229 257
230static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id) 258static irqreturn_t vt8500lcd_handle_irq(int irq, void *dev_id)