aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 11:42:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 11:42:37 -0400
commit0f1493a60167cf6333626456d3fc8aff4e6fa237 (patch)
tree3b46a263bbab4fd396f01f35f0ceca7f3b063163 /drivers/video
parent023bc8e75f8cf9e4da8411154be22a4f809d3314 (diff)
parent087faf77a57b06f9a8ce37781c68e3f02468322b (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: (126 commits) sh_mobile_meram: Safely disable MERAM operation when not initialized video: mb862xxfb: add support for L1 displaying video: mb862xx: add support for controller's I2C bus adapter video: mb862xxfb: relocate register space to get contiguous vram video: mb862xxfb: use pre-initialized configuration for PCI GDCs video: mb862xxfb: correct fix.smem_len field initialization video: s3c-fb: correct transparency checking in 32bpp video: s3c-fb: add gpio setup function to resume function fbdev/amifb: Remove superfluous alignment of frame buffer memory fbdev/amifb: Do not call panic() if there's not enough Chip RAM fbdev/amifb: Correct check for video memory size video: mb862xxfb: Require either FB_MB862XX_PCI_GDC or FB_MB862XX_LIME video: s3c-fb: add window variant information for S5P video: s3c-fb: add additional validate bpps video: s3c-fb: correct window osd size offset values udlfb: include prefetch.h explicitly drivers/video/s3c2410fb.c: Convert release_resource to release_mem_region drivers/video/sm501fb.c: Convert release_resource to release_mem_region drivers/video: Convert release_resource to release_mem_region video, udlfb: Fix two build warnings about 'ignoring return value' ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig42
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/amifb.c27
-rw-r--r--drivers/video/da8xx-fb.c4
-rw-r--r--drivers/video/efifb.c4
-rw-r--r--drivers/video/mb862xx/Makefile5
-rw-r--r--drivers/video/mb862xx/mb862xx-i2c.c177
-rw-r--r--drivers/video/mb862xx/mb862xx_reg.h58
-rw-r--r--drivers/video/mb862xx/mb862xxfb.h36
-rw-r--r--drivers/video/mb862xx/mb862xxfbdrv.c (renamed from drivers/video/mb862xx/mb862xxfb.c)152
-rw-r--r--drivers/video/omap/dispc.c4
-rw-r--r--drivers/video/omap/omapfb_main.c2
-rw-r--r--drivers/video/omap/rfbi.c2
-rw-r--r--drivers/video/omap2/Makefile4
-rw-r--r--drivers/video/omap2/displays/Kconfig9
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c2
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c57
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c2
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c2
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c6
-rw-r--r--drivers/video/omap2/displays/panel-taal.c536
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c10
-rw-r--r--drivers/video/omap2/dss/Kconfig33
-rw-r--r--drivers/video/omap2/dss/core.c15
-rw-r--r--drivers/video/omap2/dss/dispc.c1552
-rw-r--r--drivers/video/omap2/dss/dispc.h691
-rw-r--r--drivers/video/omap2/dss/display.c46
-rw-r--r--drivers/video/omap2/dss/dpi.c113
-rw-r--r--drivers/video/omap2/dss/dsi.c2367
-rw-r--r--drivers/video/omap2/dss/dss.c118
-rw-r--r--drivers/video/omap2/dss/dss.h98
-rw-r--r--drivers/video/omap2/dss/dss_features.c105
-rw-r--r--drivers/video/omap2/dss/dss_features.h39
-rw-r--r--drivers/video/omap2/dss/hdmi.c461
-rw-r--r--drivers/video/omap2/dss/hdmi.h222
-rw-r--r--drivers/video/omap2/dss/hdmi_omap4_panel.c2
-rw-r--r--drivers/video/omap2/dss/manager.c14
-rw-r--r--drivers/video/omap2/dss/overlay.c43
-rw-r--r--drivers/video/omap2/dss/rfbi.c176
-rw-r--r--drivers/video/omap2/dss/sdi.c2
-rw-r--r--drivers/video/omap2/dss/venc.c23
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c14
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c231
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c23
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h8
-rw-r--r--drivers/video/s3c-fb.c121
-rw-r--r--drivers/video/s3c2410fb.c8
-rw-r--r--drivers/video/s3fb.c209
-rw-r--r--drivers/video/savage/savagefb-i2c.c2
-rw-r--r--drivers/video/savage/savagefb.h8
-rw-r--r--drivers/video/savage/savagefb_driver.c15
-rw-r--r--drivers/video/sh7760fb.c6
-rw-r--r--drivers/video/sh_mobile_hdmi.c10
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c126
-rw-r--r--drivers/video/sh_mobile_lcdcfb.h1
-rw-r--r--drivers/video/sh_mobile_meram.c567
-rw-r--r--drivers/video/sh_mobile_meram.h41
-rw-r--r--drivers/video/sm501fb.c24
-rw-r--r--drivers/video/udlfb.c20
59 files changed, 6520 insertions, 2176 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f9916ca5ca4d..549b960667c8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1460,6 +1460,14 @@ config FB_S3
1460 ---help--- 1460 ---help---
1461 Driver for graphics boards with S3 Trio / S3 Virge chip. 1461 Driver for graphics boards with S3 Trio / S3 Virge chip.
1462 1462
1463config FB_S3_DDC
1464 bool "DDC for S3 support"
1465 depends on FB_S3
1466 select FB_DDC
1467 default y
1468 help
1469 Say Y here if you want DDC support for your S3 graphics card.
1470
1463config FB_SAVAGE 1471config FB_SAVAGE
1464 tristate "S3 Savage support" 1472 tristate "S3 Savage support"
1465 depends on FB && PCI && EXPERIMENTAL 1473 depends on FB && PCI && EXPERIMENTAL
@@ -1983,6 +1991,18 @@ config FB_SH_MOBILE_HDMI
1983 ---help--- 1991 ---help---
1984 Driver for the on-chip SH-Mobile HDMI controller. 1992 Driver for the on-chip SH-Mobile HDMI controller.
1985 1993
1994config FB_SH_MOBILE_MERAM
1995 tristate "SuperH Mobile MERAM read ahead support for LCDC"
1996 depends on FB_SH_MOBILE_LCDC
1997 default y
1998 ---help---
1999 Enable MERAM support for the SH-Mobile LCD controller.
2000
2001 This will allow for caching of the framebuffer to provide more
2002 reliable access under heavy main memory bus traffic situations.
2003 Up to 4 memory channels can be configured, allowing 4 RGB or
2004 2 YCbCr framebuffers to be configured.
2005
1986config FB_TMIO 2006config FB_TMIO
1987 tristate "Toshiba Mobile IO FrameBuffer support" 2007 tristate "Toshiba Mobile IO FrameBuffer support"
1988 depends on FB && MFD_CORE 2008 depends on FB && MFD_CORE
@@ -2246,29 +2266,43 @@ config FB_METRONOME
2246config FB_MB862XX 2266config FB_MB862XX
2247 tristate "Fujitsu MB862xx GDC support" 2267 tristate "Fujitsu MB862xx GDC support"
2248 depends on FB 2268 depends on FB
2269 depends on PCI || (OF && PPC)
2249 select FB_CFB_FILLRECT 2270 select FB_CFB_FILLRECT
2250 select FB_CFB_COPYAREA 2271 select FB_CFB_COPYAREA
2251 select FB_CFB_IMAGEBLIT 2272 select FB_CFB_IMAGEBLIT
2252 ---help--- 2273 ---help---
2253 Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. 2274 Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
2254 2275
2276choice
2277 prompt "GDC variant"
2278 depends on FB_MB862XX
2279
2255config FB_MB862XX_PCI_GDC 2280config FB_MB862XX_PCI_GDC
2256 bool "Carmine/Coral-P(A) GDC" 2281 bool "Carmine/Coral-P(A) GDC"
2257 depends on PCI && FB_MB862XX 2282 depends on PCI
2258 ---help--- 2283 ---help---
2259 This enables framebuffer support for Fujitsu Carmine/Coral-P(A) 2284 This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
2260 PCI graphics controller devices. 2285 PCI graphics controller devices.
2261 2286
2262config FB_MB862XX_LIME 2287config FB_MB862XX_LIME
2263 bool "Lime GDC" 2288 bool "Lime GDC"
2264 depends on FB_MB862XX 2289 depends on OF && PPC
2265 depends on OF && !FB_MB862XX_PCI_GDC
2266 depends on PPC
2267 select FB_FOREIGN_ENDIAN 2290 select FB_FOREIGN_ENDIAN
2268 select FB_LITTLE_ENDIAN 2291 select FB_LITTLE_ENDIAN
2269 ---help--- 2292 ---help---
2270 Framebuffer support for Fujitsu Lime GDC on host CPU bus. 2293 Framebuffer support for Fujitsu Lime GDC on host CPU bus.
2271 2294
2295endchoice
2296
2297config FB_MB862XX_I2C
2298 bool "Support I2C bus on MB862XX GDC"
2299 depends on FB_MB862XX && I2C
2300 default y
2301 help
2302 Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
2303 driver to support accessing I2C devices on controller's I2C bus.
2304 These are usually some video decoder chips.
2305
2272config FB_EP93XX 2306config FB_EP93XX
2273 tristate "EP93XX frame buffer support" 2307 tristate "EP93XX frame buffer support"
2274 depends on FB && ARCH_EP93XX 2308 depends on FB && ARCH_EP93XX
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 2ea44b6625fe..8b83129e209c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -130,6 +130,7 @@ obj-$(CONFIG_FB_UDL) += udlfb.o
130obj-$(CONFIG_FB_XILINX) += xilinxfb.o 130obj-$(CONFIG_FB_XILINX) += xilinxfb.o
131obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o 131obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
132obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o 132obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
133obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
133obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o 134obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
134obj-$(CONFIG_FB_OMAP) += omap/ 135obj-$(CONFIG_FB_OMAP) += omap/
135obj-y += omap2/ 136obj-y += omap2/
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index e5d6b56d4447..5ea6596dd824 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2224,22 +2224,23 @@ static int amifb_ioctl(struct fb_info *info,
2224 * Allocate, Clear and Align a Block of Chip Memory 2224 * Allocate, Clear and Align a Block of Chip Memory
2225 */ 2225 */
2226 2226
2227static u_long unaligned_chipptr = 0; 2227static void *aligned_chipptr;
2228 2228
2229static inline u_long __init chipalloc(u_long size) 2229static inline u_long __init chipalloc(u_long size)
2230{ 2230{
2231 size += PAGE_SIZE-1; 2231 aligned_chipptr = amiga_chip_alloc(size, "amifb [RAM]");
2232 if (!(unaligned_chipptr = (u_long)amiga_chip_alloc(size, 2232 if (!aligned_chipptr) {
2233 "amifb [RAM]"))) 2233 pr_err("amifb: No Chip RAM for frame buffer");
2234 panic("No Chip RAM for frame buffer"); 2234 return 0;
2235 memset((void *)unaligned_chipptr, 0, size); 2235 }
2236 return PAGE_ALIGN(unaligned_chipptr); 2236 memset(aligned_chipptr, 0, size);
2237 return (u_long)aligned_chipptr;
2237} 2238}
2238 2239
2239static inline void chipfree(void) 2240static inline void chipfree(void)
2240{ 2241{
2241 if (unaligned_chipptr) 2242 if (aligned_chipptr)
2242 amiga_chip_free((void *)unaligned_chipptr); 2243 amiga_chip_free(aligned_chipptr);
2243} 2244}
2244 2245
2245 2246
@@ -2295,7 +2296,7 @@ default_chipset:
2295 defmode = amiga_vblank == 50 ? DEFMODE_PAL 2296 defmode = amiga_vblank == 50 ? DEFMODE_PAL
2296 : DEFMODE_NTSC; 2297 : DEFMODE_NTSC;
2297 if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > 2298 if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
2298 VIDEOMEMSIZE_ECS_1M) 2299 VIDEOMEMSIZE_ECS_2M)
2299 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M; 2300 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
2300 else 2301 else
2301 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M; 2302 fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M;
@@ -2312,7 +2313,7 @@ default_chipset:
2312 maxfmode = TAG_FMODE_4; 2313 maxfmode = TAG_FMODE_4;
2313 defmode = DEFMODE_AGA; 2314 defmode = DEFMODE_AGA;
2314 if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT > 2315 if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
2315 VIDEOMEMSIZE_AGA_1M) 2316 VIDEOMEMSIZE_AGA_2M)
2316 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M; 2317 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
2317 else 2318 else
2318 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M; 2319 fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
@@ -2385,6 +2386,10 @@ default_chipset:
2385 DUMMYSPRITEMEMSIZE+ 2386 DUMMYSPRITEMEMSIZE+
2386 COPINITSIZE+ 2387 COPINITSIZE+
2387 4*COPLISTSIZE); 2388 4*COPLISTSIZE);
2389 if (!chipptr) {
2390 err = -ENOMEM;
2391 goto amifb_error;
2392 }
2388 2393
2389 assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len); 2394 assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len);
2390 assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE); 2395 assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE);
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 8b7d47386f39..fcdac872522d 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -899,7 +899,7 @@ static struct fb_ops da8xx_fb_ops = {
899 .fb_blank = cfb_blank, 899 .fb_blank = cfb_blank,
900}; 900};
901 901
902static int __init fb_probe(struct platform_device *device) 902static int __devinit fb_probe(struct platform_device *device)
903{ 903{
904 struct da8xx_lcdc_platform_data *fb_pdata = 904 struct da8xx_lcdc_platform_data *fb_pdata =
905 device->dev.platform_data; 905 device->dev.platform_data;
@@ -1165,7 +1165,7 @@ static int fb_resume(struct platform_device *dev)
1165 1165
1166static struct platform_driver da8xx_fb_driver = { 1166static struct platform_driver da8xx_fb_driver = {
1167 .probe = fb_probe, 1167 .probe = fb_probe,
1168 .remove = fb_remove, 1168 .remove = __devexit_p(fb_remove),
1169 .suspend = fb_suspend, 1169 .suspend = fb_suspend,
1170 .resume = fb_resume, 1170 .resume = fb_resume,
1171 .driver = { 1171 .driver = {
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 4eb38db36e4b..fb205843c2c7 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -242,9 +242,9 @@ static int set_system(const struct dmi_system_id *id)
242 return 0; 242 return 0;
243 } 243 }
244 244
245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " 245 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x "
246 "(%dx%d, stride %d)\n", id->ident, 246 "(%dx%d, stride %d)\n", id->ident,
247 (void *)screen_info.lfb_base, screen_info.lfb_width, 247 screen_info.lfb_base, screen_info.lfb_width,
248 screen_info.lfb_height, screen_info.lfb_linelength); 248 screen_info.lfb_height, screen_info.lfb_linelength);
249 249
250 250
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile
index d7777714166b..5707ed0e31a7 100644
--- a/drivers/video/mb862xx/Makefile
+++ b/drivers/video/mb862xx/Makefile
@@ -2,4 +2,7 @@
2# Makefile for the MB862xx framebuffer driver 2# Makefile for the MB862xx framebuffer driver
3# 3#
4 4
5obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o mb862xxfb_accel.o 5obj-$(CONFIG_FB_MB862XX) += mb862xxfb.o
6
7mb862xxfb-y := mb862xxfbdrv.o mb862xxfb_accel.o
8mb862xxfb-$(CONFIG_FB_MB862XX_I2C) += mb862xx-i2c.o
diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/mb862xx/mb862xx-i2c.c
new file mode 100644
index 000000000000..cb77d3b4657d
--- /dev/null
+++ b/drivers/video/mb862xx/mb862xx-i2c.c
@@ -0,0 +1,177 @@
1/*
2 * Coral-P(A)/Lime I2C adapter driver
3 *
4 * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/fb.h>
13#include <linux/i2c.h>
14#include <linux/io.h>
15
16#include "mb862xxfb.h"
17#include "mb862xx_reg.h"
18
19static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
20{
21 struct mb862xxfb_par *par = adap->algo_data;
22 u32 reg;
23
24 do {
25 udelay(1);
26 reg = inreg(i2c, GC_I2C_BCR);
27 if (reg & (I2C_INT | I2C_BER))
28 break;
29 } while (1);
30
31 return (reg & I2C_BER) ? 0 : 1;
32}
33
34static int mb862xx_i2c_do_address(struct i2c_adapter *adap, int addr)
35{
36 struct mb862xxfb_par *par = adap->algo_data;
37
38 outreg(i2c, GC_I2C_DAR, addr);
39 outreg(i2c, GC_I2C_CCR, I2C_CLOCK_AND_ENABLE);
40 outreg(i2c, GC_I2C_BCR, par->i2c_rs ? I2C_REPEATED_START : I2C_START);
41 if (!mb862xx_i2c_wait_event(adap))
42 return -EIO;
43 par->i2c_rs = !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
44 return par->i2c_rs;
45}
46
47static int mb862xx_i2c_write_byte(struct i2c_adapter *adap, u8 byte)
48{
49 struct mb862xxfb_par *par = adap->algo_data;
50
51 outreg(i2c, GC_I2C_DAR, byte);
52 outreg(i2c, GC_I2C_BCR, I2C_START);
53 if (!mb862xx_i2c_wait_event(adap))
54 return -EIO;
55 return !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
56}
57
58static int mb862xx_i2c_read_byte(struct i2c_adapter *adap, u8 *byte, int last)
59{
60 struct mb862xxfb_par *par = adap->algo_data;
61
62 outreg(i2c, GC_I2C_BCR, I2C_START | (last ? 0 : I2C_ACK));
63 if (!mb862xx_i2c_wait_event(adap))
64 return 0;
65 *byte = inreg(i2c, GC_I2C_DAR);
66 return 1;
67}
68
69void mb862xx_i2c_stop(struct i2c_adapter *adap)
70{
71 struct mb862xxfb_par *par = adap->algo_data;
72
73 outreg(i2c, GC_I2C_BCR, I2C_STOP);
74 outreg(i2c, GC_I2C_CCR, I2C_DISABLE);
75 par->i2c_rs = 0;
76}
77
78static int mb862xx_i2c_read(struct i2c_adapter *adap, struct i2c_msg *m)
79{
80 int i, ret = 0;
81 int last = m->len - 1;
82
83 for (i = 0; i < m->len; i++) {
84 if (!mb862xx_i2c_read_byte(adap, &m->buf[i], i == last)) {
85 ret = -EIO;
86 break;
87 }
88 }
89 return ret;
90}
91
92static int mb862xx_i2c_write(struct i2c_adapter *adap, struct i2c_msg *m)
93{
94 int i, ret = 0;
95
96 for (i = 0; i < m->len; i++) {
97 if (!mb862xx_i2c_write_byte(adap, m->buf[i])) {
98 ret = -EIO;
99 break;
100 }
101 }
102 return ret;
103}
104
105static int mb862xx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
106 int num)
107{
108 struct mb862xxfb_par *par = adap->algo_data;
109 struct i2c_msg *m;
110 int addr;
111 int i = 0, err = 0;
112
113 dev_dbg(par->dev, "%s: %d msgs\n", __func__, num);
114
115 for (i = 0; i < num; i++) {
116 m = &msgs[i];
117 if (!m->len) {
118 dev_dbg(par->dev, "%s: null msgs\n", __func__);
119 continue;
120 }
121 addr = m->addr;
122 if (m->flags & I2C_M_RD)
123 addr |= 1;
124
125 err = mb862xx_i2c_do_address(adap, addr);
126 if (err < 0)
127 break;
128 if (m->flags & I2C_M_RD)
129 err = mb862xx_i2c_read(adap, m);
130 else
131 err = mb862xx_i2c_write(adap, m);
132 }
133
134 if (i)
135 mb862xx_i2c_stop(adap);
136
137 return (err < 0) ? err : i;
138}
139
140static u32 mb862xx_func(struct i2c_adapter *adap)
141{
142 return I2C_FUNC_SMBUS_BYTE_DATA;
143}
144
145static const struct i2c_algorithm mb862xx_algo = {
146 .master_xfer = mb862xx_xfer,
147 .functionality = mb862xx_func,
148};
149
150static struct i2c_adapter mb862xx_i2c_adapter = {
151 .name = "MB862xx I2C adapter",
152 .algo = &mb862xx_algo,
153 .owner = THIS_MODULE,
154};
155
156int mb862xx_i2c_init(struct mb862xxfb_par *par)
157{
158 int ret;
159
160 mb862xx_i2c_adapter.algo_data = par;
161 par->adap = &mb862xx_i2c_adapter;
162
163 ret = i2c_add_adapter(par->adap);
164 if (ret < 0) {
165 dev_err(par->dev, "failed to add %s\n",
166 mb862xx_i2c_adapter.name);
167 }
168 return ret;
169}
170
171void mb862xx_i2c_exit(struct mb862xxfb_par *par)
172{
173 if (par->adap) {
174 i2c_del_adapter(par->adap);
175 par->adap = NULL;
176 }
177}
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h
index 2ba65e118500..9df48b8edc94 100644
--- a/drivers/video/mb862xx/mb862xx_reg.h
+++ b/drivers/video/mb862xx/mb862xx_reg.h
@@ -5,11 +5,8 @@
5#ifndef _MB862XX_REG_H 5#ifndef _MB862XX_REG_H
6#define _MB862XX_REG_H 6#define _MB862XX_REG_H
7 7
8#ifdef MB862XX_MMIO_BOTTOM
9#define MB862XX_MMIO_BASE 0x03fc0000
10#else
11#define MB862XX_MMIO_BASE 0x01fc0000 8#define MB862XX_MMIO_BASE 0x01fc0000
12#endif 9#define MB862XX_MMIO_HIGH_BASE 0x03fc0000
13#define MB862XX_I2C_BASE 0x0000c000 10#define MB862XX_I2C_BASE 0x0000c000
14#define MB862XX_DISP_BASE 0x00010000 11#define MB862XX_DISP_BASE 0x00010000
15#define MB862XX_CAP_BASE 0x00018000 12#define MB862XX_CAP_BASE 0x00018000
@@ -23,6 +20,7 @@
23#define GC_IMASK 0x00000024 20#define GC_IMASK 0x00000024
24#define GC_SRST 0x0000002c 21#define GC_SRST 0x0000002c
25#define GC_CCF 0x00000038 22#define GC_CCF 0x00000038
23#define GC_RSW 0x0000005c
26#define GC_CID 0x000000f0 24#define GC_CID 0x000000f0
27#define GC_REVISION 0x00000084 25#define GC_REVISION 0x00000084
28 26
@@ -53,10 +51,16 @@
53#define GC_L0OA0 0x00000024 51#define GC_L0OA0 0x00000024
54#define GC_L0DA0 0x00000028 52#define GC_L0DA0 0x00000028
55#define GC_L0DY_L0DX 0x0000002c 53#define GC_L0DY_L0DX 0x0000002c
54#define GC_L1M 0x00000030
55#define GC_L1DA 0x00000034
56#define GC_DCM1 0x00000100 56#define GC_DCM1 0x00000100
57#define GC_L0EM 0x00000110 57#define GC_L0EM 0x00000110
58#define GC_L0WY_L0WX 0x00000114 58#define GC_L0WY_L0WX 0x00000114
59#define GC_L0WH_L0WW 0x00000118 59#define GC_L0WH_L0WW 0x00000118
60#define GC_L1EM 0x00000120
61#define GC_L1WY_L1WX 0x00000124
62#define GC_L1WH_L1WW 0x00000128
63#define GC_DLS 0x00000180
60#define GC_DCM2 0x00000104 64#define GC_DCM2 0x00000104
61#define GC_DCM3 0x00000108 65#define GC_DCM3 0x00000108
62#define GC_CPM_CUTC 0x000000a0 66#define GC_CPM_CUTC 0x000000a0
@@ -68,6 +72,11 @@
68 72
69#define GC_CPM_CEN0 0x00100000 73#define GC_CPM_CEN0 0x00100000
70#define GC_CPM_CEN1 0x00200000 74#define GC_CPM_CEN1 0x00200000
75#define GC_DCM1_DEN 0x80000000
76#define GC_DCM1_L1E 0x00020000
77#define GC_L1M_16 0x80000000
78#define GC_L1M_YC 0x40000000
79#define GC_L1M_CS 0x20000000
71 80
72#define GC_DCM01_ESY 0x00000004 81#define GC_DCM01_ESY 0x00000004
73#define GC_DCM01_SC 0x00003f00 82#define GC_DCM01_SC 0x00003f00
@@ -79,9 +88,50 @@
79#define GC_L0M_L0C_16 0x80000000 88#define GC_L0M_L0C_16 0x80000000
80#define GC_L0EM_L0EC_24 0x40000000 89#define GC_L0EM_L0EC_24 0x40000000
81#define GC_L0M_L0W_UNIT 64 90#define GC_L0M_L0W_UNIT 64
91#define GC_L1EM_DM 0x02000000
82 92
83#define GC_DISP_REFCLK_400 400 93#define GC_DISP_REFCLK_400 400
84 94
95/* I2C */
96#define GC_I2C_BSR 0x00000000 /* BSR */
97#define GC_I2C_BCR 0x00000004 /* BCR */
98#define GC_I2C_CCR 0x00000008 /* CCR */
99#define GC_I2C_ADR 0x0000000C /* ADR */
100#define GC_I2C_DAR 0x00000010 /* DAR */
101
102#define I2C_DISABLE 0x00000000
103#define I2C_STOP 0x00000000
104#define I2C_START 0x00000010
105#define I2C_REPEATED_START 0x00000030
106#define I2C_CLOCK_AND_ENABLE 0x0000003f
107#define I2C_READY 0x01
108#define I2C_INT 0x01
109#define I2C_INTE 0x02
110#define I2C_ACK 0x08
111#define I2C_BER 0x80
112#define I2C_BEIE 0x40
113#define I2C_TRX 0x80
114#define I2C_LRB 0x10
115
116/* Capture registers and bits */
117#define GC_CAP_VCM 0x00000000
118#define GC_CAP_CSC 0x00000004
119#define GC_CAP_VCS 0x00000008
120#define GC_CAP_CBM 0x00000010
121#define GC_CAP_CBOA 0x00000014
122#define GC_CAP_CBLA 0x00000018
123#define GC_CAP_IMG_START 0x0000001C
124#define GC_CAP_IMG_END 0x00000020
125#define GC_CAP_CMSS 0x00000048
126#define GC_CAP_CMDS 0x0000004C
127
128#define GC_VCM_VIE 0x80000000
129#define GC_VCM_CM 0x03000000
130#define GC_VCM_VS_PAL 0x00000002
131#define GC_CBM_OO 0x80000000
132#define GC_CBM_HRV 0x00000010
133#define GC_CBM_CBST 0x00000001
134
85/* Carmine specific */ 135/* Carmine specific */
86#define MB86297_DRAW_BASE 0x00020000 136#define MB86297_DRAW_BASE 0x00020000
87#define MB86297_DISP0_BASE 0x00100000 137#define MB86297_DISP0_BASE 0x00100000
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h
index d7e7cb76bbf2..8550630c1e01 100644
--- a/drivers/video/mb862xx/mb862xxfb.h
+++ b/drivers/video/mb862xx/mb862xxfb.h
@@ -1,6 +1,26 @@
1#ifndef __MB862XX_H__ 1#ifndef __MB862XX_H__
2#define __MB862XX_H__ 2#define __MB862XX_H__
3 3
4struct mb862xx_l1_cfg {
5 unsigned short sx;
6 unsigned short sy;
7 unsigned short sw;
8 unsigned short sh;
9 unsigned short dx;
10 unsigned short dy;
11 unsigned short dw;
12 unsigned short dh;
13 int mirror;
14};
15
16#define MB862XX_BASE 'M'
17#define MB862XX_L1_GET_CFG _IOR(MB862XX_BASE, 0, struct mb862xx_l1_cfg*)
18#define MB862XX_L1_SET_CFG _IOW(MB862XX_BASE, 1, struct mb862xx_l1_cfg*)
19#define MB862XX_L1_ENABLE _IOW(MB862XX_BASE, 2, int)
20#define MB862XX_L1_CAP_CTL _IOW(MB862XX_BASE, 3, int)
21
22#ifdef __KERNEL__
23
4#define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf 24#define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf
5#define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019 25#define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019
6#define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e 26#define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e
@@ -38,6 +58,8 @@ struct mb862xxfb_par {
38 void __iomem *mmio_base; /* remapped registers */ 58 void __iomem *mmio_base; /* remapped registers */
39 size_t mapped_vram; /* length of remapped vram */ 59 size_t mapped_vram; /* length of remapped vram */
40 size_t mmio_len; /* length of register region */ 60 size_t mmio_len; /* length of register region */
61 unsigned long cap_buf; /* capture buffers offset */
62 size_t cap_len; /* length of capture buffers */
41 63
42 void __iomem *host; /* relocatable reg. bases */ 64 void __iomem *host; /* relocatable reg. bases */
43 void __iomem *i2c; 65 void __iomem *i2c;
@@ -57,11 +79,23 @@ struct mb862xxfb_par {
57 unsigned int refclk; /* disp. reference clock */ 79 unsigned int refclk; /* disp. reference clock */
58 struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */ 80 struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */
59 int pre_init; /* don't init display if 1 */ 81 int pre_init; /* don't init display if 1 */
82 struct i2c_adapter *adap; /* GDC I2C bus adapter */
83 int i2c_rs;
84
85 struct mb862xx_l1_cfg l1_cfg;
86 int l1_stride;
60 87
61 u32 pseudo_palette[16]; 88 u32 pseudo_palette[16];
62}; 89};
63 90
64extern void mb862xxfb_init_accel(struct fb_info *info, int xres); 91extern void mb862xxfb_init_accel(struct fb_info *info, int xres);
92#ifdef CONFIG_FB_MB862XX_I2C
93extern int mb862xx_i2c_init(struct mb862xxfb_par *par);
94extern void mb862xx_i2c_exit(struct mb862xxfb_par *par);
95#else
96static inline int mb862xx_i2c_init(struct mb862xxfb_par *par) { return 0; }
97static inline void mb862xx_i2c_exit(struct mb862xxfb_par *par) { }
98#endif
65 99
66#if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) 100#if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC)
67#error "Select Lime GDC or CoralP/Carmine support, but not both together" 101#error "Select Lime GDC or CoralP/Carmine support, but not both together"
@@ -82,4 +116,6 @@ extern void mb862xxfb_init_accel(struct fb_info *info, int xres);
82 116
83#define pack(a, b) (((a) << 16) | (b)) 117#define pack(a, b) (((a) << 16) | (b))
84 118
119#endif /* __KERNEL__ */
120
85#endif 121#endif
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index c76e663a6cd4..ea39336addfb 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -27,7 +27,7 @@
27 27
28#define NR_PALETTE 256 28#define NR_PALETTE 256
29#define MB862XX_MEM_SIZE 0x1000000 29#define MB862XX_MEM_SIZE 0x1000000
30#define CORALP_MEM_SIZE 0x4000000 30#define CORALP_MEM_SIZE 0x2000000
31#define CARMINE_MEM_SIZE 0x8000000 31#define CARMINE_MEM_SIZE 0x8000000
32#define DRV_NAME "mb862xxfb" 32#define DRV_NAME "mb862xxfb"
33 33
@@ -309,6 +309,97 @@ static int mb862xxfb_blank(int mode, struct fb_info *fbi)
309 return 0; 309 return 0;
310} 310}
311 311
312static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd,
313 unsigned long arg)
314{
315 struct mb862xxfb_par *par = fbi->par;
316 struct mb862xx_l1_cfg *l1_cfg = &par->l1_cfg;
317 void __user *argp = (void __user *)arg;
318 int *enable;
319 u32 l1em = 0;
320
321 switch (cmd) {
322 case MB862XX_L1_GET_CFG:
323 if (copy_to_user(argp, l1_cfg, sizeof(*l1_cfg)))
324 return -EFAULT;
325 break;
326 case MB862XX_L1_SET_CFG:
327 if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg)))
328 return -EFAULT;
329 if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) {
330 /* downscaling */
331 outreg(cap, GC_CAP_CSC,
332 pack((l1_cfg->sh << 11) / l1_cfg->dh,
333 (l1_cfg->sw << 11) / l1_cfg->dw));
334 l1em = inreg(disp, GC_L1EM);
335 l1em &= ~GC_L1EM_DM;
336 } else if ((l1_cfg->sw <= l1_cfg->dw) &&
337 (l1_cfg->sh <= l1_cfg->dh)) {
338 /* upscaling */
339 outreg(cap, GC_CAP_CSC,
340 pack((l1_cfg->sh << 11) / l1_cfg->dh,
341 (l1_cfg->sw << 11) / l1_cfg->dw));
342 outreg(cap, GC_CAP_CMSS,
343 pack(l1_cfg->sw >> 1, l1_cfg->sh));
344 outreg(cap, GC_CAP_CMDS,
345 pack(l1_cfg->dw >> 1, l1_cfg->dh));
346 l1em = inreg(disp, GC_L1EM);
347 l1em |= GC_L1EM_DM;
348 }
349
350 if (l1_cfg->mirror) {
351 outreg(cap, GC_CAP_CBM,
352 inreg(cap, GC_CAP_CBM) | GC_CBM_HRV);
353 l1em |= l1_cfg->dw * 2 - 8;
354 } else {
355 outreg(cap, GC_CAP_CBM,
356 inreg(cap, GC_CAP_CBM) & ~GC_CBM_HRV);
357 l1em &= 0xffff0000;
358 }
359 outreg(disp, GC_L1EM, l1em);
360 break;
361 case MB862XX_L1_ENABLE:
362 enable = (int *)arg;
363 if (*enable) {
364 outreg(disp, GC_L1DA, par->cap_buf);
365 outreg(cap, GC_CAP_IMG_START,
366 pack(l1_cfg->sy >> 1, l1_cfg->sx));
367 outreg(cap, GC_CAP_IMG_END,
368 pack(l1_cfg->sh, l1_cfg->sw));
369 outreg(disp, GC_L1M, GC_L1M_16 | GC_L1M_YC | GC_L1M_CS |
370 (par->l1_stride << 16));
371 outreg(disp, GC_L1WY_L1WX,
372 pack(l1_cfg->dy, l1_cfg->dx));
373 outreg(disp, GC_L1WH_L1WW,
374 pack(l1_cfg->dh - 1, l1_cfg->dw));
375 outreg(disp, GC_DLS, 1);
376 outreg(cap, GC_CAP_VCM,
377 GC_VCM_VIE | GC_VCM_CM | GC_VCM_VS_PAL);
378 outreg(disp, GC_DCM1, inreg(disp, GC_DCM1) |
379 GC_DCM1_DEN | GC_DCM1_L1E);
380 } else {
381 outreg(cap, GC_CAP_VCM,
382 inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE);
383 outreg(disp, GC_DCM1,
384 inreg(disp, GC_DCM1) & ~GC_DCM1_L1E);
385 }
386 break;
387 case MB862XX_L1_CAP_CTL:
388 enable = (int *)arg;
389 if (*enable) {
390 outreg(cap, GC_CAP_VCM,
391 inreg(cap, GC_CAP_VCM) | GC_VCM_VIE);
392 } else {
393 outreg(cap, GC_CAP_VCM,
394 inreg(cap, GC_CAP_VCM) & ~GC_VCM_VIE);
395 }
396 break;
397 default:
398 return -EINVAL;
399 }
400 return 0;
401}
402
312/* framebuffer ops */ 403/* framebuffer ops */
313static struct fb_ops mb862xxfb_ops = { 404static struct fb_ops mb862xxfb_ops = {
314 .owner = THIS_MODULE, 405 .owner = THIS_MODULE,
@@ -320,6 +411,7 @@ static struct fb_ops mb862xxfb_ops = {
320 .fb_fillrect = cfb_fillrect, 411 .fb_fillrect = cfb_fillrect,
321 .fb_copyarea = cfb_copyarea, 412 .fb_copyarea = cfb_copyarea,
322 .fb_imageblit = cfb_imageblit, 413 .fb_imageblit = cfb_imageblit,
414 .fb_ioctl = mb862xxfb_ioctl,
323}; 415};
324 416
325/* initialize fb_info data */ 417/* initialize fb_info data */
@@ -328,6 +420,7 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
328 struct mb862xxfb_par *par = fbi->par; 420 struct mb862xxfb_par *par = fbi->par;
329 struct mb862xx_gc_mode *mode = par->gc_mode; 421 struct mb862xx_gc_mode *mode = par->gc_mode;
330 unsigned long reg; 422 unsigned long reg;
423 int stride;
331 424
332 fbi->fbops = &mb862xxfb_ops; 425 fbi->fbops = &mb862xxfb_ops;
333 fbi->pseudo_palette = par->pseudo_palette; 426 fbi->pseudo_palette = par->pseudo_palette;
@@ -336,7 +429,6 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
336 429
337 strcpy(fbi->fix.id, DRV_NAME); 430 strcpy(fbi->fix.id, DRV_NAME);
338 fbi->fix.smem_start = (unsigned long)par->fb_base_phys; 431 fbi->fix.smem_start = (unsigned long)par->fb_base_phys;
339 fbi->fix.smem_len = par->mapped_vram;
340 fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; 432 fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys;
341 fbi->fix.mmio_len = par->mmio_len; 433 fbi->fix.mmio_len = par->mmio_len;
342 fbi->fix.accel = FB_ACCEL_NONE; 434 fbi->fix.accel = FB_ACCEL_NONE;
@@ -420,6 +512,28 @@ static int mb862xxfb_init_fbinfo(struct fb_info *fbi)
420 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 512 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
421 fbi->fix.line_length = (fbi->var.xres_virtual * 513 fbi->fix.line_length = (fbi->var.xres_virtual *
422 fbi->var.bits_per_pixel) / 8; 514 fbi->var.bits_per_pixel) / 8;
515 fbi->fix.smem_len = fbi->fix.line_length * fbi->var.yres_virtual;
516
517 /*
518 * reserve space for capture buffers and two cursors
519 * at the end of vram: 720x576 * 2 * 2.2 + 64x64 * 16.
520 */
521 par->cap_buf = par->mapped_vram - 0x1bd800 - 0x10000;
522 par->cap_len = 0x1bd800;
523 par->l1_cfg.sx = 0;
524 par->l1_cfg.sy = 0;
525 par->l1_cfg.sw = 720;
526 par->l1_cfg.sh = 576;
527 par->l1_cfg.dx = 0;
528 par->l1_cfg.dy = 0;
529 par->l1_cfg.dw = 720;
530 par->l1_cfg.dh = 576;
531 stride = par->l1_cfg.sw * (fbi->var.bits_per_pixel / 8);
532 par->l1_stride = stride / 64 + ((stride % 64) ? 1 : 0);
533 outreg(cap, GC_CAP_CBM, GC_CBM_OO | GC_CBM_CBST |
534 (par->l1_stride << 16));
535 outreg(cap, GC_CAP_CBOA, par->cap_buf);
536 outreg(cap, GC_CAP_CBLA, par->cap_buf + par->cap_len);
423 return 0; 537 return 0;
424} 538}
425 539
@@ -742,22 +856,38 @@ static int coralp_init(struct mb862xxfb_par *par)
742 856
743 par->refclk = GC_DISP_REFCLK_400; 857 par->refclk = GC_DISP_REFCLK_400;
744 858
859 if (par->mapped_vram >= 0x2000000) {
860 /* relocate gdc registers space */
861 writel(1, par->fb_base + MB862XX_MMIO_BASE + GC_RSW);
862 udelay(1); /* wait at least 20 bus cycles */
863 }
864
745 ver = inreg(host, GC_CID); 865 ver = inreg(host, GC_CID);
746 cn = (ver & GC_CID_CNAME_MSK) >> 8; 866 cn = (ver & GC_CID_CNAME_MSK) >> 8;
747 ver = ver & GC_CID_VERSION_MSK; 867 ver = ver & GC_CID_VERSION_MSK;
748 if (cn == 3) { 868 if (cn == 3) {
869 unsigned long reg;
870
749 dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ 871 dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\
750 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", 872 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?",
751 par->pdev->revision); 873 par->pdev->revision);
752 outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); 874 reg = inreg(disp, GC_DCM1);
753 udelay(200); 875 if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E)
754 outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); 876 par->pre_init = 1;
755 udelay(10); 877
878 if (!par->pre_init) {
879 outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133);
880 udelay(200);
881 outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL);
882 udelay(10);
883 }
756 /* Clear interrupt status */ 884 /* Clear interrupt status */
757 outreg(host, GC_IST, 0); 885 outreg(host, GC_IST, 0);
758 } else { 886 } else {
759 return -ENODEV; 887 return -ENODEV;
760 } 888 }
889
890 mb862xx_i2c_init(par);
761 return 0; 891 return 0;
762} 892}
763 893
@@ -899,7 +1029,13 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,
899 case PCI_DEVICE_ID_FUJITSU_CORALPA: 1029 case PCI_DEVICE_ID_FUJITSU_CORALPA:
900 par->fb_base_phys = pci_resource_start(par->pdev, 0); 1030 par->fb_base_phys = pci_resource_start(par->pdev, 0);
901 par->mapped_vram = CORALP_MEM_SIZE; 1031 par->mapped_vram = CORALP_MEM_SIZE;
902 par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE; 1032 if (par->mapped_vram >= 0x2000000) {
1033 par->mmio_base_phys = par->fb_base_phys +
1034 MB862XX_MMIO_HIGH_BASE;
1035 } else {
1036 par->mmio_base_phys = par->fb_base_phys +
1037 MB862XX_MMIO_BASE;
1038 }
903 par->mmio_len = MB862XX_MMIO_SIZE; 1039 par->mmio_len = MB862XX_MMIO_SIZE;
904 par->type = BT_CORALP; 1040 par->type = BT_CORALP;
905 break; 1041 break;
@@ -1009,6 +1145,8 @@ static void __devexit mb862xx_pci_remove(struct pci_dev *pdev)
1009 outreg(host, GC_IMASK, 0); 1145 outreg(host, GC_IMASK, 0);
1010 } 1146 }
1011 1147
1148 mb862xx_i2c_exit(par);
1149
1012 device_remove_file(&pdev->dev, &dev_attr_dispregs); 1150 device_remove_file(&pdev->dev, &dev_attr_dispregs);
1013 1151
1014 pci_set_drvdata(pdev, NULL); 1152 pci_set_drvdata(pdev, NULL);
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 529483467abf..0ccd7adf47bb 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -922,14 +922,14 @@ static int get_dss_clocks(void)
922 return PTR_ERR(dispc.dss_ick); 922 return PTR_ERR(dispc.dss_ick);
923 } 923 }
924 924
925 dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); 925 dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "fck");
926 if (IS_ERR(dispc.dss1_fck)) { 926 if (IS_ERR(dispc.dss1_fck)) {
927 dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); 927 dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
928 clk_put(dispc.dss_ick); 928 clk_put(dispc.dss_ick);
929 return PTR_ERR(dispc.dss1_fck); 929 return PTR_ERR(dispc.dss1_fck);
930 } 930 }
931 931
932 dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_fck"); 932 dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_clk");
933 if (IS_ERR(dispc.dss_54m_fck)) { 933 if (IS_ERR(dispc.dss_54m_fck)) {
934 dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); 934 dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
935 clk_put(dispc.dss_ick); 935 clk_put(dispc.dss_ick);
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index e264efd0278f..b3ddd743d8a6 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -90,7 +90,7 @@ static void omapdss_release(struct device *dev)
90 90
91/* dummy device for clocks */ 91/* dummy device for clocks */
92static struct platform_device omapdss_device = { 92static struct platform_device omapdss_device = {
93 .name = "omapdss", 93 .name = "omapdss_dss",
94 .id = -1, 94 .id = -1,
95 .dev = { 95 .dev = {
96 .release = omapdss_release, 96 .release = omapdss_release,
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index eada9f12efc7..0c6981f1a4a3 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -90,7 +90,7 @@ static int rfbi_get_clocks(void)
90 return PTR_ERR(rfbi.dss_ick); 90 return PTR_ERR(rfbi.dss_ick);
91 } 91 }
92 92
93 rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck"); 93 rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "fck");
94 if (IS_ERR(rfbi.dss1_fck)) { 94 if (IS_ERR(rfbi.dss1_fck)) {
95 dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); 95 dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
96 clk_put(rfbi.dss_ick); 96 clk_put(rfbi.dss_ick);
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index d853d05dad31..5ddef129f798 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_OMAP2_VRAM) += vram.o 1obj-$(CONFIG_OMAP2_VRAM) += vram.o
2obj-$(CONFIG_OMAP2_VRFB) += vrfb.o 2obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
3 3
4obj-y += dss/ 4obj-$(CONFIG_OMAP2_DSS) += dss/
5obj-y += omapfb/ 5obj-$(CONFIG_FB_OMAP2) += omapfb/
6obj-y += displays/ 6obj-y += displays/
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index d18ad6b2372a..609a28073178 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -3,6 +3,7 @@ menu "OMAP2/3 Display Device Drivers"
3 3
4config PANEL_GENERIC_DPI 4config PANEL_GENERIC_DPI
5 tristate "Generic DPI Panel" 5 tristate "Generic DPI Panel"
6 depends on OMAP2_DSS_DPI
6 help 7 help
7 Generic DPI panel driver. 8 Generic DPI panel driver.
8 Supports DVI output for Beagle and OMAP3 SDP. 9 Supports DVI output for Beagle and OMAP3 SDP.
@@ -11,20 +12,20 @@ config PANEL_GENERIC_DPI
11 12
12config PANEL_LGPHILIPS_LB035Q02 13config PANEL_LGPHILIPS_LB035Q02
13 tristate "LG.Philips LB035Q02 LCD Panel" 14 tristate "LG.Philips LB035Q02 LCD Panel"
14 depends on OMAP2_DSS && SPI 15 depends on OMAP2_DSS_DPI && SPI
15 help 16 help
16 LCD Panel used on the Gumstix Overo Palo35 17 LCD Panel used on the Gumstix Overo Palo35
17 18
18config PANEL_SHARP_LS037V7DW01 19config PANEL_SHARP_LS037V7DW01
19 tristate "Sharp LS037V7DW01 LCD Panel" 20 tristate "Sharp LS037V7DW01 LCD Panel"
20 depends on OMAP2_DSS 21 depends on OMAP2_DSS_DPI
21 select BACKLIGHT_CLASS_DEVICE 22 select BACKLIGHT_CLASS_DEVICE
22 help 23 help
23 LCD Panel used in TI's SDP3430 and EVM boards 24 LCD Panel used in TI's SDP3430 and EVM boards
24 25
25config PANEL_NEC_NL8048HL11_01B 26config PANEL_NEC_NL8048HL11_01B
26 tristate "NEC NL8048HL11-01B Panel" 27 tristate "NEC NL8048HL11-01B Panel"
27 depends on OMAP2_DSS 28 depends on OMAP2_DSS_DPI
28 help 29 help
29 This NEC NL8048HL11-01B panel is TFT LCD 30 This NEC NL8048HL11-01B panel is TFT LCD
30 used in the Zoom2/3/3630 sdp boards. 31 used in the Zoom2/3/3630 sdp boards.
@@ -37,7 +38,7 @@ config PANEL_TAAL
37 38
38config PANEL_TPO_TD043MTEA1 39config PANEL_TPO_TD043MTEA1
39 tristate "TPO TD043MTEA1 LCD Panel" 40 tristate "TPO TD043MTEA1 LCD Panel"
40 depends on OMAP2_DSS && SPI 41 depends on OMAP2_DSS_DPI && SPI
41 help 42 help
42 LCD Panel used in OMAP3 Pandora 43 LCD Panel used in OMAP3 Pandora
43 44
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 7e04c921aa2a..dbd59b8e5b36 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -30,7 +30,7 @@
30#include <linux/backlight.h> 30#include <linux/backlight.h>
31#include <linux/fb.h> 31#include <linux/fb.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34 34
35#define MIPID_CMD_READ_DISP_ID 0x04 35#define MIPID_CMD_READ_DISP_ID 0x04
36#define MIPID_CMD_READ_RED 0x06 36#define MIPID_CMD_READ_RED 0x06
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 4a9b9ff59467..9c90f75653fb 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -33,8 +33,9 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <video/omapdss.h>
36 37
37#include <plat/panel-generic-dpi.h> 38#include <video/omap-panel-generic-dpi.h>
38 39
39struct panel_config { 40struct panel_config {
40 struct omap_video_timings timings; 41 struct omap_video_timings timings;
@@ -181,6 +182,56 @@ static struct panel_config generic_dpi_panels[] = {
181 .power_off_delay = 0, 182 .power_off_delay = 0,
182 .name = "samsung_lte430wq_f0c", 183 .name = "samsung_lte430wq_f0c",
183 }, 184 },
185
186 /* Seiko 70WVW1TZ3Z3 */
187 {
188 {
189 .x_res = 800,
190 .y_res = 480,
191
192 .pixel_clock = 33000,
193
194 .hsw = 128,
195 .hfp = 10,
196 .hbp = 10,
197
198 .vsw = 2,
199 .vfp = 4,
200 .vbp = 11,
201 },
202 .acbi = 0x0,
203 .acb = 0x0,
204 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
205 OMAP_DSS_LCD_IHS,
206 .power_on_delay = 0,
207 .power_off_delay = 0,
208 .name = "seiko_70wvw1tz3",
209 },
210
211 /* Powertip PH480272T */
212 {
213 {
214 .x_res = 480,
215 .y_res = 272,
216
217 .pixel_clock = 9000,
218
219 .hsw = 40,
220 .hfp = 2,
221 .hbp = 2,
222
223 .vsw = 10,
224 .vfp = 2,
225 .vbp = 2,
226 },
227 .acbi = 0x0,
228 .acb = 0x0,
229 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
230 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO,
231 .power_on_delay = 0,
232 .power_off_delay = 0,
233 .name = "powertip_ph480272t",
234 },
184}; 235};
185 236
186struct panel_drv_data { 237struct panel_drv_data {
@@ -285,7 +336,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
285 return 0; 336 return 0;
286} 337}
287 338
288static void generic_dpi_panel_remove(struct omap_dss_device *dssdev) 339static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
289{ 340{
290 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 341 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
291 342
@@ -358,7 +409,7 @@ static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
358 409
359static struct omap_dss_driver dpi_driver = { 410static struct omap_dss_driver dpi_driver = {
360 .probe = generic_dpi_panel_probe, 411 .probe = generic_dpi_panel_probe,
361 .remove = generic_dpi_panel_remove, 412 .remove = __exit_p(generic_dpi_panel_remove),
362 413
363 .enable = generic_dpi_panel_enable, 414 .enable = generic_dpi_panel_enable,
364 .disable = generic_dpi_panel_disable, 415 .disable = generic_dpi_panel_disable,
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 271324db2436..e0eb35be303e 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -21,7 +21,7 @@
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23 23
24#include <plat/display.h> 24#include <video/omapdss.h>
25 25
26struct lb035q02_data { 26struct lb035q02_data {
27 struct mutex lock; 27 struct mutex lock;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 925e0fadff54..2ba9d0ca187c 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -22,7 +22,7 @@
22#include <linux/backlight.h> 22#include <linux/backlight.h>
23#include <linux/fb.h> 23#include <linux/fb.h>
24 24
25#include <plat/display.h> 25#include <video/omapdss.h>
26 26
27#define LCD_XRES 800 27#define LCD_XRES 800
28#define LCD_YRES 480 28#define LCD_YRES 480
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index d2b35d2df2a6..ba38b3ad17d6 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -25,7 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27 27
28#include <plat/display.h> 28#include <video/omapdss.h>
29 29
30struct sharp_data { 30struct sharp_data {
31 struct backlight_device *bl; 31 struct backlight_device *bl;
@@ -120,7 +120,7 @@ static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
120 return 0; 120 return 0;
121} 121}
122 122
123static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) 123static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
124{ 124{
125 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); 125 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
126 struct backlight_device *bl = sd->bl; 126 struct backlight_device *bl = sd->bl;
@@ -205,7 +205,7 @@ static int sharp_ls_panel_resume(struct omap_dss_device *dssdev)
205 205
206static struct omap_dss_driver sharp_ls_driver = { 206static struct omap_dss_driver sharp_ls_driver = {
207 .probe = sharp_ls_panel_probe, 207 .probe = sharp_ls_panel_probe,
208 .remove = sharp_ls_panel_remove, 208 .remove = __exit_p(sharp_ls_panel_remove),
209 209
210 .enable = sharp_ls_panel_enable, 210 .enable = sharp_ls_panel_enable,
211 .disable = sharp_ls_panel_disable, 211 .disable = sharp_ls_panel_disable,
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index adc9900458e1..fdd5d4ae437d 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -33,8 +33,8 @@
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35 35
36#include <plat/display.h> 36#include <video/omapdss.h>
37#include <plat/nokia-dsi-panel.h> 37#include <video/omap-panel-nokia-dsi.h>
38 38
39/* DSI Virtual channel. Hardcoded for now. */ 39/* DSI Virtual channel. Hardcoded for now. */
40#define TCH 0 40#define TCH 0
@@ -63,12 +63,12 @@
63#define DCS_GET_ID2 0xdb 63#define DCS_GET_ID2 0xdb
64#define DCS_GET_ID3 0xdc 64#define DCS_GET_ID3 0xdc
65 65
66#define TAAL_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
67
68static irqreturn_t taal_te_isr(int irq, void *data); 66static irqreturn_t taal_te_isr(int irq, void *data);
69static void taal_te_timeout_work_callback(struct work_struct *work); 67static void taal_te_timeout_work_callback(struct work_struct *work);
70static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 68static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
71 69
70static int taal_panel_reset(struct omap_dss_device *dssdev);
71
72struct panel_regulator { 72struct panel_regulator {
73 struct regulator *regulator; 73 struct regulator *regulator;
74 const char *name; 74 const char *name;
@@ -229,8 +229,14 @@ struct taal_data {
229 229
230 bool intro_printed; 230 bool intro_printed;
231 231
232 struct workqueue_struct *esd_wq; 232 struct workqueue_struct *workqueue;
233
233 struct delayed_work esd_work; 234 struct delayed_work esd_work;
235 unsigned esd_interval;
236
237 bool ulps_enabled;
238 unsigned ulps_timeout;
239 struct delayed_work ulps_work;
234 240
235 struct panel_config *panel_config; 241 struct panel_config *panel_config;
236}; 242};
@@ -242,6 +248,7 @@ static inline struct nokia_dsi_panel_data
242} 248}
243 249
244static void taal_esd_work(struct work_struct *work); 250static void taal_esd_work(struct work_struct *work);
251static void taal_ulps_work(struct work_struct *work);
245 252
246static void hw_guard_start(struct taal_data *td, int guard_msec) 253static void hw_guard_start(struct taal_data *td, int guard_msec)
247{ 254{
@@ -264,7 +271,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
264 int r; 271 int r;
265 u8 buf[1]; 272 u8 buf[1];
266 273
267 r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1); 274 r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
268 275
269 if (r < 0) 276 if (r < 0)
270 return r; 277 return r;
@@ -276,7 +283,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
276 283
277static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd) 284static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
278{ 285{
279 return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1); 286 return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
280} 287}
281 288
282static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param) 289static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
@@ -284,7 +291,7 @@ static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
284 u8 buf[2]; 291 u8 buf[2];
285 buf[0] = dcs_cmd; 292 buf[0] = dcs_cmd;
286 buf[1] = param; 293 buf[1] = param;
287 return dsi_vc_dcs_write(td->channel, buf, 2); 294 return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
288} 295}
289 296
290static int taal_sleep_in(struct taal_data *td) 297static int taal_sleep_in(struct taal_data *td)
@@ -296,7 +303,7 @@ static int taal_sleep_in(struct taal_data *td)
296 hw_guard_wait(td); 303 hw_guard_wait(td);
297 304
298 cmd = DCS_SLEEP_IN; 305 cmd = DCS_SLEEP_IN;
299 r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1); 306 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
300 if (r) 307 if (r)
301 return r; 308 return r;
302 309
@@ -402,7 +409,7 @@ static int taal_set_update_window(struct taal_data *td,
402 buf[3] = (x2 >> 8) & 0xff; 409 buf[3] = (x2 >> 8) & 0xff;
403 buf[4] = (x2 >> 0) & 0xff; 410 buf[4] = (x2 >> 0) & 0xff;
404 411
405 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf)); 412 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
406 if (r) 413 if (r)
407 return r; 414 return r;
408 415
@@ -412,15 +419,132 @@ static int taal_set_update_window(struct taal_data *td,
412 buf[3] = (y2 >> 8) & 0xff; 419 buf[3] = (y2 >> 8) & 0xff;
413 buf[4] = (y2 >> 0) & 0xff; 420 buf[4] = (y2 >> 0) & 0xff;
414 421
415 r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf)); 422 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
416 if (r) 423 if (r)
417 return r; 424 return r;
418 425
419 dsi_vc_send_bta_sync(td->channel); 426 dsi_vc_send_bta_sync(td->dssdev, td->channel);
420 427
421 return r; 428 return r;
422} 429}
423 430
431static void taal_queue_esd_work(struct omap_dss_device *dssdev)
432{
433 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
434
435 if (td->esd_interval > 0)
436 queue_delayed_work(td->workqueue, &td->esd_work,
437 msecs_to_jiffies(td->esd_interval));
438}
439
440static void taal_cancel_esd_work(struct omap_dss_device *dssdev)
441{
442 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
443
444 cancel_delayed_work(&td->esd_work);
445}
446
447static void taal_queue_ulps_work(struct omap_dss_device *dssdev)
448{
449 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
450
451 if (td->ulps_timeout > 0)
452 queue_delayed_work(td->workqueue, &td->ulps_work,
453 msecs_to_jiffies(td->ulps_timeout));
454}
455
456static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
457{
458 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
459
460 cancel_delayed_work(&td->ulps_work);
461}
462
463static int taal_enter_ulps(struct omap_dss_device *dssdev)
464{
465 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
466 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
467 int r;
468
469 if (td->ulps_enabled)
470 return 0;
471
472 taal_cancel_ulps_work(dssdev);
473
474 r = _taal_enable_te(dssdev, false);
475 if (r)
476 goto err;
477
478 disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
479
480 omapdss_dsi_display_disable(dssdev, false, true);
481
482 td->ulps_enabled = true;
483
484 return 0;
485
486err:
487 dev_err(&dssdev->dev, "enter ULPS failed");
488 taal_panel_reset(dssdev);
489
490 td->ulps_enabled = false;
491
492 taal_queue_ulps_work(dssdev);
493
494 return r;
495}
496
497static int taal_exit_ulps(struct omap_dss_device *dssdev)
498{
499 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
500 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
501 int r;
502
503 if (!td->ulps_enabled)
504 return 0;
505
506 r = omapdss_dsi_display_enable(dssdev);
507 if (r)
508 goto err;
509
510 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
511
512 r = _taal_enable_te(dssdev, true);
513 if (r)
514 goto err;
515
516 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
517
518 taal_queue_ulps_work(dssdev);
519
520 td->ulps_enabled = false;
521
522 return 0;
523
524err:
525 dev_err(&dssdev->dev, "exit ULPS failed");
526 r = taal_panel_reset(dssdev);
527
528 enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
529 td->ulps_enabled = false;
530
531 taal_queue_ulps_work(dssdev);
532
533 return r;
534}
535
536static int taal_wake_up(struct omap_dss_device *dssdev)
537{
538 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
539
540 if (td->ulps_enabled)
541 return taal_exit_ulps(dssdev);
542
543 taal_cancel_ulps_work(dssdev);
544 taal_queue_ulps_work(dssdev);
545 return 0;
546}
547
424static int taal_bl_update_status(struct backlight_device *dev) 548static int taal_bl_update_status(struct backlight_device *dev)
425{ 549{
426 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); 550 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
@@ -441,9 +565,13 @@ static int taal_bl_update_status(struct backlight_device *dev)
441 565
442 if (td->use_dsi_bl) { 566 if (td->use_dsi_bl) {
443 if (td->enabled) { 567 if (td->enabled) {
444 dsi_bus_lock(); 568 dsi_bus_lock(dssdev);
445 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level); 569
446 dsi_bus_unlock(); 570 r = taal_wake_up(dssdev);
571 if (!r)
572 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
573
574 dsi_bus_unlock(dssdev);
447 } else { 575 } else {
448 r = 0; 576 r = 0;
449 } 577 }
@@ -504,9 +632,13 @@ static ssize_t taal_num_errors_show(struct device *dev,
504 mutex_lock(&td->lock); 632 mutex_lock(&td->lock);
505 633
506 if (td->enabled) { 634 if (td->enabled) {
507 dsi_bus_lock(); 635 dsi_bus_lock(dssdev);
508 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors); 636
509 dsi_bus_unlock(); 637 r = taal_wake_up(dssdev);
638 if (!r)
639 r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
640
641 dsi_bus_unlock(dssdev);
510 } else { 642 } else {
511 r = -ENODEV; 643 r = -ENODEV;
512 } 644 }
@@ -530,9 +662,13 @@ static ssize_t taal_hw_revision_show(struct device *dev,
530 mutex_lock(&td->lock); 662 mutex_lock(&td->lock);
531 663
532 if (td->enabled) { 664 if (td->enabled) {
533 dsi_bus_lock(); 665 dsi_bus_lock(dssdev);
534 r = taal_get_id(td, &id1, &id2, &id3); 666
535 dsi_bus_unlock(); 667 r = taal_wake_up(dssdev);
668 if (!r)
669 r = taal_get_id(td, &id1, &id2, &id3);
670
671 dsi_bus_unlock(dssdev);
536 } else { 672 } else {
537 r = -ENODEV; 673 r = -ENODEV;
538 } 674 }
@@ -579,6 +715,7 @@ static ssize_t store_cabc_mode(struct device *dev,
579 struct omap_dss_device *dssdev = to_dss_device(dev); 715 struct omap_dss_device *dssdev = to_dss_device(dev);
580 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 716 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
581 int i; 717 int i;
718 int r;
582 719
583 for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { 720 for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
584 if (sysfs_streq(cabc_modes[i], buf)) 721 if (sysfs_streq(cabc_modes[i], buf))
@@ -591,10 +728,19 @@ static ssize_t store_cabc_mode(struct device *dev,
591 mutex_lock(&td->lock); 728 mutex_lock(&td->lock);
592 729
593 if (td->enabled) { 730 if (td->enabled) {
594 dsi_bus_lock(); 731 dsi_bus_lock(dssdev);
595 if (!td->cabc_broken) 732
596 taal_dcs_write_1(td, DCS_WRITE_CABC, i); 733 if (!td->cabc_broken) {
597 dsi_bus_unlock(); 734 r = taal_wake_up(dssdev);
735 if (r)
736 goto err;
737
738 r = taal_dcs_write_1(td, DCS_WRITE_CABC, i);
739 if (r)
740 goto err;
741 }
742
743 dsi_bus_unlock(dssdev);
598 } 744 }
599 745
600 td->cabc_mode = i; 746 td->cabc_mode = i;
@@ -602,6 +748,10 @@ static ssize_t store_cabc_mode(struct device *dev,
602 mutex_unlock(&td->lock); 748 mutex_unlock(&td->lock);
603 749
604 return count; 750 return count;
751err:
752 dsi_bus_unlock(dssdev);
753 mutex_unlock(&td->lock);
754 return r;
605} 755}
606 756
607static ssize_t show_cabc_available_modes(struct device *dev, 757static ssize_t show_cabc_available_modes(struct device *dev,
@@ -620,18 +770,161 @@ static ssize_t show_cabc_available_modes(struct device *dev,
620 return len < PAGE_SIZE ? len : PAGE_SIZE - 1; 770 return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
621} 771}
622 772
773static ssize_t taal_store_esd_interval(struct device *dev,
774 struct device_attribute *attr,
775 const char *buf, size_t count)
776{
777 struct omap_dss_device *dssdev = to_dss_device(dev);
778 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
779
780 unsigned long t;
781 int r;
782
783 r = strict_strtoul(buf, 10, &t);
784 if (r)
785 return r;
786
787 mutex_lock(&td->lock);
788 taal_cancel_esd_work(dssdev);
789 td->esd_interval = t;
790 if (td->enabled)
791 taal_queue_esd_work(dssdev);
792 mutex_unlock(&td->lock);
793
794 return count;
795}
796
797static ssize_t taal_show_esd_interval(struct device *dev,
798 struct device_attribute *attr,
799 char *buf)
800{
801 struct omap_dss_device *dssdev = to_dss_device(dev);
802 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
803 unsigned t;
804
805 mutex_lock(&td->lock);
806 t = td->esd_interval;
807 mutex_unlock(&td->lock);
808
809 return snprintf(buf, PAGE_SIZE, "%u\n", t);
810}
811
812static ssize_t taal_store_ulps(struct device *dev,
813 struct device_attribute *attr,
814 const char *buf, size_t count)
815{
816 struct omap_dss_device *dssdev = to_dss_device(dev);
817 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
818 unsigned long t;
819 int r;
820
821 r = strict_strtoul(buf, 10, &t);
822 if (r)
823 return r;
824
825 mutex_lock(&td->lock);
826
827 if (td->enabled) {
828 dsi_bus_lock(dssdev);
829
830 if (t)
831 r = taal_enter_ulps(dssdev);
832 else
833 r = taal_wake_up(dssdev);
834
835 dsi_bus_unlock(dssdev);
836 }
837
838 mutex_unlock(&td->lock);
839
840 if (r)
841 return r;
842
843 return count;
844}
845
846static ssize_t taal_show_ulps(struct device *dev,
847 struct device_attribute *attr,
848 char *buf)
849{
850 struct omap_dss_device *dssdev = to_dss_device(dev);
851 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
852 unsigned t;
853
854 mutex_lock(&td->lock);
855 t = td->ulps_enabled;
856 mutex_unlock(&td->lock);
857
858 return snprintf(buf, PAGE_SIZE, "%u\n", t);
859}
860
861static ssize_t taal_store_ulps_timeout(struct device *dev,
862 struct device_attribute *attr,
863 const char *buf, size_t count)
864{
865 struct omap_dss_device *dssdev = to_dss_device(dev);
866 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
867 unsigned long t;
868 int r;
869
870 r = strict_strtoul(buf, 10, &t);
871 if (r)
872 return r;
873
874 mutex_lock(&td->lock);
875 td->ulps_timeout = t;
876
877 if (td->enabled) {
878 /* taal_wake_up will restart the timer */
879 dsi_bus_lock(dssdev);
880 r = taal_wake_up(dssdev);
881 dsi_bus_unlock(dssdev);
882 }
883
884 mutex_unlock(&td->lock);
885
886 if (r)
887 return r;
888
889 return count;
890}
891
892static ssize_t taal_show_ulps_timeout(struct device *dev,
893 struct device_attribute *attr,
894 char *buf)
895{
896 struct omap_dss_device *dssdev = to_dss_device(dev);
897 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
898 unsigned t;
899
900 mutex_lock(&td->lock);
901 t = td->ulps_timeout;
902 mutex_unlock(&td->lock);
903
904 return snprintf(buf, PAGE_SIZE, "%u\n", t);
905}
906
623static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL); 907static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL);
624static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL); 908static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL);
625static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, 909static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
626 show_cabc_mode, store_cabc_mode); 910 show_cabc_mode, store_cabc_mode);
627static DEVICE_ATTR(cabc_available_modes, S_IRUGO, 911static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
628 show_cabc_available_modes, NULL); 912 show_cabc_available_modes, NULL);
913static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR,
914 taal_show_esd_interval, taal_store_esd_interval);
915static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
916 taal_show_ulps, taal_store_ulps);
917static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
918 taal_show_ulps_timeout, taal_store_ulps_timeout);
629 919
630static struct attribute *taal_attrs[] = { 920static struct attribute *taal_attrs[] = {
631 &dev_attr_num_dsi_errors.attr, 921 &dev_attr_num_dsi_errors.attr,
632 &dev_attr_hw_revision.attr, 922 &dev_attr_hw_revision.attr,
633 &dev_attr_cabc_mode.attr, 923 &dev_attr_cabc_mode.attr,
634 &dev_attr_cabc_available_modes.attr, 924 &dev_attr_cabc_available_modes.attr,
925 &dev_attr_esd_interval.attr,
926 &dev_attr_ulps.attr,
927 &dev_attr_ulps_timeout.attr,
635 NULL, 928 NULL,
636}; 929};
637 930
@@ -700,6 +993,9 @@ static int taal_probe(struct omap_dss_device *dssdev)
700 } 993 }
701 td->dssdev = dssdev; 994 td->dssdev = dssdev;
702 td->panel_config = panel_config; 995 td->panel_config = panel_config;
996 td->esd_interval = panel_data->esd_interval;
997 td->ulps_enabled = false;
998 td->ulps_timeout = panel_data->ulps_timeout;
703 999
704 mutex_init(&td->lock); 1000 mutex_init(&td->lock);
705 1001
@@ -710,13 +1006,14 @@ static int taal_probe(struct omap_dss_device *dssdev)
710 if (r) 1006 if (r)
711 goto err_reg; 1007 goto err_reg;
712 1008
713 td->esd_wq = create_singlethread_workqueue("taal_esd"); 1009 td->workqueue = create_singlethread_workqueue("taal_esd");
714 if (td->esd_wq == NULL) { 1010 if (td->workqueue == NULL) {
715 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 1011 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
716 r = -ENOMEM; 1012 r = -ENOMEM;
717 goto err_wq; 1013 goto err_wq;
718 } 1014 }
719 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); 1015 INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
1016 INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
720 1017
721 dev_set_drvdata(&dssdev->dev, td); 1018 dev_set_drvdata(&dssdev->dev, td);
722 1019
@@ -734,8 +1031,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
734 props.max_brightness = 127; 1031 props.max_brightness = 127;
735 1032
736 props.type = BACKLIGHT_RAW; 1033 props.type = BACKLIGHT_RAW;
737 bldev = backlight_device_register("taal", &dssdev->dev, dssdev, 1034 bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
738 &taal_bl_ops, &props); 1035 dssdev, &taal_bl_ops, &props);
739 if (IS_ERR(bldev)) { 1036 if (IS_ERR(bldev)) {
740 r = PTR_ERR(bldev); 1037 r = PTR_ERR(bldev);
741 goto err_bl; 1038 goto err_bl;
@@ -810,7 +1107,7 @@ err_irq:
810err_gpio: 1107err_gpio:
811 backlight_device_unregister(bldev); 1108 backlight_device_unregister(bldev);
812err_bl: 1109err_bl:
813 destroy_workqueue(td->esd_wq); 1110 destroy_workqueue(td->workqueue);
814err_wq: 1111err_wq:
815 free_regulators(panel_config->regulators, panel_config->num_regulators); 1112 free_regulators(panel_config->regulators, panel_config->num_regulators);
816err_reg: 1113err_reg:
@@ -819,7 +1116,7 @@ err:
819 return r; 1116 return r;
820} 1117}
821 1118
822static void taal_remove(struct omap_dss_device *dssdev) 1119static void __exit taal_remove(struct omap_dss_device *dssdev)
823{ 1120{
824 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1121 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
825 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); 1122 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
@@ -841,8 +1138,9 @@ static void taal_remove(struct omap_dss_device *dssdev)
841 taal_bl_update_status(bldev); 1138 taal_bl_update_status(bldev);
842 backlight_device_unregister(bldev); 1139 backlight_device_unregister(bldev);
843 1140
844 cancel_delayed_work(&td->esd_work); 1141 taal_cancel_ulps_work(dssdev);
845 destroy_workqueue(td->esd_wq); 1142 taal_cancel_esd_work(dssdev);
1143 destroy_workqueue(td->workqueue);
846 1144
847 /* reset, to be sure that the panel is in a valid state */ 1145 /* reset, to be sure that the panel is in a valid state */
848 taal_hw_reset(dssdev); 1146 taal_hw_reset(dssdev);
@@ -867,7 +1165,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
867 1165
868 taal_hw_reset(dssdev); 1166 taal_hw_reset(dssdev);
869 1167
870 omapdss_dsi_vc_enable_hs(td->channel, false); 1168 omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
871 1169
872 r = taal_sleep_out(td); 1170 r = taal_sleep_out(td);
873 if (r) 1171 if (r)
@@ -924,7 +1222,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
924 td->intro_printed = true; 1222 td->intro_printed = true;
925 } 1223 }
926 1224
927 omapdss_dsi_vc_enable_hs(td->channel, true); 1225 omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
928 1226
929 return 0; 1227 return 0;
930err: 1228err:
@@ -932,7 +1230,7 @@ err:
932 1230
933 taal_hw_reset(dssdev); 1231 taal_hw_reset(dssdev);
934 1232
935 omapdss_dsi_display_disable(dssdev); 1233 omapdss_dsi_display_disable(dssdev, true, false);
936err0: 1234err0:
937 return r; 1235 return r;
938} 1236}
@@ -955,15 +1253,23 @@ static void taal_power_off(struct omap_dss_device *dssdev)
955 taal_hw_reset(dssdev); 1253 taal_hw_reset(dssdev);
956 } 1254 }
957 1255
958 omapdss_dsi_display_disable(dssdev); 1256 omapdss_dsi_display_disable(dssdev, true, false);
959 1257
960 td->enabled = 0; 1258 td->enabled = 0;
961} 1259}
962 1260
1261static int taal_panel_reset(struct omap_dss_device *dssdev)
1262{
1263 dev_err(&dssdev->dev, "performing LCD reset\n");
1264
1265 taal_power_off(dssdev);
1266 taal_hw_reset(dssdev);
1267 return taal_power_on(dssdev);
1268}
1269
963static int taal_enable(struct omap_dss_device *dssdev) 1270static int taal_enable(struct omap_dss_device *dssdev)
964{ 1271{
965 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1272 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
966 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
967 int r; 1273 int r;
968 1274
969 dev_dbg(&dssdev->dev, "enable\n"); 1275 dev_dbg(&dssdev->dev, "enable\n");
@@ -975,18 +1281,16 @@ static int taal_enable(struct omap_dss_device *dssdev)
975 goto err; 1281 goto err;
976 } 1282 }
977 1283
978 dsi_bus_lock(); 1284 dsi_bus_lock(dssdev);
979 1285
980 r = taal_power_on(dssdev); 1286 r = taal_power_on(dssdev);
981 1287
982 dsi_bus_unlock(); 1288 dsi_bus_unlock(dssdev);
983 1289
984 if (r) 1290 if (r)
985 goto err; 1291 goto err;
986 1292
987 if (panel_data->use_esd_check) 1293 taal_queue_esd_work(dssdev);
988 queue_delayed_work(td->esd_wq, &td->esd_work,
989 TAAL_ESD_CHECK_PERIOD);
990 1294
991 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 1295 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
992 1296
@@ -1007,14 +1311,17 @@ static void taal_disable(struct omap_dss_device *dssdev)
1007 1311
1008 mutex_lock(&td->lock); 1312 mutex_lock(&td->lock);
1009 1313
1010 cancel_delayed_work(&td->esd_work); 1314 taal_cancel_ulps_work(dssdev);
1315 taal_cancel_esd_work(dssdev);
1011 1316
1012 dsi_bus_lock(); 1317 dsi_bus_lock(dssdev);
1013 1318
1014 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 1319 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
1320 taal_wake_up(dssdev);
1015 taal_power_off(dssdev); 1321 taal_power_off(dssdev);
1322 }
1016 1323
1017 dsi_bus_unlock(); 1324 dsi_bus_unlock(dssdev);
1018 1325
1019 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 1326 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1020 1327
@@ -1035,13 +1342,16 @@ static int taal_suspend(struct omap_dss_device *dssdev)
1035 goto err; 1342 goto err;
1036 } 1343 }
1037 1344
1038 cancel_delayed_work(&td->esd_work); 1345 taal_cancel_ulps_work(dssdev);
1346 taal_cancel_esd_work(dssdev);
1039 1347
1040 dsi_bus_lock(); 1348 dsi_bus_lock(dssdev);
1041 1349
1042 taal_power_off(dssdev); 1350 r = taal_wake_up(dssdev);
1351 if (!r)
1352 taal_power_off(dssdev);
1043 1353
1044 dsi_bus_unlock(); 1354 dsi_bus_unlock(dssdev);
1045 1355
1046 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 1356 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
1047 1357
@@ -1056,7 +1366,6 @@ err:
1056static int taal_resume(struct omap_dss_device *dssdev) 1366static int taal_resume(struct omap_dss_device *dssdev)
1057{ 1367{
1058 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1368 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1059 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1060 int r; 1369 int r;
1061 1370
1062 dev_dbg(&dssdev->dev, "resume\n"); 1371 dev_dbg(&dssdev->dev, "resume\n");
@@ -1068,19 +1377,17 @@ static int taal_resume(struct omap_dss_device *dssdev)
1068 goto err; 1377 goto err;
1069 } 1378 }
1070 1379
1071 dsi_bus_lock(); 1380 dsi_bus_lock(dssdev);
1072 1381
1073 r = taal_power_on(dssdev); 1382 r = taal_power_on(dssdev);
1074 1383
1075 dsi_bus_unlock(); 1384 dsi_bus_unlock(dssdev);
1076 1385
1077 if (r) { 1386 if (r) {
1078 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 1387 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
1079 } else { 1388 } else {
1080 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 1389 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
1081 if (panel_data->use_esd_check) 1390 taal_queue_esd_work(dssdev);
1082 queue_delayed_work(td->esd_wq, &td->esd_work,
1083 TAAL_ESD_CHECK_PERIOD);
1084 } 1391 }
1085 1392
1086 mutex_unlock(&td->lock); 1393 mutex_unlock(&td->lock);
@@ -1095,7 +1402,7 @@ static void taal_framedone_cb(int err, void *data)
1095{ 1402{
1096 struct omap_dss_device *dssdev = data; 1403 struct omap_dss_device *dssdev = data;
1097 dev_dbg(&dssdev->dev, "framedone, err %d\n", err); 1404 dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
1098 dsi_bus_unlock(); 1405 dsi_bus_unlock(dssdev);
1099} 1406}
1100 1407
1101static irqreturn_t taal_te_isr(int irq, void *data) 1408static irqreturn_t taal_te_isr(int irq, void *data)
@@ -1123,7 +1430,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
1123 return IRQ_HANDLED; 1430 return IRQ_HANDLED;
1124err: 1431err:
1125 dev_err(&dssdev->dev, "start update failed\n"); 1432 dev_err(&dssdev->dev, "start update failed\n");
1126 dsi_bus_unlock(); 1433 dsi_bus_unlock(dssdev);
1127 return IRQ_HANDLED; 1434 return IRQ_HANDLED;
1128} 1435}
1129 1436
@@ -1136,7 +1443,7 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
1136 dev_err(&dssdev->dev, "TE not received for 250ms!\n"); 1443 dev_err(&dssdev->dev, "TE not received for 250ms!\n");
1137 1444
1138 atomic_set(&td->do_update, 0); 1445 atomic_set(&td->do_update, 0);
1139 dsi_bus_unlock(); 1446 dsi_bus_unlock(dssdev);
1140} 1447}
1141 1448
1142static int taal_update(struct omap_dss_device *dssdev, 1449static int taal_update(struct omap_dss_device *dssdev,
@@ -1149,7 +1456,11 @@ static int taal_update(struct omap_dss_device *dssdev,
1149 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); 1456 dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
1150 1457
1151 mutex_lock(&td->lock); 1458 mutex_lock(&td->lock);
1152 dsi_bus_lock(); 1459 dsi_bus_lock(dssdev);
1460
1461 r = taal_wake_up(dssdev);
1462 if (r)
1463 goto err;
1153 1464
1154 if (!td->enabled) { 1465 if (!td->enabled) {
1155 r = 0; 1466 r = 0;
@@ -1184,7 +1495,7 @@ static int taal_update(struct omap_dss_device *dssdev,
1184 mutex_unlock(&td->lock); 1495 mutex_unlock(&td->lock);
1185 return 0; 1496 return 0;
1186err: 1497err:
1187 dsi_bus_unlock(); 1498 dsi_bus_unlock(dssdev);
1188 mutex_unlock(&td->lock); 1499 mutex_unlock(&td->lock);
1189 return r; 1500 return r;
1190} 1501}
@@ -1196,8 +1507,8 @@ static int taal_sync(struct omap_dss_device *dssdev)
1196 dev_dbg(&dssdev->dev, "sync\n"); 1507 dev_dbg(&dssdev->dev, "sync\n");
1197 1508
1198 mutex_lock(&td->lock); 1509 mutex_lock(&td->lock);
1199 dsi_bus_lock(); 1510 dsi_bus_lock(dssdev);
1200 dsi_bus_unlock(); 1511 dsi_bus_unlock(dssdev);
1201 mutex_unlock(&td->lock); 1512 mutex_unlock(&td->lock);
1202 1513
1203 dev_dbg(&dssdev->dev, "sync done\n"); 1514 dev_dbg(&dssdev->dev, "sync done\n");
@@ -1235,9 +1546,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1235 if (td->te_enabled == enable) 1546 if (td->te_enabled == enable)
1236 goto end; 1547 goto end;
1237 1548
1238 dsi_bus_lock(); 1549 dsi_bus_lock(dssdev);
1239 1550
1240 if (td->enabled) { 1551 if (td->enabled) {
1552 r = taal_wake_up(dssdev);
1553 if (r)
1554 goto err;
1555
1241 r = _taal_enable_te(dssdev, enable); 1556 r = _taal_enable_te(dssdev, enable);
1242 if (r) 1557 if (r)
1243 goto err; 1558 goto err;
@@ -1245,13 +1560,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1245 1560
1246 td->te_enabled = enable; 1561 td->te_enabled = enable;
1247 1562
1248 dsi_bus_unlock(); 1563 dsi_bus_unlock(dssdev);
1249end: 1564end:
1250 mutex_unlock(&td->lock); 1565 mutex_unlock(&td->lock);
1251 1566
1252 return 0; 1567 return 0;
1253err: 1568err:
1254 dsi_bus_unlock(); 1569 dsi_bus_unlock(dssdev);
1255 mutex_unlock(&td->lock); 1570 mutex_unlock(&td->lock);
1256 1571
1257 return r; 1572 return r;
@@ -1281,9 +1596,13 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1281 if (td->rotate == rotate) 1596 if (td->rotate == rotate)
1282 goto end; 1597 goto end;
1283 1598
1284 dsi_bus_lock(); 1599 dsi_bus_lock(dssdev);
1285 1600
1286 if (td->enabled) { 1601 if (td->enabled) {
1602 r = taal_wake_up(dssdev);
1603 if (r)
1604 goto err;
1605
1287 r = taal_set_addr_mode(td, rotate, td->mirror); 1606 r = taal_set_addr_mode(td, rotate, td->mirror);
1288 if (r) 1607 if (r)
1289 goto err; 1608 goto err;
@@ -1291,12 +1610,12 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1291 1610
1292 td->rotate = rotate; 1611 td->rotate = rotate;
1293 1612
1294 dsi_bus_unlock(); 1613 dsi_bus_unlock(dssdev);
1295end: 1614end:
1296 mutex_unlock(&td->lock); 1615 mutex_unlock(&td->lock);
1297 return 0; 1616 return 0;
1298err: 1617err:
1299 dsi_bus_unlock(); 1618 dsi_bus_unlock(dssdev);
1300 mutex_unlock(&td->lock); 1619 mutex_unlock(&td->lock);
1301 return r; 1620 return r;
1302} 1621}
@@ -1325,8 +1644,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1325 if (td->mirror == enable) 1644 if (td->mirror == enable)
1326 goto end; 1645 goto end;
1327 1646
1328 dsi_bus_lock(); 1647 dsi_bus_lock(dssdev);
1329 if (td->enabled) { 1648 if (td->enabled) {
1649 r = taal_wake_up(dssdev);
1650 if (r)
1651 goto err;
1652
1330 r = taal_set_addr_mode(td, td->rotate, enable); 1653 r = taal_set_addr_mode(td, td->rotate, enable);
1331 if (r) 1654 if (r)
1332 goto err; 1655 goto err;
@@ -1334,12 +1657,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1334 1657
1335 td->mirror = enable; 1658 td->mirror = enable;
1336 1659
1337 dsi_bus_unlock(); 1660 dsi_bus_unlock(dssdev);
1338end: 1661end:
1339 mutex_unlock(&td->lock); 1662 mutex_unlock(&td->lock);
1340 return 0; 1663 return 0;
1341err: 1664err:
1342 dsi_bus_unlock(); 1665 dsi_bus_unlock(dssdev);
1343 mutex_unlock(&td->lock); 1666 mutex_unlock(&td->lock);
1344 return r; 1667 return r;
1345} 1668}
@@ -1369,7 +1692,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1369 goto err1; 1692 goto err1;
1370 } 1693 }
1371 1694
1372 dsi_bus_lock(); 1695 dsi_bus_lock(dssdev);
1696
1697 r = taal_wake_up(dssdev);
1698 if (r)
1699 goto err2;
1373 1700
1374 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1); 1701 r = taal_dcs_read_1(td, DCS_GET_ID1, &id1);
1375 if (r) 1702 if (r)
@@ -1381,11 +1708,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1381 if (r) 1708 if (r)
1382 goto err2; 1709 goto err2;
1383 1710
1384 dsi_bus_unlock(); 1711 dsi_bus_unlock(dssdev);
1385 mutex_unlock(&td->lock); 1712 mutex_unlock(&td->lock);
1386 return 0; 1713 return 0;
1387err2: 1714err2:
1388 dsi_bus_unlock(); 1715 dsi_bus_unlock(dssdev);
1389err1: 1716err1:
1390 mutex_unlock(&td->lock); 1717 mutex_unlock(&td->lock);
1391 return r; 1718 return r;
@@ -1415,7 +1742,11 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1415 dssdev->panel.timings.x_res * 1742 dssdev->panel.timings.x_res *
1416 dssdev->panel.timings.y_res * 3); 1743 dssdev->panel.timings.y_res * 3);
1417 1744
1418 dsi_bus_lock(); 1745 dsi_bus_lock(dssdev);
1746
1747 r = taal_wake_up(dssdev);
1748 if (r)
1749 goto err2;
1419 1750
1420 /* plen 1 or 2 goes into short packet. until checksum error is fixed, 1751 /* plen 1 or 2 goes into short packet. until checksum error is fixed,
1421 * use short packets. plen 32 works, but bigger packets seem to cause 1752 * use short packets. plen 32 works, but bigger packets seem to cause
@@ -1427,7 +1758,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1427 1758
1428 taal_set_update_window(td, x, y, w, h); 1759 taal_set_update_window(td, x, y, w, h);
1429 1760
1430 r = dsi_vc_set_max_rx_packet_size(td->channel, plen); 1761 r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
1431 if (r) 1762 if (r)
1432 goto err2; 1763 goto err2;
1433 1764
@@ -1435,7 +1766,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1435 u8 dcs_cmd = first ? 0x2e : 0x3e; 1766 u8 dcs_cmd = first ? 0x2e : 0x3e;
1436 first = 0; 1767 first = 0;
1437 1768
1438 r = dsi_vc_dcs_read(td->channel, dcs_cmd, 1769 r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
1439 buf + buf_used, size - buf_used); 1770 buf + buf_used, size - buf_used);
1440 1771
1441 if (r < 0) { 1772 if (r < 0) {
@@ -1461,14 +1792,35 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
1461 r = buf_used; 1792 r = buf_used;
1462 1793
1463err3: 1794err3:
1464 dsi_vc_set_max_rx_packet_size(td->channel, 1); 1795 dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
1465err2: 1796err2:
1466 dsi_bus_unlock(); 1797 dsi_bus_unlock(dssdev);
1467err1: 1798err1:
1468 mutex_unlock(&td->lock); 1799 mutex_unlock(&td->lock);
1469 return r; 1800 return r;
1470} 1801}
1471 1802
1803static void taal_ulps_work(struct work_struct *work)
1804{
1805 struct taal_data *td = container_of(work, struct taal_data,
1806 ulps_work.work);
1807 struct omap_dss_device *dssdev = td->dssdev;
1808
1809 mutex_lock(&td->lock);
1810
1811 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) {
1812 mutex_unlock(&td->lock);
1813 return;
1814 }
1815
1816 dsi_bus_lock(dssdev);
1817
1818 taal_enter_ulps(dssdev);
1819
1820 dsi_bus_unlock(dssdev);
1821 mutex_unlock(&td->lock);
1822}
1823
1472static void taal_esd_work(struct work_struct *work) 1824static void taal_esd_work(struct work_struct *work)
1473{ 1825{
1474 struct taal_data *td = container_of(work, struct taal_data, 1826 struct taal_data *td = container_of(work, struct taal_data,
@@ -1485,7 +1837,13 @@ static void taal_esd_work(struct work_struct *work)
1485 return; 1837 return;
1486 } 1838 }
1487 1839
1488 dsi_bus_lock(); 1840 dsi_bus_lock(dssdev);
1841
1842 r = taal_wake_up(dssdev);
1843 if (r) {
1844 dev_err(&dssdev->dev, "failed to exit ULPS\n");
1845 goto err;
1846 }
1489 1847
1490 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1); 1848 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
1491 if (r) { 1849 if (r) {
@@ -1521,22 +1879,20 @@ static void taal_esd_work(struct work_struct *work)
1521 goto err; 1879 goto err;
1522 } 1880 }
1523 1881
1524 dsi_bus_unlock(); 1882 dsi_bus_unlock(dssdev);
1525 1883
1526 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1884 taal_queue_esd_work(dssdev);
1527 1885
1528 mutex_unlock(&td->lock); 1886 mutex_unlock(&td->lock);
1529 return; 1887 return;
1530err: 1888err:
1531 dev_err(&dssdev->dev, "performing LCD reset\n"); 1889 dev_err(&dssdev->dev, "performing LCD reset\n");
1532 1890
1533 taal_power_off(dssdev); 1891 taal_panel_reset(dssdev);
1534 taal_hw_reset(dssdev);
1535 taal_power_on(dssdev);
1536 1892
1537 dsi_bus_unlock(); 1893 dsi_bus_unlock(dssdev);
1538 1894
1539 queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); 1895 taal_queue_esd_work(dssdev);
1540 1896
1541 mutex_unlock(&td->lock); 1897 mutex_unlock(&td->lock);
1542} 1898}
@@ -1557,7 +1913,7 @@ static enum omap_dss_update_mode taal_get_update_mode(
1557 1913
1558static struct omap_dss_driver taal_driver = { 1914static struct omap_dss_driver taal_driver = {
1559 .probe = taal_probe, 1915 .probe = taal_probe,
1560 .remove = taal_remove, 1916 .remove = __exit_p(taal_remove),
1561 1917
1562 .enable = taal_enable, 1918 .enable = taal_enable,
1563 .disable = taal_disable, 1919 .disable = taal_disable,
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index dbe9d43b4850..2462b9ec6662 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -17,7 +17,7 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#include <plat/display.h> 20#include <video/omapdss.h>
21 21
22#define TPO_R02_MODE(x) ((x) & 7) 22#define TPO_R02_MODE(x) ((x) & 7)
23#define TPO_R02_MODE_800x480 7 23#define TPO_R02_MODE_800x480 7
@@ -144,13 +144,15 @@ static ssize_t tpo_td043_vmirror_store(struct device *dev,
144 struct device_attribute *attr, const char *buf, size_t count) 144 struct device_attribute *attr, const char *buf, size_t count)
145{ 145{
146 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); 146 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev);
147 long val; 147 int val;
148 int ret; 148 int ret;
149 149
150 ret = strict_strtol(buf, 0, &val); 150 ret = kstrtoint(buf, 0, &val);
151 if (ret < 0) 151 if (ret < 0)
152 return ret; 152 return ret;
153 153
154 val = !!val;
155
154 ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); 156 ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val);
155 if (ret < 0) 157 if (ret < 0)
156 return ret; 158 return ret;
@@ -175,7 +177,7 @@ static ssize_t tpo_td043_mode_store(struct device *dev,
175 long val; 177 long val;
176 int ret; 178 int ret;
177 179
178 ret = strict_strtol(buf, 0, &val); 180 ret = kstrtol(buf, 0, &val);
179 if (ret != 0 || val & ~7) 181 if (ret != 0 || val & ~7)
180 return -EINVAL; 182 return -EINVAL;
181 183
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index bfc5da0e9700..6b3e2da11419 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -80,7 +80,7 @@ config OMAP2_DSS_SDI
80 80
81config OMAP2_DSS_DSI 81config OMAP2_DSS_DSI
82 bool "DSI support" 82 bool "DSI support"
83 depends on ARCH_OMAP3 83 depends on ARCH_OMAP3 || ARCH_OMAP4
84 default n 84 default n
85 help 85 help
86 MIPI DSI (Display Serial Interface) support. 86 MIPI DSI (Display Serial Interface) support.
@@ -90,14 +90,6 @@ config OMAP2_DSS_DSI
90 90
91 See http://www.mipi.org/ for DSI spesifications. 91 See http://www.mipi.org/ for DSI spesifications.
92 92
93config OMAP2_DSS_USE_DSI_PLL
94 bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
95 default n
96 depends on OMAP2_DSS_DSI
97 help
98 Use DSI PLL to generate pixel clock. Currently only for DPI output.
99 DSI PLL can be used to generate higher and more precise pixel clocks.
100
101config OMAP2_DSS_FAKE_VSYNC 93config OMAP2_DSS_FAKE_VSYNC
102 bool "Fake VSYNC irq from manual update displays" 94 bool "Fake VSYNC irq from manual update displays"
103 default n 95 default n
@@ -125,4 +117,27 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
125 Max FCK is 173MHz, so this doesn't work if your PCK 117 Max FCK is 173MHz, so this doesn't work if your PCK
126 is very high. 118 is very high.
127 119
120config OMAP2_DSS_SLEEP_BEFORE_RESET
121 bool "Sleep 50ms before DSS reset"
122 default y
123 help
124 For some unknown reason we may get SYNC_LOST errors from the display
125 subsystem at initialization time if we don't sleep before resetting
126 the DSS. See the source (dss.c) for more comments.
127
128 However, 50ms is quite long time to sleep, and with some
129 configurations the SYNC_LOST may never happen, so the sleep can
130 be disabled here.
131
132config OMAP2_DSS_SLEEP_AFTER_VENC_RESET
133 bool "Sleep 20ms after VENC reset"
134 default y
135 help
136 There is a 20ms sleep after VENC reset which seemed to fix the
137 reset. The reason for the bug is unclear, and it's also unclear
138 on what platforms this happens.
139
140 This option enables the sleep, and is enabled by default. You can
141 disable the sleep if it doesn't cause problems on your platform.
142
128endif 143endif
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 1aa2ed1e786e..3da426719dd6 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,7 +33,7 @@
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35 35
36#include <plat/display.h> 36#include <video/omapdss.h>
37 37
38#include "dss.h" 38#include "dss.h"
39#include "dss_features.h" 39#include "dss_features.h"
@@ -54,6 +54,9 @@ unsigned int dss_debug;
54module_param_named(debug, dss_debug, bool, 0644); 54module_param_named(debug, dss_debug, bool, 0644);
55#endif 55#endif
56 56
57static int omap_dss_register_device(struct omap_dss_device *);
58static void omap_dss_unregister_device(struct omap_dss_device *);
59
57/* REGULATORS */ 60/* REGULATORS */
58 61
59struct regulator *dss_get_vdds_dsi(void) 62struct regulator *dss_get_vdds_dsi(void)
@@ -124,8 +127,7 @@ static int dss_initialize_debugfs(void)
124#endif 127#endif
125 128
126#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) 129#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
127 debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, 130 dsi_create_debugfs_files_irq(dss_debugfs_dir, &dss_debug_fops);
128 &dsi_dump_irqs, &dss_debug_fops);
129#endif 131#endif
130 132
131 debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, 133 debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
@@ -137,8 +139,7 @@ static int dss_initialize_debugfs(void)
137 &rfbi_dump_regs, &dss_debug_fops); 139 &rfbi_dump_regs, &dss_debug_fops);
138#endif 140#endif
139#ifdef CONFIG_OMAP2_DSS_DSI 141#ifdef CONFIG_OMAP2_DSS_DSI
140 debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir, 142 dsi_create_debugfs_files_reg(dss_debugfs_dir, &dss_debug_fops);
141 &dsi_dump_regs, &dss_debug_fops);
142#endif 143#endif
143#ifdef CONFIG_OMAP2_DSS_VENC 144#ifdef CONFIG_OMAP2_DSS_VENC
144 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, 145 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
@@ -480,7 +481,7 @@ static void omap_dss_dev_release(struct device *dev)
480 reset_device(dev, 0); 481 reset_device(dev, 0);
481} 482}
482 483
483int omap_dss_register_device(struct omap_dss_device *dssdev) 484static int omap_dss_register_device(struct omap_dss_device *dssdev)
484{ 485{
485 static int dev_num; 486 static int dev_num;
486 487
@@ -494,7 +495,7 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
494 return device_register(&dssdev->dev); 495 return device_register(&dssdev->dev);
495} 496}
496 497
497void omap_dss_unregister_device(struct omap_dss_device *dssdev) 498static void omap_dss_unregister_device(struct omap_dss_device *dssdev)
498{ 499{
499 device_unregister(&dssdev->dev); 500 device_unregister(&dssdev->dev);
500} 501}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7804779c9da1..7a9a2e7d9685 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,99 +37,15 @@
37#include <plat/sram.h> 37#include <plat/sram.h>
38#include <plat/clock.h> 38#include <plat/clock.h>
39 39
40#include <plat/display.h> 40#include <video/omapdss.h>
41 41
42#include "dss.h" 42#include "dss.h"
43#include "dss_features.h" 43#include "dss_features.h"
44#include "dispc.h"
44 45
45/* DISPC */ 46/* DISPC */
46#define DISPC_SZ_REGS SZ_4K 47#define DISPC_SZ_REGS SZ_4K
47 48
48struct dispc_reg { u16 idx; };
49
50#define DISPC_REG(idx) ((const struct dispc_reg) { idx })
51
52/*
53 * DISPC common registers and
54 * DISPC channel registers , ch = 0 for LCD, ch = 1 for
55 * DIGIT, and ch = 2 for LCD2
56 */
57#define DISPC_REVISION DISPC_REG(0x0000)
58#define DISPC_SYSCONFIG DISPC_REG(0x0010)
59#define DISPC_SYSSTATUS DISPC_REG(0x0014)
60#define DISPC_IRQSTATUS DISPC_REG(0x0018)
61#define DISPC_IRQENABLE DISPC_REG(0x001C)
62#define DISPC_CONTROL DISPC_REG(0x0040)
63#define DISPC_CONTROL2 DISPC_REG(0x0238)
64#define DISPC_CONFIG DISPC_REG(0x0044)
65#define DISPC_CONFIG2 DISPC_REG(0x0620)
66#define DISPC_CAPABLE DISPC_REG(0x0048)
67#define DISPC_DEFAULT_COLOR(ch) DISPC_REG(ch == 0 ? 0x004C : \
68 (ch == 1 ? 0x0050 : 0x03AC))
69#define DISPC_TRANS_COLOR(ch) DISPC_REG(ch == 0 ? 0x0054 : \
70 (ch == 1 ? 0x0058 : 0x03B0))
71#define DISPC_LINE_STATUS DISPC_REG(0x005C)
72#define DISPC_LINE_NUMBER DISPC_REG(0x0060)
73#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
74#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
75#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
76#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
77#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
78#define DISPC_SIZE_DIG DISPC_REG(0x0078)
79#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
80
81/* DISPC GFX plane */
82#define DISPC_GFX_BA0 DISPC_REG(0x0080)
83#define DISPC_GFX_BA1 DISPC_REG(0x0084)
84#define DISPC_GFX_POSITION DISPC_REG(0x0088)
85#define DISPC_GFX_SIZE DISPC_REG(0x008C)
86#define DISPC_GFX_ATTRIBUTES DISPC_REG(0x00A0)
87#define DISPC_GFX_FIFO_THRESHOLD DISPC_REG(0x00A4)
88#define DISPC_GFX_FIFO_SIZE_STATUS DISPC_REG(0x00A8)
89#define DISPC_GFX_ROW_INC DISPC_REG(0x00AC)
90#define DISPC_GFX_PIXEL_INC DISPC_REG(0x00B0)
91#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
92#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
93
94#define DISPC_DATA_CYCLE1(ch) DISPC_REG(ch != 2 ? 0x01D4 : 0x03C0)
95#define DISPC_DATA_CYCLE2(ch) DISPC_REG(ch != 2 ? 0x01D8 : 0x03C4)
96#define DISPC_DATA_CYCLE3(ch) DISPC_REG(ch != 2 ? 0x01DC : 0x03C8)
97#define DISPC_CPR_COEF_R(ch) DISPC_REG(ch != 2 ? 0x0220 : 0x03BC)
98#define DISPC_CPR_COEF_G(ch) DISPC_REG(ch != 2 ? 0x0224 : 0x03B8)
99#define DISPC_CPR_COEF_B(ch) DISPC_REG(ch != 2 ? 0x0228 : 0x03B4)
100
101#define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
102
103/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */
104#define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx)
105
106#define DISPC_VID_BA0(n) DISPC_VID_REG(n, 0x0000)
107#define DISPC_VID_BA1(n) DISPC_VID_REG(n, 0x0004)
108#define DISPC_VID_POSITION(n) DISPC_VID_REG(n, 0x0008)
109#define DISPC_VID_SIZE(n) DISPC_VID_REG(n, 0x000C)
110#define DISPC_VID_ATTRIBUTES(n) DISPC_VID_REG(n, 0x0010)
111#define DISPC_VID_FIFO_THRESHOLD(n) DISPC_VID_REG(n, 0x0014)
112#define DISPC_VID_FIFO_SIZE_STATUS(n) DISPC_VID_REG(n, 0x0018)
113#define DISPC_VID_ROW_INC(n) DISPC_VID_REG(n, 0x001C)
114#define DISPC_VID_PIXEL_INC(n) DISPC_VID_REG(n, 0x0020)
115#define DISPC_VID_FIR(n) DISPC_VID_REG(n, 0x0024)
116#define DISPC_VID_PICTURE_SIZE(n) DISPC_VID_REG(n, 0x0028)
117#define DISPC_VID_ACCU0(n) DISPC_VID_REG(n, 0x002C)
118#define DISPC_VID_ACCU1(n) DISPC_VID_REG(n, 0x0030)
119
120/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
121#define DISPC_VID_FIR_COEF_H(n, i) DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8)
122/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
123#define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8)
124/* coef index i = {0, 1, 2, 3, 4} */
125#define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4)
126/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
127#define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4)
128
129#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
130
131#define DISPC_DIVISOR DISPC_REG(0x0804)
132
133#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ 49#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
134 DISPC_IRQ_OCP_ERR | \ 50 DISPC_IRQ_OCP_ERR | \
135 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \ 51 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
@@ -167,10 +83,6 @@ struct dispc_v_coef {
167#define REG_FLD_MOD(idx, val, start, end) \ 83#define REG_FLD_MOD(idx, val, start, end) \
168 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end)) 84 dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
169 85
170static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
171 DISPC_VID_ATTRIBUTES(0),
172 DISPC_VID_ATTRIBUTES(1) };
173
174struct dispc_irq_stats { 86struct dispc_irq_stats {
175 unsigned long last_reset; 87 unsigned long last_reset;
176 unsigned irq_count; 88 unsigned irq_count;
@@ -198,25 +110,38 @@ static struct {
198#endif 110#endif
199} dispc; 111} dispc;
200 112
113enum omap_color_component {
114 /* used for all color formats for OMAP3 and earlier
115 * and for RGB and Y color component on OMAP4
116 */
117 DISPC_COLOR_COMPONENT_RGB_Y = 1 << 0,
118 /* used for UV component for
119 * OMAP_DSS_COLOR_YUV2, OMAP_DSS_COLOR_UYVY, OMAP_DSS_COLOR_NV12
120 * color formats on OMAP4
121 */
122 DISPC_COLOR_COMPONENT_UV = 1 << 1,
123};
124
201static void _omap_dispc_set_irqs(void); 125static void _omap_dispc_set_irqs(void);
202 126
203static inline void dispc_write_reg(const struct dispc_reg idx, u32 val) 127static inline void dispc_write_reg(const u16 idx, u32 val)
204{ 128{
205 __raw_writel(val, dispc.base + idx.idx); 129 __raw_writel(val, dispc.base + idx);
206} 130}
207 131
208static inline u32 dispc_read_reg(const struct dispc_reg idx) 132static inline u32 dispc_read_reg(const u16 idx)
209{ 133{
210 return __raw_readl(dispc.base + idx.idx); 134 return __raw_readl(dispc.base + idx);
211} 135}
212 136
213#define SR(reg) \ 137#define SR(reg) \
214 dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg) 138 dispc.ctx[DISPC_##reg / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
215#define RR(reg) \ 139#define RR(reg) \
216 dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)]) 140 dispc_write_reg(DISPC_##reg, dispc.ctx[DISPC_##reg / sizeof(u32)])
217 141
218void dispc_save_context(void) 142void dispc_save_context(void)
219{ 143{
144 int i;
220 if (cpu_is_omap24xx()) 145 if (cpu_is_omap24xx())
221 return; 146 return;
222 147
@@ -224,157 +149,153 @@ void dispc_save_context(void)
224 SR(IRQENABLE); 149 SR(IRQENABLE);
225 SR(CONTROL); 150 SR(CONTROL);
226 SR(CONFIG); 151 SR(CONFIG);
227 SR(DEFAULT_COLOR(0)); 152 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
228 SR(DEFAULT_COLOR(1)); 153 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
229 SR(TRANS_COLOR(0)); 154 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
230 SR(TRANS_COLOR(1)); 155 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
231 SR(LINE_NUMBER); 156 SR(LINE_NUMBER);
232 SR(TIMING_H(0)); 157 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
233 SR(TIMING_V(0)); 158 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
234 SR(POL_FREQ(0)); 159 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
235 SR(DIVISORo(0)); 160 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
236 SR(GLOBAL_ALPHA); 161 SR(GLOBAL_ALPHA);
237 SR(SIZE_DIG); 162 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
238 SR(SIZE_LCD(0)); 163 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
239 if (dss_has_feature(FEAT_MGR_LCD2)) { 164 if (dss_has_feature(FEAT_MGR_LCD2)) {
240 SR(CONTROL2); 165 SR(CONTROL2);
241 SR(DEFAULT_COLOR(2)); 166 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
242 SR(TRANS_COLOR(2)); 167 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
243 SR(SIZE_LCD(2)); 168 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
244 SR(TIMING_H(2)); 169 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
245 SR(TIMING_V(2)); 170 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
246 SR(POL_FREQ(2)); 171 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
247 SR(DIVISORo(2)); 172 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
248 SR(CONFIG2); 173 SR(CONFIG2);
249 } 174 }
250 175
251 SR(GFX_BA0); 176 SR(OVL_BA0(OMAP_DSS_GFX));
252 SR(GFX_BA1); 177 SR(OVL_BA1(OMAP_DSS_GFX));
253 SR(GFX_POSITION); 178 SR(OVL_POSITION(OMAP_DSS_GFX));
254 SR(GFX_SIZE); 179 SR(OVL_SIZE(OMAP_DSS_GFX));
255 SR(GFX_ATTRIBUTES); 180 SR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
256 SR(GFX_FIFO_THRESHOLD); 181 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
257 SR(GFX_ROW_INC); 182 SR(OVL_ROW_INC(OMAP_DSS_GFX));
258 SR(GFX_PIXEL_INC); 183 SR(OVL_PIXEL_INC(OMAP_DSS_GFX));
259 SR(GFX_WINDOW_SKIP); 184 SR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
260 SR(GFX_TABLE_BA); 185 SR(OVL_TABLE_BA(OMAP_DSS_GFX));
261 186
262 SR(DATA_CYCLE1(0)); 187 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
263 SR(DATA_CYCLE2(0)); 188 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
264 SR(DATA_CYCLE3(0)); 189 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
265 190
266 SR(CPR_COEF_R(0)); 191 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
267 SR(CPR_COEF_G(0)); 192 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
268 SR(CPR_COEF_B(0)); 193 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
269 if (dss_has_feature(FEAT_MGR_LCD2)) { 194 if (dss_has_feature(FEAT_MGR_LCD2)) {
270 SR(CPR_COEF_B(2)); 195 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
271 SR(CPR_COEF_G(2)); 196 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
272 SR(CPR_COEF_R(2)); 197 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
273 198
274 SR(DATA_CYCLE1(2)); 199 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
275 SR(DATA_CYCLE2(2)); 200 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
276 SR(DATA_CYCLE3(2)); 201 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
277 } 202 }
278 203
279 SR(GFX_PRELOAD); 204 SR(OVL_PRELOAD(OMAP_DSS_GFX));
280 205
281 /* VID1 */ 206 /* VID1 */
282 SR(VID_BA0(0)); 207 SR(OVL_BA0(OMAP_DSS_VIDEO1));
283 SR(VID_BA1(0)); 208 SR(OVL_BA1(OMAP_DSS_VIDEO1));
284 SR(VID_POSITION(0)); 209 SR(OVL_POSITION(OMAP_DSS_VIDEO1));
285 SR(VID_SIZE(0)); 210 SR(OVL_SIZE(OMAP_DSS_VIDEO1));
286 SR(VID_ATTRIBUTES(0)); 211 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
287 SR(VID_FIFO_THRESHOLD(0)); 212 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
288 SR(VID_ROW_INC(0)); 213 SR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
289 SR(VID_PIXEL_INC(0)); 214 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
290 SR(VID_FIR(0)); 215 SR(OVL_FIR(OMAP_DSS_VIDEO1));
291 SR(VID_PICTURE_SIZE(0)); 216 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
292 SR(VID_ACCU0(0)); 217 SR(OVL_ACCU0(OMAP_DSS_VIDEO1));
293 SR(VID_ACCU1(0)); 218 SR(OVL_ACCU1(OMAP_DSS_VIDEO1));
294 219
295 SR(VID_FIR_COEF_H(0, 0)); 220 for (i = 0; i < 8; i++)
296 SR(VID_FIR_COEF_H(0, 1)); 221 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
297 SR(VID_FIR_COEF_H(0, 2)); 222
298 SR(VID_FIR_COEF_H(0, 3)); 223 for (i = 0; i < 8; i++)
299 SR(VID_FIR_COEF_H(0, 4)); 224 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
300 SR(VID_FIR_COEF_H(0, 5)); 225
301 SR(VID_FIR_COEF_H(0, 6)); 226 for (i = 0; i < 5; i++)
302 SR(VID_FIR_COEF_H(0, 7)); 227 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
303 228
304 SR(VID_FIR_COEF_HV(0, 0)); 229 for (i = 0; i < 8; i++)
305 SR(VID_FIR_COEF_HV(0, 1)); 230 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
306 SR(VID_FIR_COEF_HV(0, 2)); 231
307 SR(VID_FIR_COEF_HV(0, 3)); 232 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
308 SR(VID_FIR_COEF_HV(0, 4)); 233 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
309 SR(VID_FIR_COEF_HV(0, 5)); 234 SR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
310 SR(VID_FIR_COEF_HV(0, 6)); 235 SR(OVL_FIR2(OMAP_DSS_VIDEO1));
311 SR(VID_FIR_COEF_HV(0, 7)); 236 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
312 237 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
313 SR(VID_CONV_COEF(0, 0)); 238
314 SR(VID_CONV_COEF(0, 1)); 239 for (i = 0; i < 8; i++)
315 SR(VID_CONV_COEF(0, 2)); 240 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
316 SR(VID_CONV_COEF(0, 3)); 241
317 SR(VID_CONV_COEF(0, 4)); 242 for (i = 0; i < 8; i++)
318 243 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
319 SR(VID_FIR_COEF_V(0, 0)); 244
320 SR(VID_FIR_COEF_V(0, 1)); 245 for (i = 0; i < 8; i++)
321 SR(VID_FIR_COEF_V(0, 2)); 246 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
322 SR(VID_FIR_COEF_V(0, 3)); 247 }
323 SR(VID_FIR_COEF_V(0, 4)); 248 if (dss_has_feature(FEAT_ATTR2))
324 SR(VID_FIR_COEF_V(0, 5)); 249 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
325 SR(VID_FIR_COEF_V(0, 6)); 250
326 SR(VID_FIR_COEF_V(0, 7)); 251 SR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
327
328 SR(VID_PRELOAD(0));
329 252
330 /* VID2 */ 253 /* VID2 */
331 SR(VID_BA0(1)); 254 SR(OVL_BA0(OMAP_DSS_VIDEO2));
332 SR(VID_BA1(1)); 255 SR(OVL_BA1(OMAP_DSS_VIDEO2));
333 SR(VID_POSITION(1)); 256 SR(OVL_POSITION(OMAP_DSS_VIDEO2));
334 SR(VID_SIZE(1)); 257 SR(OVL_SIZE(OMAP_DSS_VIDEO2));
335 SR(VID_ATTRIBUTES(1)); 258 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
336 SR(VID_FIFO_THRESHOLD(1)); 259 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
337 SR(VID_ROW_INC(1)); 260 SR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
338 SR(VID_PIXEL_INC(1)); 261 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
339 SR(VID_FIR(1)); 262 SR(OVL_FIR(OMAP_DSS_VIDEO2));
340 SR(VID_PICTURE_SIZE(1)); 263 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
341 SR(VID_ACCU0(1)); 264 SR(OVL_ACCU0(OMAP_DSS_VIDEO2));
342 SR(VID_ACCU1(1)); 265 SR(OVL_ACCU1(OMAP_DSS_VIDEO2));
343 266
344 SR(VID_FIR_COEF_H(1, 0)); 267 for (i = 0; i < 8; i++)
345 SR(VID_FIR_COEF_H(1, 1)); 268 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
346 SR(VID_FIR_COEF_H(1, 2)); 269
347 SR(VID_FIR_COEF_H(1, 3)); 270 for (i = 0; i < 8; i++)
348 SR(VID_FIR_COEF_H(1, 4)); 271 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
349 SR(VID_FIR_COEF_H(1, 5)); 272
350 SR(VID_FIR_COEF_H(1, 6)); 273 for (i = 0; i < 5; i++)
351 SR(VID_FIR_COEF_H(1, 7)); 274 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
352 275
353 SR(VID_FIR_COEF_HV(1, 0)); 276 for (i = 0; i < 8; i++)
354 SR(VID_FIR_COEF_HV(1, 1)); 277 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
355 SR(VID_FIR_COEF_HV(1, 2)); 278
356 SR(VID_FIR_COEF_HV(1, 3)); 279 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
357 SR(VID_FIR_COEF_HV(1, 4)); 280 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
358 SR(VID_FIR_COEF_HV(1, 5)); 281 SR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
359 SR(VID_FIR_COEF_HV(1, 6)); 282 SR(OVL_FIR2(OMAP_DSS_VIDEO2));
360 SR(VID_FIR_COEF_HV(1, 7)); 283 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
361 284 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
362 SR(VID_CONV_COEF(1, 0)); 285
363 SR(VID_CONV_COEF(1, 1)); 286 for (i = 0; i < 8; i++)
364 SR(VID_CONV_COEF(1, 2)); 287 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
365 SR(VID_CONV_COEF(1, 3)); 288
366 SR(VID_CONV_COEF(1, 4)); 289 for (i = 0; i < 8; i++)
367 290 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
368 SR(VID_FIR_COEF_V(1, 0)); 291
369 SR(VID_FIR_COEF_V(1, 1)); 292 for (i = 0; i < 8; i++)
370 SR(VID_FIR_COEF_V(1, 2)); 293 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
371 SR(VID_FIR_COEF_V(1, 3)); 294 }
372 SR(VID_FIR_COEF_V(1, 4)); 295 if (dss_has_feature(FEAT_ATTR2))
373 SR(VID_FIR_COEF_V(1, 5)); 296 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
374 SR(VID_FIR_COEF_V(1, 6)); 297
375 SR(VID_FIR_COEF_V(1, 7)); 298 SR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
376
377 SR(VID_PRELOAD(1));
378 299
379 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 300 if (dss_has_feature(FEAT_CORE_CLK_DIV))
380 SR(DIVISOR); 301 SR(DIVISOR);
@@ -382,160 +303,158 @@ void dispc_save_context(void)
382 303
383void dispc_restore_context(void) 304void dispc_restore_context(void)
384{ 305{
306 int i;
385 RR(SYSCONFIG); 307 RR(SYSCONFIG);
386 /*RR(IRQENABLE);*/ 308 /*RR(IRQENABLE);*/
387 /*RR(CONTROL);*/ 309 /*RR(CONTROL);*/
388 RR(CONFIG); 310 RR(CONFIG);
389 RR(DEFAULT_COLOR(0)); 311 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
390 RR(DEFAULT_COLOR(1)); 312 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
391 RR(TRANS_COLOR(0)); 313 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
392 RR(TRANS_COLOR(1)); 314 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
393 RR(LINE_NUMBER); 315 RR(LINE_NUMBER);
394 RR(TIMING_H(0)); 316 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD));
395 RR(TIMING_V(0)); 317 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD));
396 RR(POL_FREQ(0)); 318 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
397 RR(DIVISORo(0)); 319 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
398 RR(GLOBAL_ALPHA); 320 RR(GLOBAL_ALPHA);
399 RR(SIZE_DIG); 321 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
400 RR(SIZE_LCD(0)); 322 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
401 if (dss_has_feature(FEAT_MGR_LCD2)) { 323 if (dss_has_feature(FEAT_MGR_LCD2)) {
402 RR(DEFAULT_COLOR(2)); 324 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
403 RR(TRANS_COLOR(2)); 325 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
404 RR(SIZE_LCD(2)); 326 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
405 RR(TIMING_H(2)); 327 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
406 RR(TIMING_V(2)); 328 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
407 RR(POL_FREQ(2)); 329 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
408 RR(DIVISORo(2)); 330 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
409 RR(CONFIG2); 331 RR(CONFIG2);
410 } 332 }
411 333
412 RR(GFX_BA0); 334 RR(OVL_BA0(OMAP_DSS_GFX));
413 RR(GFX_BA1); 335 RR(OVL_BA1(OMAP_DSS_GFX));
414 RR(GFX_POSITION); 336 RR(OVL_POSITION(OMAP_DSS_GFX));
415 RR(GFX_SIZE); 337 RR(OVL_SIZE(OMAP_DSS_GFX));
416 RR(GFX_ATTRIBUTES); 338 RR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
417 RR(GFX_FIFO_THRESHOLD); 339 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
418 RR(GFX_ROW_INC); 340 RR(OVL_ROW_INC(OMAP_DSS_GFX));
419 RR(GFX_PIXEL_INC); 341 RR(OVL_PIXEL_INC(OMAP_DSS_GFX));
420 RR(GFX_WINDOW_SKIP); 342 RR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
421 RR(GFX_TABLE_BA); 343 RR(OVL_TABLE_BA(OMAP_DSS_GFX));
422 344
423 RR(DATA_CYCLE1(0)); 345
424 RR(DATA_CYCLE2(0)); 346 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
425 RR(DATA_CYCLE3(0)); 347 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
426 348 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
427 RR(CPR_COEF_R(0)); 349
428 RR(CPR_COEF_G(0)); 350 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
429 RR(CPR_COEF_B(0)); 351 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
352 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
430 if (dss_has_feature(FEAT_MGR_LCD2)) { 353 if (dss_has_feature(FEAT_MGR_LCD2)) {
431 RR(DATA_CYCLE1(2)); 354 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
432 RR(DATA_CYCLE2(2)); 355 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
433 RR(DATA_CYCLE3(2)); 356 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
434 357
435 RR(CPR_COEF_B(2)); 358 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
436 RR(CPR_COEF_G(2)); 359 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
437 RR(CPR_COEF_R(2)); 360 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
438 } 361 }
439 362
440 RR(GFX_PRELOAD); 363 RR(OVL_PRELOAD(OMAP_DSS_GFX));
441 364
442 /* VID1 */ 365 /* VID1 */
443 RR(VID_BA0(0)); 366 RR(OVL_BA0(OMAP_DSS_VIDEO1));
444 RR(VID_BA1(0)); 367 RR(OVL_BA1(OMAP_DSS_VIDEO1));
445 RR(VID_POSITION(0)); 368 RR(OVL_POSITION(OMAP_DSS_VIDEO1));
446 RR(VID_SIZE(0)); 369 RR(OVL_SIZE(OMAP_DSS_VIDEO1));
447 RR(VID_ATTRIBUTES(0)); 370 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
448 RR(VID_FIFO_THRESHOLD(0)); 371 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
449 RR(VID_ROW_INC(0)); 372 RR(OVL_ROW_INC(OMAP_DSS_VIDEO1));
450 RR(VID_PIXEL_INC(0)); 373 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
451 RR(VID_FIR(0)); 374 RR(OVL_FIR(OMAP_DSS_VIDEO1));
452 RR(VID_PICTURE_SIZE(0)); 375 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
453 RR(VID_ACCU0(0)); 376 RR(OVL_ACCU0(OMAP_DSS_VIDEO1));
454 RR(VID_ACCU1(0)); 377 RR(OVL_ACCU1(OMAP_DSS_VIDEO1));
455 378
456 RR(VID_FIR_COEF_H(0, 0)); 379 for (i = 0; i < 8; i++)
457 RR(VID_FIR_COEF_H(0, 1)); 380 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i));
458 RR(VID_FIR_COEF_H(0, 2)); 381
459 RR(VID_FIR_COEF_H(0, 3)); 382 for (i = 0; i < 8; i++)
460 RR(VID_FIR_COEF_H(0, 4)); 383 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
461 RR(VID_FIR_COEF_H(0, 5)); 384
462 RR(VID_FIR_COEF_H(0, 6)); 385 for (i = 0; i < 5; i++)
463 RR(VID_FIR_COEF_H(0, 7)); 386 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
464 387
465 RR(VID_FIR_COEF_HV(0, 0)); 388 for (i = 0; i < 8; i++)
466 RR(VID_FIR_COEF_HV(0, 1)); 389 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
467 RR(VID_FIR_COEF_HV(0, 2)); 390
468 RR(VID_FIR_COEF_HV(0, 3)); 391 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
469 RR(VID_FIR_COEF_HV(0, 4)); 392 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
470 RR(VID_FIR_COEF_HV(0, 5)); 393 RR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
471 RR(VID_FIR_COEF_HV(0, 6)); 394 RR(OVL_FIR2(OMAP_DSS_VIDEO1));
472 RR(VID_FIR_COEF_HV(0, 7)); 395 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
473 396 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
474 RR(VID_CONV_COEF(0, 0)); 397
475 RR(VID_CONV_COEF(0, 1)); 398 for (i = 0; i < 8; i++)
476 RR(VID_CONV_COEF(0, 2)); 399 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
477 RR(VID_CONV_COEF(0, 3)); 400
478 RR(VID_CONV_COEF(0, 4)); 401 for (i = 0; i < 8; i++)
479 402 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
480 RR(VID_FIR_COEF_V(0, 0)); 403
481 RR(VID_FIR_COEF_V(0, 1)); 404 for (i = 0; i < 8; i++)
482 RR(VID_FIR_COEF_V(0, 2)); 405 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
483 RR(VID_FIR_COEF_V(0, 3)); 406 }
484 RR(VID_FIR_COEF_V(0, 4)); 407 if (dss_has_feature(FEAT_ATTR2))
485 RR(VID_FIR_COEF_V(0, 5)); 408 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
486 RR(VID_FIR_COEF_V(0, 6)); 409
487 RR(VID_FIR_COEF_V(0, 7)); 410 RR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
488
489 RR(VID_PRELOAD(0));
490 411
491 /* VID2 */ 412 /* VID2 */
492 RR(VID_BA0(1)); 413 RR(OVL_BA0(OMAP_DSS_VIDEO2));
493 RR(VID_BA1(1)); 414 RR(OVL_BA1(OMAP_DSS_VIDEO2));
494 RR(VID_POSITION(1)); 415 RR(OVL_POSITION(OMAP_DSS_VIDEO2));
495 RR(VID_SIZE(1)); 416 RR(OVL_SIZE(OMAP_DSS_VIDEO2));
496 RR(VID_ATTRIBUTES(1)); 417 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
497 RR(VID_FIFO_THRESHOLD(1)); 418 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
498 RR(VID_ROW_INC(1)); 419 RR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
499 RR(VID_PIXEL_INC(1)); 420 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
500 RR(VID_FIR(1)); 421 RR(OVL_FIR(OMAP_DSS_VIDEO2));
501 RR(VID_PICTURE_SIZE(1)); 422 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
502 RR(VID_ACCU0(1)); 423 RR(OVL_ACCU0(OMAP_DSS_VIDEO2));
503 RR(VID_ACCU1(1)); 424 RR(OVL_ACCU1(OMAP_DSS_VIDEO2));
504 425
505 RR(VID_FIR_COEF_H(1, 0)); 426 for (i = 0; i < 8; i++)
506 RR(VID_FIR_COEF_H(1, 1)); 427 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i));
507 RR(VID_FIR_COEF_H(1, 2)); 428
508 RR(VID_FIR_COEF_H(1, 3)); 429 for (i = 0; i < 8; i++)
509 RR(VID_FIR_COEF_H(1, 4)); 430 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i));
510 RR(VID_FIR_COEF_H(1, 5)); 431
511 RR(VID_FIR_COEF_H(1, 6)); 432 for (i = 0; i < 5; i++)
512 RR(VID_FIR_COEF_H(1, 7)); 433 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i));
513 434
514 RR(VID_FIR_COEF_HV(1, 0)); 435 for (i = 0; i < 8; i++)
515 RR(VID_FIR_COEF_HV(1, 1)); 436 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i));
516 RR(VID_FIR_COEF_HV(1, 2)); 437
517 RR(VID_FIR_COEF_HV(1, 3)); 438 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
518 RR(VID_FIR_COEF_HV(1, 4)); 439 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2));
519 RR(VID_FIR_COEF_HV(1, 5)); 440 RR(OVL_BA1_UV(OMAP_DSS_VIDEO2));
520 RR(VID_FIR_COEF_HV(1, 6)); 441 RR(OVL_FIR2(OMAP_DSS_VIDEO2));
521 RR(VID_FIR_COEF_HV(1, 7)); 442 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO2));
522 443 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO2));
523 RR(VID_CONV_COEF(1, 0)); 444
524 RR(VID_CONV_COEF(1, 1)); 445 for (i = 0; i < 8; i++)
525 RR(VID_CONV_COEF(1, 2)); 446 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i));
526 RR(VID_CONV_COEF(1, 3)); 447
527 RR(VID_CONV_COEF(1, 4)); 448 for (i = 0; i < 8; i++)
528 449 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i));
529 RR(VID_FIR_COEF_V(1, 0)); 450
530 RR(VID_FIR_COEF_V(1, 1)); 451 for (i = 0; i < 8; i++)
531 RR(VID_FIR_COEF_V(1, 2)); 452 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i));
532 RR(VID_FIR_COEF_V(1, 3)); 453 }
533 RR(VID_FIR_COEF_V(1, 4)); 454 if (dss_has_feature(FEAT_ATTR2))
534 RR(VID_FIR_COEF_V(1, 5)); 455 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
535 RR(VID_FIR_COEF_V(1, 6)); 456
536 RR(VID_FIR_COEF_V(1, 7)); 457 RR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
537
538 RR(VID_PRELOAD(1));
539 458
540 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 459 if (dss_has_feature(FEAT_CORE_CLK_DIV))
541 RR(DIVISOR); 460 RR(DIVISOR);
@@ -632,27 +551,43 @@ end:
632 551
633static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) 552static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
634{ 553{
554 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
555}
556
557static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
558{
559 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value);
560}
561
562static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value)
563{
564 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value);
565}
566
567static void _dispc_write_firh2_reg(enum omap_plane plane, int reg, u32 value)
568{
635 BUG_ON(plane == OMAP_DSS_GFX); 569 BUG_ON(plane == OMAP_DSS_GFX);
636 570
637 dispc_write_reg(DISPC_VID_FIR_COEF_H(plane-1, reg), value); 571 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value);
638} 572}
639 573
640static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value) 574static void _dispc_write_firhv2_reg(enum omap_plane plane, int reg, u32 value)
641{ 575{
642 BUG_ON(plane == OMAP_DSS_GFX); 576 BUG_ON(plane == OMAP_DSS_GFX);
643 577
644 dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane-1, reg), value); 578 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value);
645} 579}
646 580
647static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value) 581static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
648{ 582{
649 BUG_ON(plane == OMAP_DSS_GFX); 583 BUG_ON(plane == OMAP_DSS_GFX);
650 584
651 dispc_write_reg(DISPC_VID_FIR_COEF_V(plane-1, reg), value); 585 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
652} 586}
653 587
654static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup, 588static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
655 int vscaleup, int five_taps) 589 int vscaleup, int five_taps,
590 enum omap_color_component color_comp)
656{ 591{
657 /* Coefficients for horizontal up-sampling */ 592 /* Coefficients for horizontal up-sampling */
658 static const struct dispc_h_coef coef_hup[8] = { 593 static const struct dispc_h_coef coef_hup[8] = {
@@ -750,8 +685,14 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
750 | FLD_VAL(v_coef[i].vc1, 23, 16) 685 | FLD_VAL(v_coef[i].vc1, 23, 16)
751 | FLD_VAL(v_coef[i].vc2, 31, 24); 686 | FLD_VAL(v_coef[i].vc2, 31, 24);
752 687
753 _dispc_write_firh_reg(plane, i, h); 688 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
754 _dispc_write_firhv_reg(plane, i, hv); 689 _dispc_write_firh_reg(plane, i, h);
690 _dispc_write_firhv_reg(plane, i, hv);
691 } else {
692 _dispc_write_firh2_reg(plane, i, h);
693 _dispc_write_firhv2_reg(plane, i, hv);
694 }
695
755 } 696 }
756 697
757 if (five_taps) { 698 if (five_taps) {
@@ -759,7 +700,10 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
759 u32 v; 700 u32 v;
760 v = FLD_VAL(v_coef[i].vc00, 7, 0) 701 v = FLD_VAL(v_coef[i].vc00, 7, 0)
761 | FLD_VAL(v_coef[i].vc22, 15, 8); 702 | FLD_VAL(v_coef[i].vc22, 15, 8);
762 _dispc_write_firv_reg(plane, i, v); 703 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
704 _dispc_write_firv_reg(plane, i, v);
705 else
706 _dispc_write_firv2_reg(plane, i, v);
763 } 707 }
764 } 708 }
765} 709}
@@ -779,72 +723,83 @@ static void _dispc_setup_color_conv_coef(void)
779 723
780 ct = &ctbl_bt601_5; 724 ct = &ctbl_bt601_5;
781 725
782 dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct->rcr, ct->ry)); 726 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0),
783 dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct->gy, ct->rcb)); 727 CVAL(ct->rcr, ct->ry));
784 dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct->gcb, ct->gcr)); 728 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1),
785 dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct->bcr, ct->by)); 729 CVAL(ct->gy, ct->rcb));
786 dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0, ct->bcb)); 730 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2),
787 731 CVAL(ct->gcb, ct->gcr));
788 dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct->rcr, ct->ry)); 732 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3),
789 dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct->gy, ct->rcb)); 733 CVAL(ct->bcr, ct->by));
790 dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct->gcb, ct->gcr)); 734 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4),
791 dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct->bcr, ct->by)); 735 CVAL(0, ct->bcb));
792 dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0, ct->bcb)); 736
737 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0),
738 CVAL(ct->rcr, ct->ry));
739 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1),
740 CVAL(ct->gy, ct->rcb));
741 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2),
742 CVAL(ct->gcb, ct->gcr));
743 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3),
744 CVAL(ct->bcr, ct->by));
745 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4),
746 CVAL(0, ct->bcb));
793 747
794#undef CVAL 748#undef CVAL
795 749
796 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct->full_range, 11, 11); 750 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1),
797 REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct->full_range, 11, 11); 751 ct->full_range, 11, 11);
752 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2),
753 ct->full_range, 11, 11);
798} 754}
799 755
800 756
801static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr) 757static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr)
802{ 758{
803 const struct dispc_reg ba0_reg[] = { DISPC_GFX_BA0, 759 dispc_write_reg(DISPC_OVL_BA0(plane), paddr);
804 DISPC_VID_BA0(0),
805 DISPC_VID_BA0(1) };
806
807 dispc_write_reg(ba0_reg[plane], paddr);
808} 760}
809 761
810static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr) 762static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr)
811{ 763{
812 const struct dispc_reg ba1_reg[] = { DISPC_GFX_BA1, 764 dispc_write_reg(DISPC_OVL_BA1(plane), paddr);
813 DISPC_VID_BA1(0), 765}
814 DISPC_VID_BA1(1) };
815 766
816 dispc_write_reg(ba1_reg[plane], paddr); 767static void _dispc_set_plane_ba0_uv(enum omap_plane plane, u32 paddr)
768{
769 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr);
817} 770}
818 771
819static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y) 772static void _dispc_set_plane_ba1_uv(enum omap_plane plane, u32 paddr)
820{ 773{
821 const struct dispc_reg pos_reg[] = { DISPC_GFX_POSITION, 774 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
822 DISPC_VID_POSITION(0), 775}
823 DISPC_VID_POSITION(1) };
824 776
777static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y)
778{
825 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); 779 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
826 dispc_write_reg(pos_reg[plane], val); 780
781 dispc_write_reg(DISPC_OVL_POSITION(plane), val);
827} 782}
828 783
829static void _dispc_set_pic_size(enum omap_plane plane, int width, int height) 784static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
830{ 785{
831 const struct dispc_reg siz_reg[] = { DISPC_GFX_SIZE,
832 DISPC_VID_PICTURE_SIZE(0),
833 DISPC_VID_PICTURE_SIZE(1) };
834 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 786 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
835 dispc_write_reg(siz_reg[plane], val); 787
788 if (plane == OMAP_DSS_GFX)
789 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
790 else
791 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
836} 792}
837 793
838static void _dispc_set_vid_size(enum omap_plane plane, int width, int height) 794static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
839{ 795{
840 u32 val; 796 u32 val;
841 const struct dispc_reg vsi_reg[] = { DISPC_VID_SIZE(0),
842 DISPC_VID_SIZE(1) };
843 797
844 BUG_ON(plane == OMAP_DSS_GFX); 798 BUG_ON(plane == OMAP_DSS_GFX);
845 799
846 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 800 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
847 dispc_write_reg(vsi_reg[plane-1], val); 801
802 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
848} 803}
849 804
850static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable) 805static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
@@ -856,7 +811,7 @@ static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
856 plane == OMAP_DSS_VIDEO1) 811 plane == OMAP_DSS_VIDEO1)
857 return; 812 return;
858 813
859 REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 28, 28); 814 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
860} 815}
861 816
862static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) 817static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
@@ -876,61 +831,93 @@ static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
876 831
877static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc) 832static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc)
878{ 833{
879 const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC, 834 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc);
880 DISPC_VID_PIXEL_INC(0),
881 DISPC_VID_PIXEL_INC(1) };
882
883 dispc_write_reg(ri_reg[plane], inc);
884} 835}
885 836
886static void _dispc_set_row_inc(enum omap_plane plane, s32 inc) 837static void _dispc_set_row_inc(enum omap_plane plane, s32 inc)
887{ 838{
888 const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC, 839 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc);
889 DISPC_VID_ROW_INC(0),
890 DISPC_VID_ROW_INC(1) };
891
892 dispc_write_reg(ri_reg[plane], inc);
893} 840}
894 841
895static void _dispc_set_color_mode(enum omap_plane plane, 842static void _dispc_set_color_mode(enum omap_plane plane,
896 enum omap_color_mode color_mode) 843 enum omap_color_mode color_mode)
897{ 844{
898 u32 m = 0; 845 u32 m = 0;
899 846 if (plane != OMAP_DSS_GFX) {
900 switch (color_mode) { 847 switch (color_mode) {
901 case OMAP_DSS_COLOR_CLUT1: 848 case OMAP_DSS_COLOR_NV12:
902 m = 0x0; break; 849 m = 0x0; break;
903 case OMAP_DSS_COLOR_CLUT2: 850 case OMAP_DSS_COLOR_RGB12U:
904 m = 0x1; break; 851 m = 0x1; break;
905 case OMAP_DSS_COLOR_CLUT4: 852 case OMAP_DSS_COLOR_RGBA16:
906 m = 0x2; break; 853 m = 0x2; break;
907 case OMAP_DSS_COLOR_CLUT8: 854 case OMAP_DSS_COLOR_RGBX16:
908 m = 0x3; break; 855 m = 0x4; break;
909 case OMAP_DSS_COLOR_RGB12U: 856 case OMAP_DSS_COLOR_ARGB16:
910 m = 0x4; break; 857 m = 0x5; break;
911 case OMAP_DSS_COLOR_ARGB16: 858 case OMAP_DSS_COLOR_RGB16:
912 m = 0x5; break; 859 m = 0x6; break;
913 case OMAP_DSS_COLOR_RGB16: 860 case OMAP_DSS_COLOR_ARGB16_1555:
914 m = 0x6; break; 861 m = 0x7; break;
915 case OMAP_DSS_COLOR_RGB24U: 862 case OMAP_DSS_COLOR_RGB24U:
916 m = 0x8; break; 863 m = 0x8; break;
917 case OMAP_DSS_COLOR_RGB24P: 864 case OMAP_DSS_COLOR_RGB24P:
918 m = 0x9; break; 865 m = 0x9; break;
919 case OMAP_DSS_COLOR_YUV2: 866 case OMAP_DSS_COLOR_YUV2:
920 m = 0xa; break; 867 m = 0xa; break;
921 case OMAP_DSS_COLOR_UYVY: 868 case OMAP_DSS_COLOR_UYVY:
922 m = 0xb; break; 869 m = 0xb; break;
923 case OMAP_DSS_COLOR_ARGB32: 870 case OMAP_DSS_COLOR_ARGB32:
924 m = 0xc; break; 871 m = 0xc; break;
925 case OMAP_DSS_COLOR_RGBA32: 872 case OMAP_DSS_COLOR_RGBA32:
926 m = 0xd; break; 873 m = 0xd; break;
927 case OMAP_DSS_COLOR_RGBX32: 874 case OMAP_DSS_COLOR_RGBX32:
928 m = 0xe; break; 875 m = 0xe; break;
929 default: 876 case OMAP_DSS_COLOR_XRGB16_1555:
930 BUG(); break; 877 m = 0xf; break;
878 default:
879 BUG(); break;
880 }
881 } else {
882 switch (color_mode) {
883 case OMAP_DSS_COLOR_CLUT1:
884 m = 0x0; break;
885 case OMAP_DSS_COLOR_CLUT2:
886 m = 0x1; break;
887 case OMAP_DSS_COLOR_CLUT4:
888 m = 0x2; break;
889 case OMAP_DSS_COLOR_CLUT8:
890 m = 0x3; break;
891 case OMAP_DSS_COLOR_RGB12U:
892 m = 0x4; break;
893 case OMAP_DSS_COLOR_ARGB16:
894 m = 0x5; break;
895 case OMAP_DSS_COLOR_RGB16:
896 m = 0x6; break;
897 case OMAP_DSS_COLOR_ARGB16_1555:
898 m = 0x7; break;
899 case OMAP_DSS_COLOR_RGB24U:
900 m = 0x8; break;
901 case OMAP_DSS_COLOR_RGB24P:
902 m = 0x9; break;
903 case OMAP_DSS_COLOR_YUV2:
904 m = 0xa; break;
905 case OMAP_DSS_COLOR_UYVY:
906 m = 0xb; break;
907 case OMAP_DSS_COLOR_ARGB32:
908 m = 0xc; break;
909 case OMAP_DSS_COLOR_RGBA32:
910 m = 0xd; break;
911 case OMAP_DSS_COLOR_RGBX32:
912 m = 0xe; break;
913 case OMAP_DSS_COLOR_XRGB16_1555:
914 m = 0xf; break;
915 default:
916 BUG(); break;
917 }
931 } 918 }
932 919
933 REG_FLD_MOD(dispc_reg_att[plane], m, 4, 1); 920 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
934} 921}
935 922
936static void _dispc_set_channel_out(enum omap_plane plane, 923static void _dispc_set_channel_out(enum omap_plane plane,
@@ -953,7 +940,7 @@ static void _dispc_set_channel_out(enum omap_plane plane,
953 return; 940 return;
954 } 941 }
955 942
956 val = dispc_read_reg(dispc_reg_att[plane]); 943 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
957 if (dss_has_feature(FEAT_MGR_LCD2)) { 944 if (dss_has_feature(FEAT_MGR_LCD2)) {
958 switch (channel) { 945 switch (channel) {
959 case OMAP_DSS_CHANNEL_LCD: 946 case OMAP_DSS_CHANNEL_LCD:
@@ -977,7 +964,7 @@ static void _dispc_set_channel_out(enum omap_plane plane,
977 } else { 964 } else {
978 val = FLD_MOD(val, channel, shift, shift); 965 val = FLD_MOD(val, channel, shift, shift);
979 } 966 }
980 dispc_write_reg(dispc_reg_att[plane], val); 967 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
981} 968}
982 969
983void dispc_set_burst_size(enum omap_plane plane, 970void dispc_set_burst_size(enum omap_plane plane,
@@ -1001,9 +988,9 @@ void dispc_set_burst_size(enum omap_plane plane,
1001 return; 988 return;
1002 } 989 }
1003 990
1004 val = dispc_read_reg(dispc_reg_att[plane]); 991 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
1005 val = FLD_MOD(val, burst_size, shift+1, shift); 992 val = FLD_MOD(val, burst_size, shift+1, shift);
1006 dispc_write_reg(dispc_reg_att[plane], val); 993 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1007 994
1008 enable_clocks(0); 995 enable_clocks(0);
1009} 996}
@@ -1028,9 +1015,9 @@ static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1028 1015
1029 BUG_ON(plane == OMAP_DSS_GFX); 1016 BUG_ON(plane == OMAP_DSS_GFX);
1030 1017
1031 val = dispc_read_reg(dispc_reg_att[plane]); 1018 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
1032 val = FLD_MOD(val, enable, 9, 9); 1019 val = FLD_MOD(val, enable, 9, 9);
1033 dispc_write_reg(dispc_reg_att[plane], val); 1020 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1034} 1021}
1035 1022
1036void dispc_enable_replication(enum omap_plane plane, bool enable) 1023void dispc_enable_replication(enum omap_plane plane, bool enable)
@@ -1043,7 +1030,7 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
1043 bit = 10; 1030 bit = 10;
1044 1031
1045 enable_clocks(1); 1032 enable_clocks(1);
1046 REG_FLD_MOD(dispc_reg_att[plane], enable, bit, bit); 1033 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
1047 enable_clocks(0); 1034 enable_clocks(0);
1048} 1035}
1049 1036
@@ -1053,7 +1040,7 @@ void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
1053 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1040 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
1054 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1041 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
1055 enable_clocks(1); 1042 enable_clocks(1);
1056 dispc_write_reg(DISPC_SIZE_LCD(channel), val); 1043 dispc_write_reg(DISPC_SIZE_MGR(channel), val);
1057 enable_clocks(0); 1044 enable_clocks(0);
1058} 1045}
1059 1046
@@ -1063,15 +1050,12 @@ void dispc_set_digit_size(u16 width, u16 height)
1063 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1050 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
1064 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1051 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
1065 enable_clocks(1); 1052 enable_clocks(1);
1066 dispc_write_reg(DISPC_SIZE_DIG, val); 1053 dispc_write_reg(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT), val);
1067 enable_clocks(0); 1054 enable_clocks(0);
1068} 1055}
1069 1056
1070static void dispc_read_plane_fifo_sizes(void) 1057static void dispc_read_plane_fifo_sizes(void)
1071{ 1058{
1072 const struct dispc_reg fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
1073 DISPC_VID_FIFO_SIZE_STATUS(0),
1074 DISPC_VID_FIFO_SIZE_STATUS(1) };
1075 u32 size; 1059 u32 size;
1076 int plane; 1060 int plane;
1077 u8 start, end; 1061 u8 start, end;
@@ -1081,7 +1065,8 @@ static void dispc_read_plane_fifo_sizes(void)
1081 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); 1065 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
1082 1066
1083 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { 1067 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) {
1084 size = FLD_GET(dispc_read_reg(fsz_reg[plane]), start, end); 1068 size = FLD_GET(dispc_read_reg(DISPC_OVL_FIFO_SIZE_STATUS(plane)),
1069 start, end);
1085 dispc.fifo_size[plane] = size; 1070 dispc.fifo_size[plane] = size;
1086 } 1071 }
1087 1072
@@ -1095,23 +1080,22 @@ u32 dispc_get_plane_fifo_size(enum omap_plane plane)
1095 1080
1096void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high) 1081void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
1097{ 1082{
1098 const struct dispc_reg ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
1099 DISPC_VID_FIFO_THRESHOLD(0),
1100 DISPC_VID_FIFO_THRESHOLD(1) };
1101 u8 hi_start, hi_end, lo_start, lo_end; 1083 u8 hi_start, hi_end, lo_start, lo_end;
1102 1084
1085 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end);
1086 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
1087
1103 enable_clocks(1); 1088 enable_clocks(1);
1104 1089
1105 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", 1090 DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n",
1106 plane, 1091 plane,
1107 REG_GET(ftrs_reg[plane], 11, 0), 1092 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1108 REG_GET(ftrs_reg[plane], 27, 16), 1093 lo_start, lo_end),
1094 REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane),
1095 hi_start, hi_end),
1109 low, high); 1096 low, high);
1110 1097
1111 dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); 1098 dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
1112 dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end);
1113
1114 dispc_write_reg(ftrs_reg[plane],
1115 FLD_VAL(high, hi_start, hi_end) | 1099 FLD_VAL(high, hi_start, hi_end) |
1116 FLD_VAL(low, lo_start, lo_end)); 1100 FLD_VAL(low, lo_start, lo_end));
1117 1101
@@ -1128,106 +1112,120 @@ void dispc_enable_fifomerge(bool enable)
1128 enable_clocks(0); 1112 enable_clocks(0);
1129} 1113}
1130 1114
1131static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc) 1115static void _dispc_set_fir(enum omap_plane plane,
1116 int hinc, int vinc,
1117 enum omap_color_component color_comp)
1132{ 1118{
1133 u32 val; 1119 u32 val;
1134 const struct dispc_reg fir_reg[] = { DISPC_VID_FIR(0),
1135 DISPC_VID_FIR(1) };
1136 u8 hinc_start, hinc_end, vinc_start, vinc_end;
1137
1138 BUG_ON(plane == OMAP_DSS_GFX);
1139 1120
1140 dss_feat_get_reg_field(FEAT_REG_FIRHINC, &hinc_start, &hinc_end); 1121 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
1141 dss_feat_get_reg_field(FEAT_REG_FIRVINC, &vinc_start, &vinc_end); 1122 u8 hinc_start, hinc_end, vinc_start, vinc_end;
1142 1123
1143 val = FLD_VAL(vinc, vinc_start, vinc_end) | 1124 dss_feat_get_reg_field(FEAT_REG_FIRHINC,
1144 FLD_VAL(hinc, hinc_start, hinc_end); 1125 &hinc_start, &hinc_end);
1126 dss_feat_get_reg_field(FEAT_REG_FIRVINC,
1127 &vinc_start, &vinc_end);
1128 val = FLD_VAL(vinc, vinc_start, vinc_end) |
1129 FLD_VAL(hinc, hinc_start, hinc_end);
1145 1130
1146 dispc_write_reg(fir_reg[plane-1], val); 1131 dispc_write_reg(DISPC_OVL_FIR(plane), val);
1132 } else {
1133 val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0);
1134 dispc_write_reg(DISPC_OVL_FIR2(plane), val);
1135 }
1147} 1136}
1148 1137
1149static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) 1138static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1150{ 1139{
1151 u32 val; 1140 u32 val;
1152 const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
1153 DISPC_VID_ACCU0(1) };
1154 u8 hor_start, hor_end, vert_start, vert_end; 1141 u8 hor_start, hor_end, vert_start, vert_end;
1155 1142
1156 BUG_ON(plane == OMAP_DSS_GFX);
1157
1158 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end); 1143 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1159 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end); 1144 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1160 1145
1161 val = FLD_VAL(vaccu, vert_start, vert_end) | 1146 val = FLD_VAL(vaccu, vert_start, vert_end) |
1162 FLD_VAL(haccu, hor_start, hor_end); 1147 FLD_VAL(haccu, hor_start, hor_end);
1163 1148
1164 dispc_write_reg(ac0_reg[plane-1], val); 1149 dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
1165} 1150}
1166 1151
1167static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) 1152static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1168{ 1153{
1169 u32 val; 1154 u32 val;
1170 const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
1171 DISPC_VID_ACCU1(1) };
1172 u8 hor_start, hor_end, vert_start, vert_end; 1155 u8 hor_start, hor_end, vert_start, vert_end;
1173 1156
1174 BUG_ON(plane == OMAP_DSS_GFX);
1175
1176 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end); 1157 dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end);
1177 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end); 1158 dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end);
1178 1159
1179 val = FLD_VAL(vaccu, vert_start, vert_end) | 1160 val = FLD_VAL(vaccu, vert_start, vert_end) |
1180 FLD_VAL(haccu, hor_start, hor_end); 1161 FLD_VAL(haccu, hor_start, hor_end);
1181 1162
1182 dispc_write_reg(ac1_reg[plane-1], val); 1163 dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
1164}
1165
1166static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu)
1167{
1168 u32 val;
1169
1170 val = FLD_VAL(vaccu, 26, 16) | FLD_VAL(haccu, 10, 0);
1171 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val);
1183} 1172}
1184 1173
1174static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
1175{
1176 u32 val;
1185 1177
1186static void _dispc_set_scaling(enum omap_plane plane, 1178 val = FLD_VAL(vaccu, 26, 16) | FLD_VAL(haccu, 10, 0);
1179 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
1180}
1181
1182static void _dispc_set_scale_param(enum omap_plane plane,
1187 u16 orig_width, u16 orig_height, 1183 u16 orig_width, u16 orig_height,
1188 u16 out_width, u16 out_height, 1184 u16 out_width, u16 out_height,
1189 bool ilace, bool five_taps, 1185 bool five_taps, u8 rotation,
1190 bool fieldmode) 1186 enum omap_color_component color_comp)
1191{ 1187{
1192 int fir_hinc; 1188 int fir_hinc, fir_vinc;
1193 int fir_vinc;
1194 int hscaleup, vscaleup; 1189 int hscaleup, vscaleup;
1195 int accu0 = 0;
1196 int accu1 = 0;
1197 u32 l;
1198
1199 BUG_ON(plane == OMAP_DSS_GFX);
1200 1190
1201 hscaleup = orig_width <= out_width; 1191 hscaleup = orig_width <= out_width;
1202 vscaleup = orig_height <= out_height; 1192 vscaleup = orig_height <= out_height;
1203 1193
1204 _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps); 1194 _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp);
1205 1195
1206 if (!orig_width || orig_width == out_width) 1196 fir_hinc = 1024 * orig_width / out_width;
1207 fir_hinc = 0; 1197 fir_vinc = 1024 * orig_height / out_height;
1208 else
1209 fir_hinc = 1024 * orig_width / out_width;
1210 1198
1211 if (!orig_height || orig_height == out_height) 1199 _dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp);
1212 fir_vinc = 0; 1200}
1213 else
1214 fir_vinc = 1024 * orig_height / out_height;
1215 1201
1216 _dispc_set_fir(plane, fir_hinc, fir_vinc); 1202static void _dispc_set_scaling_common(enum omap_plane plane,
1203 u16 orig_width, u16 orig_height,
1204 u16 out_width, u16 out_height,
1205 bool ilace, bool five_taps,
1206 bool fieldmode, enum omap_color_mode color_mode,
1207 u8 rotation)
1208{
1209 int accu0 = 0;
1210 int accu1 = 0;
1211 u32 l;
1217 1212
1218 l = dispc_read_reg(dispc_reg_att[plane]); 1213 _dispc_set_scale_param(plane, orig_width, orig_height,
1214 out_width, out_height, five_taps,
1215 rotation, DISPC_COLOR_COMPONENT_RGB_Y);
1216 l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
1219 1217
1220 /* RESIZEENABLE and VERTICALTAPS */ 1218 /* RESIZEENABLE and VERTICALTAPS */
1221 l &= ~((0x3 << 5) | (0x1 << 21)); 1219 l &= ~((0x3 << 5) | (0x1 << 21));
1222 l |= fir_hinc ? (1 << 5) : 0; 1220 l |= (orig_width != out_width) ? (1 << 5) : 0;
1223 l |= fir_vinc ? (1 << 6) : 0; 1221 l |= (orig_height != out_height) ? (1 << 6) : 0;
1224 l |= five_taps ? (1 << 21) : 0; 1222 l |= five_taps ? (1 << 21) : 0;
1225 1223
1226 /* VRESIZECONF and HRESIZECONF */ 1224 /* VRESIZECONF and HRESIZECONF */
1227 if (dss_has_feature(FEAT_RESIZECONF)) { 1225 if (dss_has_feature(FEAT_RESIZECONF)) {
1228 l &= ~(0x3 << 7); 1226 l &= ~(0x3 << 7);
1229 l |= hscaleup ? 0 : (1 << 7); 1227 l |= (orig_width <= out_width) ? 0 : (1 << 7);
1230 l |= vscaleup ? 0 : (1 << 8); 1228 l |= (orig_height <= out_height) ? 0 : (1 << 8);
1231 } 1229 }
1232 1230
1233 /* LINEBUFFERSPLIT */ 1231 /* LINEBUFFERSPLIT */
@@ -1236,7 +1234,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
1236 l |= five_taps ? (1 << 22) : 0; 1234 l |= five_taps ? (1 << 22) : 0;
1237 } 1235 }
1238 1236
1239 dispc_write_reg(dispc_reg_att[plane], l); 1237 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
1240 1238
1241 /* 1239 /*
1242 * field 0 = even field = bottom field 1240 * field 0 = even field = bottom field
@@ -1244,7 +1242,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
1244 */ 1242 */
1245 if (ilace && !fieldmode) { 1243 if (ilace && !fieldmode) {
1246 accu1 = 0; 1244 accu1 = 0;
1247 accu0 = (fir_vinc / 2) & 0x3ff; 1245 accu0 = ((1024 * orig_height / out_height) / 2) & 0x3ff;
1248 if (accu0 >= 1024/2) { 1246 if (accu0 >= 1024/2) {
1249 accu1 = 1024/2; 1247 accu1 = 1024/2;
1250 accu0 -= accu1; 1248 accu0 -= accu1;
@@ -1255,6 +1253,93 @@ static void _dispc_set_scaling(enum omap_plane plane,
1255 _dispc_set_vid_accu1(plane, 0, accu1); 1253 _dispc_set_vid_accu1(plane, 0, accu1);
1256} 1254}
1257 1255
1256static void _dispc_set_scaling_uv(enum omap_plane plane,
1257 u16 orig_width, u16 orig_height,
1258 u16 out_width, u16 out_height,
1259 bool ilace, bool five_taps,
1260 bool fieldmode, enum omap_color_mode color_mode,
1261 u8 rotation)
1262{
1263 int scale_x = out_width != orig_width;
1264 int scale_y = out_height != orig_height;
1265
1266 if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
1267 return;
1268 if ((color_mode != OMAP_DSS_COLOR_YUV2 &&
1269 color_mode != OMAP_DSS_COLOR_UYVY &&
1270 color_mode != OMAP_DSS_COLOR_NV12)) {
1271 /* reset chroma resampling for RGB formats */
1272 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
1273 return;
1274 }
1275 switch (color_mode) {
1276 case OMAP_DSS_COLOR_NV12:
1277 /* UV is subsampled by 2 vertically*/
1278 orig_height >>= 1;
1279 /* UV is subsampled by 2 horz.*/
1280 orig_width >>= 1;
1281 break;
1282 case OMAP_DSS_COLOR_YUV2:
1283 case OMAP_DSS_COLOR_UYVY:
1284 /*For YUV422 with 90/270 rotation,
1285 *we don't upsample chroma
1286 */
1287 if (rotation == OMAP_DSS_ROT_0 ||
1288 rotation == OMAP_DSS_ROT_180)
1289 /* UV is subsampled by 2 hrz*/
1290 orig_width >>= 1;
1291 /* must use FIR for YUV422 if rotated */
1292 if (rotation != OMAP_DSS_ROT_0)
1293 scale_x = scale_y = true;
1294 break;
1295 default:
1296 BUG();
1297 }
1298
1299 if (out_width != orig_width)
1300 scale_x = true;
1301 if (out_height != orig_height)
1302 scale_y = true;
1303
1304 _dispc_set_scale_param(plane, orig_width, orig_height,
1305 out_width, out_height, five_taps,
1306 rotation, DISPC_COLOR_COMPONENT_UV);
1307
1308 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
1309 (scale_x || scale_y) ? 1 : 0, 8, 8);
1310 /* set H scaling */
1311 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
1312 /* set V scaling */
1313 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);
1314
1315 _dispc_set_vid_accu2_0(plane, 0x80, 0);
1316 _dispc_set_vid_accu2_1(plane, 0x80, 0);
1317}
1318
1319static void _dispc_set_scaling(enum omap_plane plane,
1320 u16 orig_width, u16 orig_height,
1321 u16 out_width, u16 out_height,
1322 bool ilace, bool five_taps,
1323 bool fieldmode, enum omap_color_mode color_mode,
1324 u8 rotation)
1325{
1326 BUG_ON(plane == OMAP_DSS_GFX);
1327
1328 _dispc_set_scaling_common(plane,
1329 orig_width, orig_height,
1330 out_width, out_height,
1331 ilace, five_taps,
1332 fieldmode, color_mode,
1333 rotation);
1334
1335 _dispc_set_scaling_uv(plane,
1336 orig_width, orig_height,
1337 out_width, out_height,
1338 ilace, five_taps,
1339 fieldmode, color_mode,
1340 rotation);
1341}
1342
1258static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1343static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1259 bool mirroring, enum omap_color_mode color_mode) 1344 bool mirroring, enum omap_color_mode color_mode)
1260{ 1345{
@@ -1302,9 +1387,10 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1302 row_repeat = false; 1387 row_repeat = false;
1303 } 1388 }
1304 1389
1305 REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12); 1390 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
1306 if (dss_has_feature(FEAT_ROWREPEATENABLE)) 1391 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1307 REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18); 1392 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
1393 row_repeat ? 1 : 0, 18, 18);
1308} 1394}
1309 1395
1310static int color_mode_to_bpp(enum omap_color_mode color_mode) 1396static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -1317,12 +1403,17 @@ static int color_mode_to_bpp(enum omap_color_mode color_mode)
1317 case OMAP_DSS_COLOR_CLUT4: 1403 case OMAP_DSS_COLOR_CLUT4:
1318 return 4; 1404 return 4;
1319 case OMAP_DSS_COLOR_CLUT8: 1405 case OMAP_DSS_COLOR_CLUT8:
1406 case OMAP_DSS_COLOR_NV12:
1320 return 8; 1407 return 8;
1321 case OMAP_DSS_COLOR_RGB12U: 1408 case OMAP_DSS_COLOR_RGB12U:
1322 case OMAP_DSS_COLOR_RGB16: 1409 case OMAP_DSS_COLOR_RGB16:
1323 case OMAP_DSS_COLOR_ARGB16: 1410 case OMAP_DSS_COLOR_ARGB16:
1324 case OMAP_DSS_COLOR_YUV2: 1411 case OMAP_DSS_COLOR_YUV2:
1325 case OMAP_DSS_COLOR_UYVY: 1412 case OMAP_DSS_COLOR_UYVY:
1413 case OMAP_DSS_COLOR_RGBA16:
1414 case OMAP_DSS_COLOR_RGBX16:
1415 case OMAP_DSS_COLOR_ARGB16_1555:
1416 case OMAP_DSS_COLOR_XRGB16_1555:
1326 return 16; 1417 return 16;
1327 case OMAP_DSS_COLOR_RGB24P: 1418 case OMAP_DSS_COLOR_RGB24P:
1328 return 24; 1419 return 24;
@@ -1655,7 +1746,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1655 enum omap_dss_rotation_type rotation_type, 1746 enum omap_dss_rotation_type rotation_type,
1656 u8 rotation, int mirror, 1747 u8 rotation, int mirror,
1657 u8 global_alpha, u8 pre_mult_alpha, 1748 u8 global_alpha, u8 pre_mult_alpha,
1658 enum omap_channel channel) 1749 enum omap_channel channel, u32 puv_addr)
1659{ 1750{
1660 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; 1751 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1661 bool five_taps = 0; 1752 bool five_taps = 0;
@@ -1704,7 +1795,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1704 return -EINVAL; 1795 return -EINVAL;
1705 1796
1706 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1797 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1707 color_mode == OMAP_DSS_COLOR_UYVY) 1798 color_mode == OMAP_DSS_COLOR_UYVY ||
1799 color_mode == OMAP_DSS_COLOR_NV12)
1708 cconv = 1; 1800 cconv = 1;
1709 1801
1710 /* Must use 5-tap filter? */ 1802 /* Must use 5-tap filter? */
@@ -1778,6 +1870,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
1778 _dispc_set_plane_ba0(plane, paddr + offset0); 1870 _dispc_set_plane_ba0(plane, paddr + offset0);
1779 _dispc_set_plane_ba1(plane, paddr + offset1); 1871 _dispc_set_plane_ba1(plane, paddr + offset1);
1780 1872
1873 if (OMAP_DSS_COLOR_NV12 == color_mode) {
1874 _dispc_set_plane_ba0_uv(plane, puv_addr + offset0);
1875 _dispc_set_plane_ba1_uv(plane, puv_addr + offset1);
1876 }
1877
1878
1781 _dispc_set_row_inc(plane, row_inc); 1879 _dispc_set_row_inc(plane, row_inc);
1782 _dispc_set_pix_inc(plane, pix_inc); 1880 _dispc_set_pix_inc(plane, pix_inc);
1783 1881
@@ -1791,7 +1889,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1791 if (plane != OMAP_DSS_GFX) { 1889 if (plane != OMAP_DSS_GFX) {
1792 _dispc_set_scaling(plane, width, height, 1890 _dispc_set_scaling(plane, width, height,
1793 out_width, out_height, 1891 out_width, out_height,
1794 ilace, five_taps, fieldmode); 1892 ilace, five_taps, fieldmode,
1893 color_mode, rotation);
1795 _dispc_set_vid_size(plane, out_width, out_height); 1894 _dispc_set_vid_size(plane, out_width, out_height);
1796 _dispc_set_vid_color_conv(plane, cconv); 1895 _dispc_set_vid_color_conv(plane, cconv);
1797 } 1896 }
@@ -1806,7 +1905,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1806 1905
1807static void _dispc_enable_plane(enum omap_plane plane, bool enable) 1906static void _dispc_enable_plane(enum omap_plane plane, bool enable)
1808{ 1907{
1809 REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 0, 0); 1908 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
1810} 1909}
1811 1910
1812static void dispc_disable_isr(void *data, u32 mask) 1911static void dispc_disable_isr(void *data, u32 mask)
@@ -2353,14 +2452,20 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2353 2452
2354unsigned long dispc_fclk_rate(void) 2453unsigned long dispc_fclk_rate(void)
2355{ 2454{
2455 struct platform_device *dsidev;
2356 unsigned long r = 0; 2456 unsigned long r = 0;
2357 2457
2358 switch (dss_get_dispc_clk_source()) { 2458 switch (dss_get_dispc_clk_source()) {
2359 case DSS_CLK_SRC_FCK: 2459 case OMAP_DSS_CLK_SRC_FCK:
2360 r = dss_clk_get_rate(DSS_CLK_FCK); 2460 r = dss_clk_get_rate(DSS_CLK_FCK);
2361 break; 2461 break;
2362 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2462 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2363 r = dsi_get_pll_hsdiv_dispc_rate(); 2463 dsidev = dsi_get_dsidev_from_id(0);
2464 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2465 break;
2466 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
2467 dsidev = dsi_get_dsidev_from_id(1);
2468 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2364 break; 2469 break;
2365 default: 2470 default:
2366 BUG(); 2471 BUG();
@@ -2371,6 +2476,7 @@ unsigned long dispc_fclk_rate(void)
2371 2476
2372unsigned long dispc_lclk_rate(enum omap_channel channel) 2477unsigned long dispc_lclk_rate(enum omap_channel channel)
2373{ 2478{
2479 struct platform_device *dsidev;
2374 int lcd; 2480 int lcd;
2375 unsigned long r; 2481 unsigned long r;
2376 u32 l; 2482 u32 l;
@@ -2380,11 +2486,16 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2380 lcd = FLD_GET(l, 23, 16); 2486 lcd = FLD_GET(l, 23, 16);
2381 2487
2382 switch (dss_get_lcd_clk_source(channel)) { 2488 switch (dss_get_lcd_clk_source(channel)) {
2383 case DSS_CLK_SRC_FCK: 2489 case OMAP_DSS_CLK_SRC_FCK:
2384 r = dss_clk_get_rate(DSS_CLK_FCK); 2490 r = dss_clk_get_rate(DSS_CLK_FCK);
2385 break; 2491 break;
2386 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 2492 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
2387 r = dsi_get_pll_hsdiv_dispc_rate(); 2493 dsidev = dsi_get_dsidev_from_id(0);
2494 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2495 break;
2496 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
2497 dsidev = dsi_get_dsidev_from_id(1);
2498 r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
2388 break; 2499 break;
2389 default: 2500 default:
2390 BUG(); 2501 BUG();
@@ -2412,8 +2523,8 @@ void dispc_dump_clocks(struct seq_file *s)
2412{ 2523{
2413 int lcd, pcd; 2524 int lcd, pcd;
2414 u32 l; 2525 u32 l;
2415 enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); 2526 enum omap_dss_clk_source dispc_clk_src = dss_get_dispc_clk_source();
2416 enum dss_clk_source lcd_clk_src; 2527 enum omap_dss_clk_source lcd_clk_src;
2417 2528
2418 enable_clocks(1); 2529 enable_clocks(1);
2419 2530
@@ -2516,7 +2627,7 @@ void dispc_dump_irqs(struct seq_file *s)
2516 2627
2517void dispc_dump_regs(struct seq_file *s) 2628void dispc_dump_regs(struct seq_file *s)
2518{ 2629{
2519#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) 2630#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
2520 2631
2521 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 2632 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
2522 2633
@@ -2528,152 +2639,227 @@ void dispc_dump_regs(struct seq_file *s)
2528 DUMPREG(DISPC_CONTROL); 2639 DUMPREG(DISPC_CONTROL);
2529 DUMPREG(DISPC_CONFIG); 2640 DUMPREG(DISPC_CONFIG);
2530 DUMPREG(DISPC_CAPABLE); 2641 DUMPREG(DISPC_CAPABLE);
2531 DUMPREG(DISPC_DEFAULT_COLOR(0)); 2642 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
2532 DUMPREG(DISPC_DEFAULT_COLOR(1)); 2643 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2533 DUMPREG(DISPC_TRANS_COLOR(0)); 2644 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
2534 DUMPREG(DISPC_TRANS_COLOR(1)); 2645 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2535 DUMPREG(DISPC_LINE_STATUS); 2646 DUMPREG(DISPC_LINE_STATUS);
2536 DUMPREG(DISPC_LINE_NUMBER); 2647 DUMPREG(DISPC_LINE_NUMBER);
2537 DUMPREG(DISPC_TIMING_H(0)); 2648 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD));
2538 DUMPREG(DISPC_TIMING_V(0)); 2649 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD));
2539 DUMPREG(DISPC_POL_FREQ(0)); 2650 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD));
2540 DUMPREG(DISPC_DIVISORo(0)); 2651 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD));
2541 DUMPREG(DISPC_GLOBAL_ALPHA); 2652 DUMPREG(DISPC_GLOBAL_ALPHA);
2542 DUMPREG(DISPC_SIZE_DIG); 2653 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
2543 DUMPREG(DISPC_SIZE_LCD(0)); 2654 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
2544 if (dss_has_feature(FEAT_MGR_LCD2)) { 2655 if (dss_has_feature(FEAT_MGR_LCD2)) {
2545 DUMPREG(DISPC_CONTROL2); 2656 DUMPREG(DISPC_CONTROL2);
2546 DUMPREG(DISPC_CONFIG2); 2657 DUMPREG(DISPC_CONFIG2);
2547 DUMPREG(DISPC_DEFAULT_COLOR(2)); 2658 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
2548 DUMPREG(DISPC_TRANS_COLOR(2)); 2659 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
2549 DUMPREG(DISPC_TIMING_H(2)); 2660 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD2));
2550 DUMPREG(DISPC_TIMING_V(2)); 2661 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD2));
2551 DUMPREG(DISPC_POL_FREQ(2)); 2662 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
2552 DUMPREG(DISPC_DIVISORo(2)); 2663 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD2));
2553 DUMPREG(DISPC_SIZE_LCD(2)); 2664 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
2554 } 2665 }
2555 2666
2556 DUMPREG(DISPC_GFX_BA0); 2667 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_GFX));
2557 DUMPREG(DISPC_GFX_BA1); 2668 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_GFX));
2558 DUMPREG(DISPC_GFX_POSITION); 2669 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_GFX));
2559 DUMPREG(DISPC_GFX_SIZE); 2670 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_GFX));
2560 DUMPREG(DISPC_GFX_ATTRIBUTES); 2671 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_GFX));
2561 DUMPREG(DISPC_GFX_FIFO_THRESHOLD); 2672 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
2562 DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS); 2673 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_GFX));
2563 DUMPREG(DISPC_GFX_ROW_INC); 2674 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_GFX));
2564 DUMPREG(DISPC_GFX_PIXEL_INC); 2675 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_GFX));
2565 DUMPREG(DISPC_GFX_WINDOW_SKIP); 2676 DUMPREG(DISPC_OVL_WINDOW_SKIP(OMAP_DSS_GFX));
2566 DUMPREG(DISPC_GFX_TABLE_BA); 2677 DUMPREG(DISPC_OVL_TABLE_BA(OMAP_DSS_GFX));
2567 2678
2568 DUMPREG(DISPC_DATA_CYCLE1(0)); 2679 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
2569 DUMPREG(DISPC_DATA_CYCLE2(0)); 2680 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
2570 DUMPREG(DISPC_DATA_CYCLE3(0)); 2681 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
2571 2682
2572 DUMPREG(DISPC_CPR_COEF_R(0)); 2683 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
2573 DUMPREG(DISPC_CPR_COEF_G(0)); 2684 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
2574 DUMPREG(DISPC_CPR_COEF_B(0)); 2685 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
2575 if (dss_has_feature(FEAT_MGR_LCD2)) { 2686 if (dss_has_feature(FEAT_MGR_LCD2)) {
2576 DUMPREG(DISPC_DATA_CYCLE1(2)); 2687 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
2577 DUMPREG(DISPC_DATA_CYCLE2(2)); 2688 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
2578 DUMPREG(DISPC_DATA_CYCLE3(2)); 2689 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
2579 2690
2580 DUMPREG(DISPC_CPR_COEF_R(2)); 2691 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2));
2581 DUMPREG(DISPC_CPR_COEF_G(2)); 2692 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2));
2582 DUMPREG(DISPC_CPR_COEF_B(2)); 2693 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2));
2583 } 2694 }
2584 2695
2585 DUMPREG(DISPC_GFX_PRELOAD); 2696 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX));
2586 2697
2587 DUMPREG(DISPC_VID_BA0(0)); 2698 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1));
2588 DUMPREG(DISPC_VID_BA1(0)); 2699 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1));
2589 DUMPREG(DISPC_VID_POSITION(0)); 2700 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO1));
2590 DUMPREG(DISPC_VID_SIZE(0)); 2701 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO1));
2591 DUMPREG(DISPC_VID_ATTRIBUTES(0)); 2702 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1));
2592 DUMPREG(DISPC_VID_FIFO_THRESHOLD(0)); 2703 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1));
2593 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0)); 2704 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO1));
2594 DUMPREG(DISPC_VID_ROW_INC(0)); 2705 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO1));
2595 DUMPREG(DISPC_VID_PIXEL_INC(0)); 2706 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO1));
2596 DUMPREG(DISPC_VID_FIR(0)); 2707 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO1));
2597 DUMPREG(DISPC_VID_PICTURE_SIZE(0)); 2708 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1));
2598 DUMPREG(DISPC_VID_ACCU0(0)); 2709 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO1));
2599 DUMPREG(DISPC_VID_ACCU1(0)); 2710 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO1));
2600 2711
2601 DUMPREG(DISPC_VID_BA0(1)); 2712 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO2));
2602 DUMPREG(DISPC_VID_BA1(1)); 2713 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO2));
2603 DUMPREG(DISPC_VID_POSITION(1)); 2714 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO2));
2604 DUMPREG(DISPC_VID_SIZE(1)); 2715 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO2));
2605 DUMPREG(DISPC_VID_ATTRIBUTES(1)); 2716 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
2606 DUMPREG(DISPC_VID_FIFO_THRESHOLD(1)); 2717 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
2607 DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1)); 2718 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO2));
2608 DUMPREG(DISPC_VID_ROW_INC(1)); 2719 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO2));
2609 DUMPREG(DISPC_VID_PIXEL_INC(1)); 2720 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
2610 DUMPREG(DISPC_VID_FIR(1)); 2721 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO2));
2611 DUMPREG(DISPC_VID_PICTURE_SIZE(1)); 2722 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
2612 DUMPREG(DISPC_VID_ACCU0(1)); 2723 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO2));
2613 DUMPREG(DISPC_VID_ACCU1(1)); 2724 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO2));
2614 2725
2615 DUMPREG(DISPC_VID_FIR_COEF_H(0, 0)); 2726 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 0));
2616 DUMPREG(DISPC_VID_FIR_COEF_H(0, 1)); 2727 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 1));
2617 DUMPREG(DISPC_VID_FIR_COEF_H(0, 2)); 2728 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 2));
2618 DUMPREG(DISPC_VID_FIR_COEF_H(0, 3)); 2729 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 3));
2619 DUMPREG(DISPC_VID_FIR_COEF_H(0, 4)); 2730 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 4));
2620 DUMPREG(DISPC_VID_FIR_COEF_H(0, 5)); 2731 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 5));
2621 DUMPREG(DISPC_VID_FIR_COEF_H(0, 6)); 2732 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 6));
2622 DUMPREG(DISPC_VID_FIR_COEF_H(0, 7)); 2733 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 7));
2623 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0)); 2734 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 0));
2624 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1)); 2735 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 1));
2625 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2)); 2736 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 2));
2626 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3)); 2737 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 3));
2627 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4)); 2738 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 4));
2628 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5)); 2739 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 5));
2629 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6)); 2740 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 6));
2630 DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7)); 2741 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 7));
2631 DUMPREG(DISPC_VID_CONV_COEF(0, 0)); 2742 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0));
2632 DUMPREG(DISPC_VID_CONV_COEF(0, 1)); 2743 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1));
2633 DUMPREG(DISPC_VID_CONV_COEF(0, 2)); 2744 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2));
2634 DUMPREG(DISPC_VID_CONV_COEF(0, 3)); 2745 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3));
2635 DUMPREG(DISPC_VID_CONV_COEF(0, 4)); 2746 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4));
2636 DUMPREG(DISPC_VID_FIR_COEF_V(0, 0)); 2747 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0));
2637 DUMPREG(DISPC_VID_FIR_COEF_V(0, 1)); 2748 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1));
2638 DUMPREG(DISPC_VID_FIR_COEF_V(0, 2)); 2749 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2));
2639 DUMPREG(DISPC_VID_FIR_COEF_V(0, 3)); 2750 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3));
2640 DUMPREG(DISPC_VID_FIR_COEF_V(0, 4)); 2751 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4));
2641 DUMPREG(DISPC_VID_FIR_COEF_V(0, 5)); 2752 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5));
2642 DUMPREG(DISPC_VID_FIR_COEF_V(0, 6)); 2753 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6));
2643 DUMPREG(DISPC_VID_FIR_COEF_V(0, 7)); 2754 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7));
2644 2755
2645 DUMPREG(DISPC_VID_FIR_COEF_H(1, 0)); 2756 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2646 DUMPREG(DISPC_VID_FIR_COEF_H(1, 1)); 2757 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1));
2647 DUMPREG(DISPC_VID_FIR_COEF_H(1, 2)); 2758 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO1));
2648 DUMPREG(DISPC_VID_FIR_COEF_H(1, 3)); 2759 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO1));
2649 DUMPREG(DISPC_VID_FIR_COEF_H(1, 4)); 2760 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO1));
2650 DUMPREG(DISPC_VID_FIR_COEF_H(1, 5)); 2761 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO1));
2651 DUMPREG(DISPC_VID_FIR_COEF_H(1, 6)); 2762
2652 DUMPREG(DISPC_VID_FIR_COEF_H(1, 7)); 2763 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 0));
2653 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0)); 2764 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 1));
2654 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1)); 2765 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 2));
2655 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2)); 2766 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 3));
2656 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3)); 2767 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 4));
2657 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4)); 2768 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 5));
2658 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5)); 2769 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 6));
2659 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6)); 2770 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 7));
2660 DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7)); 2771
2661 DUMPREG(DISPC_VID_CONV_COEF(1, 0)); 2772 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 0));
2662 DUMPREG(DISPC_VID_CONV_COEF(1, 1)); 2773 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 1));
2663 DUMPREG(DISPC_VID_CONV_COEF(1, 2)); 2774 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 2));
2664 DUMPREG(DISPC_VID_CONV_COEF(1, 3)); 2775 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 3));
2665 DUMPREG(DISPC_VID_CONV_COEF(1, 4)); 2776 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 4));
2666 DUMPREG(DISPC_VID_FIR_COEF_V(1, 0)); 2777 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 5));
2667 DUMPREG(DISPC_VID_FIR_COEF_V(1, 1)); 2778 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 6));
2668 DUMPREG(DISPC_VID_FIR_COEF_V(1, 2)); 2779 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 7));
2669 DUMPREG(DISPC_VID_FIR_COEF_V(1, 3)); 2780
2670 DUMPREG(DISPC_VID_FIR_COEF_V(1, 4)); 2781 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 0));
2671 DUMPREG(DISPC_VID_FIR_COEF_V(1, 5)); 2782 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 1));
2672 DUMPREG(DISPC_VID_FIR_COEF_V(1, 6)); 2783 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 2));
2673 DUMPREG(DISPC_VID_FIR_COEF_V(1, 7)); 2784 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 3));
2674 2785 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 4));
2675 DUMPREG(DISPC_VID_PRELOAD(0)); 2786 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 5));
2676 DUMPREG(DISPC_VID_PRELOAD(1)); 2787 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 6));
2788 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 7));
2789 }
2790 if (dss_has_feature(FEAT_ATTR2))
2791 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
2792
2793
2794 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 0));
2795 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 1));
2796 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 2));
2797 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 3));
2798 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 4));
2799 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 5));
2800 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 6));
2801 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 7));
2802 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 0));
2803 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 1));
2804 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 2));
2805 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 3));
2806 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 4));
2807 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 5));
2808 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 6));
2809 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 7));
2810 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0));
2811 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1));
2812 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2));
2813 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3));
2814 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4));
2815 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0));
2816 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1));
2817 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2));
2818 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3));
2819 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4));
2820 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5));
2821 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6));
2822 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7));
2823
2824 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2825 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2));
2826 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO2));
2827 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO2));
2828 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO2));
2829 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO2));
2830
2831 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 0));
2832 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 1));
2833 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 2));
2834 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 3));
2835 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 4));
2836 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 5));
2837 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 6));
2838 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 7));
2839
2840 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 0));
2841 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 1));
2842 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 2));
2843 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 3));
2844 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 4));
2845 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 5));
2846 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 6));
2847 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 7));
2848
2849 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 0));
2850 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 1));
2851 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 2));
2852 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 3));
2853 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 4));
2854 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 5));
2855 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 6));
2856 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 7));
2857 }
2858 if (dss_has_feature(FEAT_ATTR2))
2859 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
2860
2861 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1));
2862 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
2677 2863
2678 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 2864 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
2679#undef DUMPREG 2865#undef DUMPREG
@@ -3388,11 +3574,12 @@ int dispc_setup_plane(enum omap_plane plane,
3388 bool ilace, 3574 bool ilace,
3389 enum omap_dss_rotation_type rotation_type, 3575 enum omap_dss_rotation_type rotation_type,
3390 u8 rotation, bool mirror, u8 global_alpha, 3576 u8 rotation, bool mirror, u8 global_alpha,
3391 u8 pre_mult_alpha, enum omap_channel channel) 3577 u8 pre_mult_alpha, enum omap_channel channel,
3578 u32 puv_addr)
3392{ 3579{
3393 int r = 0; 3580 int r = 0;
3394 3581
3395 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 3582 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d, %d, %dx%d -> "
3396 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n", 3583 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
3397 plane, paddr, screen_width, pos_x, pos_y, 3584 plane, paddr, screen_width, pos_x, pos_y,
3398 width, height, 3585 width, height,
@@ -3411,7 +3598,8 @@ int dispc_setup_plane(enum omap_plane plane,
3411 rotation_type, 3598 rotation_type,
3412 rotation, mirror, 3599 rotation, mirror,
3413 global_alpha, 3600 global_alpha,
3414 pre_mult_alpha, channel); 3601 pre_mult_alpha,
3602 channel, puv_addr);
3415 3603
3416 enable_clocks(0); 3604 enable_clocks(0);
3417 3605
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
new file mode 100644
index 000000000000..6c9ee0a0efb3
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc.h
@@ -0,0 +1,691 @@
1/*
2 * linux/drivers/video/omap2/dss/dispc.h
3 *
4 * Copyright (C) 2011 Texas Instruments
5 * Author: Archit Taneja <archit@ti.com>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef __OMAP2_DISPC_REG_H
22#define __OMAP2_DISPC_REG_H
23
24/* DISPC common registers */
25#define DISPC_REVISION 0x0000
26#define DISPC_SYSCONFIG 0x0010
27#define DISPC_SYSSTATUS 0x0014
28#define DISPC_IRQSTATUS 0x0018
29#define DISPC_IRQENABLE 0x001C
30#define DISPC_CONTROL 0x0040
31#define DISPC_CONFIG 0x0044
32#define DISPC_CAPABLE 0x0048
33#define DISPC_LINE_STATUS 0x005C
34#define DISPC_LINE_NUMBER 0x0060
35#define DISPC_GLOBAL_ALPHA 0x0074
36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804
39
40/* DISPC overlay registers */
41#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
42 DISPC_BA0_OFFSET(n))
43#define DISPC_OVL_BA1(n) (DISPC_OVL_BASE(n) + \
44 DISPC_BA1_OFFSET(n))
45#define DISPC_OVL_BA0_UV(n) (DISPC_OVL_BASE(n) + \
46 DISPC_BA0_UV_OFFSET(n))
47#define DISPC_OVL_BA1_UV(n) (DISPC_OVL_BASE(n) + \
48 DISPC_BA1_UV_OFFSET(n))
49#define DISPC_OVL_POSITION(n) (DISPC_OVL_BASE(n) + \
50 DISPC_POS_OFFSET(n))
51#define DISPC_OVL_SIZE(n) (DISPC_OVL_BASE(n) + \
52 DISPC_SIZE_OFFSET(n))
53#define DISPC_OVL_ATTRIBUTES(n) (DISPC_OVL_BASE(n) + \
54 DISPC_ATTR_OFFSET(n))
55#define DISPC_OVL_ATTRIBUTES2(n) (DISPC_OVL_BASE(n) + \
56 DISPC_ATTR2_OFFSET(n))
57#define DISPC_OVL_FIFO_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
58 DISPC_FIFO_THRESH_OFFSET(n))
59#define DISPC_OVL_FIFO_SIZE_STATUS(n) (DISPC_OVL_BASE(n) + \
60 DISPC_FIFO_SIZE_STATUS_OFFSET(n))
61#define DISPC_OVL_ROW_INC(n) (DISPC_OVL_BASE(n) + \
62 DISPC_ROW_INC_OFFSET(n))
63#define DISPC_OVL_PIXEL_INC(n) (DISPC_OVL_BASE(n) + \
64 DISPC_PIX_INC_OFFSET(n))
65#define DISPC_OVL_WINDOW_SKIP(n) (DISPC_OVL_BASE(n) + \
66 DISPC_WINDOW_SKIP_OFFSET(n))
67#define DISPC_OVL_TABLE_BA(n) (DISPC_OVL_BASE(n) + \
68 DISPC_TABLE_BA_OFFSET(n))
69#define DISPC_OVL_FIR(n) (DISPC_OVL_BASE(n) + \
70 DISPC_FIR_OFFSET(n))
71#define DISPC_OVL_FIR2(n) (DISPC_OVL_BASE(n) + \
72 DISPC_FIR2_OFFSET(n))
73#define DISPC_OVL_PICTURE_SIZE(n) (DISPC_OVL_BASE(n) + \
74 DISPC_PIC_SIZE_OFFSET(n))
75#define DISPC_OVL_ACCU0(n) (DISPC_OVL_BASE(n) + \
76 DISPC_ACCU0_OFFSET(n))
77#define DISPC_OVL_ACCU1(n) (DISPC_OVL_BASE(n) + \
78 DISPC_ACCU1_OFFSET(n))
79#define DISPC_OVL_ACCU2_0(n) (DISPC_OVL_BASE(n) + \
80 DISPC_ACCU2_0_OFFSET(n))
81#define DISPC_OVL_ACCU2_1(n) (DISPC_OVL_BASE(n) + \
82 DISPC_ACCU2_1_OFFSET(n))
83#define DISPC_OVL_FIR_COEF_H(n, i) (DISPC_OVL_BASE(n) + \
84 DISPC_FIR_COEF_H_OFFSET(n, i))
85#define DISPC_OVL_FIR_COEF_HV(n, i) (DISPC_OVL_BASE(n) + \
86 DISPC_FIR_COEF_HV_OFFSET(n, i))
87#define DISPC_OVL_FIR_COEF_H2(n, i) (DISPC_OVL_BASE(n) + \
88 DISPC_FIR_COEF_H2_OFFSET(n, i))
89#define DISPC_OVL_FIR_COEF_HV2(n, i) (DISPC_OVL_BASE(n) + \
90 DISPC_FIR_COEF_HV2_OFFSET(n, i))
91#define DISPC_OVL_CONV_COEF(n, i) (DISPC_OVL_BASE(n) + \
92 DISPC_CONV_COEF_OFFSET(n, i))
93#define DISPC_OVL_FIR_COEF_V(n, i) (DISPC_OVL_BASE(n) + \
94 DISPC_FIR_COEF_V_OFFSET(n, i))
95#define DISPC_OVL_FIR_COEF_V2(n, i) (DISPC_OVL_BASE(n) + \
96 DISPC_FIR_COEF_V2_OFFSET(n, i))
97#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
98 DISPC_PRELOAD_OFFSET(n))
99
100/* DISPC manager/channel specific registers */
101static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
102{
103 switch (channel) {
104 case OMAP_DSS_CHANNEL_LCD:
105 return 0x004C;
106 case OMAP_DSS_CHANNEL_DIGIT:
107 return 0x0050;
108 case OMAP_DSS_CHANNEL_LCD2:
109 return 0x03AC;
110 default:
111 BUG();
112 }
113}
114
115static inline u16 DISPC_TRANS_COLOR(enum omap_channel channel)
116{
117 switch (channel) {
118 case OMAP_DSS_CHANNEL_LCD:
119 return 0x0054;
120 case OMAP_DSS_CHANNEL_DIGIT:
121 return 0x0058;
122 case OMAP_DSS_CHANNEL_LCD2:
123 return 0x03B0;
124 default:
125 BUG();
126 }
127}
128
129static inline u16 DISPC_TIMING_H(enum omap_channel channel)
130{
131 switch (channel) {
132 case OMAP_DSS_CHANNEL_LCD:
133 return 0x0064;
134 case OMAP_DSS_CHANNEL_DIGIT:
135 BUG();
136 case OMAP_DSS_CHANNEL_LCD2:
137 return 0x0400;
138 default:
139 BUG();
140 }
141}
142
143static inline u16 DISPC_TIMING_V(enum omap_channel channel)
144{
145 switch (channel) {
146 case OMAP_DSS_CHANNEL_LCD:
147 return 0x0068;
148 case OMAP_DSS_CHANNEL_DIGIT:
149 BUG();
150 case OMAP_DSS_CHANNEL_LCD2:
151 return 0x0404;
152 default:
153 BUG();
154 }
155}
156
157static inline u16 DISPC_POL_FREQ(enum omap_channel channel)
158{
159 switch (channel) {
160 case OMAP_DSS_CHANNEL_LCD:
161 return 0x006C;
162 case OMAP_DSS_CHANNEL_DIGIT:
163 BUG();
164 case OMAP_DSS_CHANNEL_LCD2:
165 return 0x0408;
166 default:
167 BUG();
168 }
169}
170
171static inline u16 DISPC_DIVISORo(enum omap_channel channel)
172{
173 switch (channel) {
174 case OMAP_DSS_CHANNEL_LCD:
175 return 0x0070;
176 case OMAP_DSS_CHANNEL_DIGIT:
177 BUG();
178 case OMAP_DSS_CHANNEL_LCD2:
179 return 0x040C;
180 default:
181 BUG();
182 }
183}
184
185/* Named as DISPC_SIZE_LCD, DISPC_SIZE_DIGIT and DISPC_SIZE_LCD2 in TRM */
186static inline u16 DISPC_SIZE_MGR(enum omap_channel channel)
187{
188 switch (channel) {
189 case OMAP_DSS_CHANNEL_LCD:
190 return 0x007C;
191 case OMAP_DSS_CHANNEL_DIGIT:
192 return 0x0078;
193 case OMAP_DSS_CHANNEL_LCD2:
194 return 0x03CC;
195 default:
196 BUG();
197 }
198}
199
200static inline u16 DISPC_DATA_CYCLE1(enum omap_channel channel)
201{
202 switch (channel) {
203 case OMAP_DSS_CHANNEL_LCD:
204 return 0x01D4;
205 case OMAP_DSS_CHANNEL_DIGIT:
206 BUG();
207 case OMAP_DSS_CHANNEL_LCD2:
208 return 0x03C0;
209 default:
210 BUG();
211 }
212}
213
214static inline u16 DISPC_DATA_CYCLE2(enum omap_channel channel)
215{
216 switch (channel) {
217 case OMAP_DSS_CHANNEL_LCD:
218 return 0x01D8;
219 case OMAP_DSS_CHANNEL_DIGIT:
220 BUG();
221 case OMAP_DSS_CHANNEL_LCD2:
222 return 0x03C4;
223 default:
224 BUG();
225 }
226}
227
228static inline u16 DISPC_DATA_CYCLE3(enum omap_channel channel)
229{
230 switch (channel) {
231 case OMAP_DSS_CHANNEL_LCD:
232 return 0x01DC;
233 case OMAP_DSS_CHANNEL_DIGIT:
234 BUG();
235 case OMAP_DSS_CHANNEL_LCD2:
236 return 0x03C8;
237 default:
238 BUG();
239 }
240}
241
242static inline u16 DISPC_CPR_COEF_R(enum omap_channel channel)
243{
244 switch (channel) {
245 case OMAP_DSS_CHANNEL_LCD:
246 return 0x0220;
247 case OMAP_DSS_CHANNEL_DIGIT:
248 BUG();
249 case OMAP_DSS_CHANNEL_LCD2:
250 return 0x03BC;
251 default:
252 BUG();
253 }
254}
255
256static inline u16 DISPC_CPR_COEF_G(enum omap_channel channel)
257{
258 switch (channel) {
259 case OMAP_DSS_CHANNEL_LCD:
260 return 0x0224;
261 case OMAP_DSS_CHANNEL_DIGIT:
262 BUG();
263 case OMAP_DSS_CHANNEL_LCD2:
264 return 0x03B8;
265 default:
266 BUG();
267 }
268}
269
270static inline u16 DISPC_CPR_COEF_B(enum omap_channel channel)
271{
272 switch (channel) {
273 case OMAP_DSS_CHANNEL_LCD:
274 return 0x0228;
275 case OMAP_DSS_CHANNEL_DIGIT:
276 BUG();
277 case OMAP_DSS_CHANNEL_LCD2:
278 return 0x03B4;
279 default:
280 BUG();
281 }
282}
283
284/* DISPC overlay register base addresses */
285static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
286{
287 switch (plane) {
288 case OMAP_DSS_GFX:
289 return 0x0080;
290 case OMAP_DSS_VIDEO1:
291 return 0x00BC;
292 case OMAP_DSS_VIDEO2:
293 return 0x014C;
294 default:
295 BUG();
296 }
297}
298
299/* DISPC overlay register offsets */
300static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
301{
302 switch (plane) {
303 case OMAP_DSS_GFX:
304 case OMAP_DSS_VIDEO1:
305 case OMAP_DSS_VIDEO2:
306 return 0x0000;
307 default:
308 BUG();
309 }
310}
311
312static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
313{
314 switch (plane) {
315 case OMAP_DSS_GFX:
316 case OMAP_DSS_VIDEO1:
317 case OMAP_DSS_VIDEO2:
318 return 0x0004;
319 default:
320 BUG();
321 }
322}
323
324static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
325{
326 switch (plane) {
327 case OMAP_DSS_GFX:
328 BUG();
329 case OMAP_DSS_VIDEO1:
330 return 0x0544;
331 case OMAP_DSS_VIDEO2:
332 return 0x04BC;
333 default:
334 BUG();
335 }
336}
337
338static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
339{
340 switch (plane) {
341 case OMAP_DSS_GFX:
342 BUG();
343 case OMAP_DSS_VIDEO1:
344 return 0x0548;
345 case OMAP_DSS_VIDEO2:
346 return 0x04C0;
347 default:
348 BUG();
349 }
350}
351
352static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
353{
354 switch (plane) {
355 case OMAP_DSS_GFX:
356 case OMAP_DSS_VIDEO1:
357 case OMAP_DSS_VIDEO2:
358 return 0x0008;
359 default:
360 BUG();
361 }
362}
363
364static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
365{
366 switch (plane) {
367 case OMAP_DSS_GFX:
368 case OMAP_DSS_VIDEO1:
369 case OMAP_DSS_VIDEO2:
370 return 0x000C;
371 default:
372 BUG();
373 }
374}
375
376static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
377{
378 switch (plane) {
379 case OMAP_DSS_GFX:
380 return 0x0020;
381 case OMAP_DSS_VIDEO1:
382 case OMAP_DSS_VIDEO2:
383 return 0x0010;
384 default:
385 BUG();
386 }
387}
388
389static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
390{
391 switch (plane) {
392 case OMAP_DSS_GFX:
393 BUG();
394 case OMAP_DSS_VIDEO1:
395 return 0x0568;
396 case OMAP_DSS_VIDEO2:
397 return 0x04DC;
398 default:
399 BUG();
400 }
401}
402
403static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
404{
405 switch (plane) {
406 case OMAP_DSS_GFX:
407 return 0x0024;
408 case OMAP_DSS_VIDEO1:
409 case OMAP_DSS_VIDEO2:
410 return 0x0014;
411 default:
412 BUG();
413 }
414}
415
416static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
417{
418 switch (plane) {
419 case OMAP_DSS_GFX:
420 return 0x0028;
421 case OMAP_DSS_VIDEO1:
422 case OMAP_DSS_VIDEO2:
423 return 0x0018;
424 default:
425 BUG();
426 }
427}
428
429static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
430{
431 switch (plane) {
432 case OMAP_DSS_GFX:
433 return 0x002C;
434 case OMAP_DSS_VIDEO1:
435 case OMAP_DSS_VIDEO2:
436 return 0x001C;
437 default:
438 BUG();
439 }
440}
441
442static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
443{
444 switch (plane) {
445 case OMAP_DSS_GFX:
446 return 0x0030;
447 case OMAP_DSS_VIDEO1:
448 case OMAP_DSS_VIDEO2:
449 return 0x0020;
450 default:
451 BUG();
452 }
453}
454
455static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
456{
457 switch (plane) {
458 case OMAP_DSS_GFX:
459 return 0x0034;
460 case OMAP_DSS_VIDEO1:
461 case OMAP_DSS_VIDEO2:
462 BUG();
463 default:
464 BUG();
465 }
466}
467
468static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
469{
470 switch (plane) {
471 case OMAP_DSS_GFX:
472 return 0x0038;
473 case OMAP_DSS_VIDEO1:
474 case OMAP_DSS_VIDEO2:
475 BUG();
476 default:
477 BUG();
478 }
479}
480
481static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
482{
483 switch (plane) {
484 case OMAP_DSS_GFX:
485 BUG();
486 case OMAP_DSS_VIDEO1:
487 case OMAP_DSS_VIDEO2:
488 return 0x0024;
489 default:
490 BUG();
491 }
492}
493
494static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
495{
496 switch (plane) {
497 case OMAP_DSS_GFX:
498 BUG();
499 case OMAP_DSS_VIDEO1:
500 return 0x0580;
501 case OMAP_DSS_VIDEO2:
502 return 0x055C;
503 default:
504 BUG();
505 }
506}
507
508static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
509{
510 switch (plane) {
511 case OMAP_DSS_GFX:
512 BUG();
513 case OMAP_DSS_VIDEO1:
514 case OMAP_DSS_VIDEO2:
515 return 0x0028;
516 default:
517 BUG();
518 }
519}
520
521
522static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
523{
524 switch (plane) {
525 case OMAP_DSS_GFX:
526 BUG();
527 case OMAP_DSS_VIDEO1:
528 case OMAP_DSS_VIDEO2:
529 return 0x002C;
530 default:
531 BUG();
532 }
533}
534
535static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
536{
537 switch (plane) {
538 case OMAP_DSS_GFX:
539 BUG();
540 case OMAP_DSS_VIDEO1:
541 return 0x0584;
542 case OMAP_DSS_VIDEO2:
543 return 0x0560;
544 default:
545 BUG();
546 }
547}
548
549static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
550{
551 switch (plane) {
552 case OMAP_DSS_GFX:
553 BUG();
554 case OMAP_DSS_VIDEO1:
555 case OMAP_DSS_VIDEO2:
556 return 0x0030;
557 default:
558 BUG();
559 }
560}
561
562static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
563{
564 switch (plane) {
565 case OMAP_DSS_GFX:
566 BUG();
567 case OMAP_DSS_VIDEO1:
568 return 0x0588;
569 case OMAP_DSS_VIDEO2:
570 return 0x0564;
571 default:
572 BUG();
573 }
574}
575
576/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
577static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
578{
579 switch (plane) {
580 case OMAP_DSS_GFX:
581 BUG();
582 case OMAP_DSS_VIDEO1:
583 case OMAP_DSS_VIDEO2:
584 return 0x0034 + i * 0x8;
585 default:
586 BUG();
587 }
588}
589
590/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
591static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
592{
593 switch (plane) {
594 case OMAP_DSS_GFX:
595 BUG();
596 case OMAP_DSS_VIDEO1:
597 return 0x058C + i * 0x8;
598 case OMAP_DSS_VIDEO2:
599 return 0x0568 + i * 0x8;
600 default:
601 BUG();
602 }
603}
604
605/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
606static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
607{
608 switch (plane) {
609 case OMAP_DSS_GFX:
610 BUG();
611 case OMAP_DSS_VIDEO1:
612 case OMAP_DSS_VIDEO2:
613 return 0x0038 + i * 0x8;
614 default:
615 BUG();
616 }
617}
618
619/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
620static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
621{
622 switch (plane) {
623 case OMAP_DSS_GFX:
624 BUG();
625 case OMAP_DSS_VIDEO1:
626 return 0x0590 + i * 8;
627 case OMAP_DSS_VIDEO2:
628 return 0x056C + i * 0x8;
629 default:
630 BUG();
631 }
632}
633
634/* coef index i = {0, 1, 2, 3, 4,} */
635static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
636{
637 switch (plane) {
638 case OMAP_DSS_GFX:
639 BUG();
640 case OMAP_DSS_VIDEO1:
641 case OMAP_DSS_VIDEO2:
642 return 0x0074 + i * 0x4;
643 default:
644 BUG();
645 }
646}
647
648/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
649static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
650{
651 switch (plane) {
652 case OMAP_DSS_GFX:
653 BUG();
654 case OMAP_DSS_VIDEO1:
655 return 0x0124 + i * 0x4;
656 case OMAP_DSS_VIDEO2:
657 return 0x00B4 + i * 0x4;
658 default:
659 BUG();
660 }
661}
662
663/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
664static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
665{
666 switch (plane) {
667 case OMAP_DSS_GFX:
668 BUG();
669 case OMAP_DSS_VIDEO1:
670 return 0x05CC + i * 0x4;
671 case OMAP_DSS_VIDEO2:
672 return 0x05A8 + i * 0x4;
673 default:
674 BUG();
675 }
676}
677
678static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
679{
680 switch (plane) {
681 case OMAP_DSS_GFX:
682 return 0x01AC;
683 case OMAP_DSS_VIDEO1:
684 return 0x0174;
685 case OMAP_DSS_VIDEO2:
686 return 0x00E8;
687 default:
688 BUG();
689 }
690}
691#endif
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index a85a6f38b40c..c2dfc8c50057 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -27,7 +27,7 @@
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29 29
30#include <plat/display.h> 30#include <video/omapdss.h>
31#include "dss.h" 31#include "dss.h"
32 32
33static ssize_t display_enabled_show(struct device *dev, 33static ssize_t display_enabled_show(struct device *dev,
@@ -44,9 +44,13 @@ static ssize_t display_enabled_store(struct device *dev,
44 const char *buf, size_t size) 44 const char *buf, size_t size)
45{ 45{
46 struct omap_dss_device *dssdev = to_dss_device(dev); 46 struct omap_dss_device *dssdev = to_dss_device(dev);
47 bool enabled, r; 47 int r, enabled;
48 48
49 enabled = simple_strtoul(buf, NULL, 10); 49 r = kstrtoint(buf, 0, &enabled);
50 if (r)
51 return r;
52
53 enabled = !!enabled;
50 54
51 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 55 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
52 if (enabled) { 56 if (enabled) {
@@ -82,7 +86,9 @@ static ssize_t display_upd_mode_store(struct device *dev,
82 if (!dssdev->driver->set_update_mode) 86 if (!dssdev->driver->set_update_mode)
83 return -EINVAL; 87 return -EINVAL;
84 88
85 val = simple_strtoul(buf, NULL, 10); 89 r = kstrtoint(buf, 0, &val);
90 if (r)
91 return r;
86 92
87 switch (val) { 93 switch (val) {
88 case OMAP_DSS_UPDATE_DISABLED: 94 case OMAP_DSS_UPDATE_DISABLED:
@@ -114,13 +120,16 @@ static ssize_t display_tear_store(struct device *dev,
114 struct device_attribute *attr, const char *buf, size_t size) 120 struct device_attribute *attr, const char *buf, size_t size)
115{ 121{
116 struct omap_dss_device *dssdev = to_dss_device(dev); 122 struct omap_dss_device *dssdev = to_dss_device(dev);
117 unsigned long te; 123 int te, r;
118 int r;
119 124
120 if (!dssdev->driver->enable_te || !dssdev->driver->get_te) 125 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
121 return -ENOENT; 126 return -ENOENT;
122 127
123 te = simple_strtoul(buf, NULL, 0); 128 r = kstrtoint(buf, 0, &te);
129 if (r)
130 return r;
131
132 te = !!te;
124 133
125 r = dssdev->driver->enable_te(dssdev, te); 134 r = dssdev->driver->enable_te(dssdev, te);
126 if (r) 135 if (r)
@@ -196,13 +205,14 @@ static ssize_t display_rotate_store(struct device *dev,
196 struct device_attribute *attr, const char *buf, size_t size) 205 struct device_attribute *attr, const char *buf, size_t size)
197{ 206{
198 struct omap_dss_device *dssdev = to_dss_device(dev); 207 struct omap_dss_device *dssdev = to_dss_device(dev);
199 unsigned long rot; 208 int rot, r;
200 int r;
201 209
202 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) 210 if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
203 return -ENOENT; 211 return -ENOENT;
204 212
205 rot = simple_strtoul(buf, NULL, 0); 213 r = kstrtoint(buf, 0, &rot);
214 if (r)
215 return r;
206 216
207 r = dssdev->driver->set_rotate(dssdev, rot); 217 r = dssdev->driver->set_rotate(dssdev, rot);
208 if (r) 218 if (r)
@@ -226,13 +236,16 @@ static ssize_t display_mirror_store(struct device *dev,
226 struct device_attribute *attr, const char *buf, size_t size) 236 struct device_attribute *attr, const char *buf, size_t size)
227{ 237{
228 struct omap_dss_device *dssdev = to_dss_device(dev); 238 struct omap_dss_device *dssdev = to_dss_device(dev);
229 unsigned long mirror; 239 int mirror, r;
230 int r;
231 240
232 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) 241 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
233 return -ENOENT; 242 return -ENOENT;
234 243
235 mirror = simple_strtoul(buf, NULL, 0); 244 r = kstrtoint(buf, 0, &mirror);
245 if (r)
246 return r;
247
248 mirror = !!mirror;
236 249
237 r = dssdev->driver->set_mirror(dssdev, mirror); 250 r = dssdev->driver->set_mirror(dssdev, mirror);
238 if (r) 251 if (r)
@@ -259,14 +272,15 @@ static ssize_t display_wss_store(struct device *dev,
259 struct device_attribute *attr, const char *buf, size_t size) 272 struct device_attribute *attr, const char *buf, size_t size)
260{ 273{
261 struct omap_dss_device *dssdev = to_dss_device(dev); 274 struct omap_dss_device *dssdev = to_dss_device(dev);
262 unsigned long wss; 275 u32 wss;
263 int r; 276 int r;
264 277
265 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss) 278 if (!dssdev->driver->get_wss || !dssdev->driver->set_wss)
266 return -ENOENT; 279 return -ENOENT;
267 280
268 if (strict_strtoul(buf, 0, &wss)) 281 r = kstrtou32(buf, 0, &wss);
269 return -EINVAL; 282 if (r)
283 return r;
270 284
271 if (wss > 0xfffff) 285 if (wss > 0xfffff)
272 return -EINVAL; 286 return -EINVAL;
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 2d3ca4ca4a05..ff6bd30132df 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -30,16 +30,40 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34#include <plat/cpu.h> 34#include <plat/cpu.h>
35 35
36#include "dss.h" 36#include "dss.h"
37 37
38static struct { 38static struct {
39 struct regulator *vdds_dsi_reg; 39 struct regulator *vdds_dsi_reg;
40 struct platform_device *dsidev;
40} dpi; 41} dpi;
41 42
42#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 43static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
44{
45 int dsi_module;
46
47 dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
48
49 return dsi_get_dsidev_from_id(dsi_module);
50}
51
52static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
53{
54 if (dssdev->clocks.dispc.dispc_fclk_src ==
55 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
56 dssdev->clocks.dispc.dispc_fclk_src ==
57 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
58 dssdev->clocks.dispc.channel.lcd_clk_src ==
59 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
60 dssdev->clocks.dispc.channel.lcd_clk_src ==
61 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
62 return true;
63 else
64 return false;
65}
66
43static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, 67static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
44 unsigned long pck_req, unsigned long *fck, int *lck_div, 68 unsigned long pck_req, unsigned long *fck, int *lck_div,
45 int *pck_div) 69 int *pck_div)
@@ -48,16 +72,16 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
48 struct dispc_clock_info dispc_cinfo; 72 struct dispc_clock_info dispc_cinfo;
49 int r; 73 int r;
50 74
51 r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo, 75 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req,
52 &dispc_cinfo); 76 &dsi_cinfo, &dispc_cinfo);
53 if (r) 77 if (r)
54 return r; 78 return r;
55 79
56 r = dsi_pll_set_clock_div(&dsi_cinfo); 80 r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
57 if (r) 81 if (r)
58 return r; 82 return r;
59 83
60 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); 84 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
61 85
62 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 86 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo);
63 if (r) 87 if (r)
@@ -69,7 +93,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
69 93
70 return 0; 94 return 0;
71} 95}
72#else 96
73static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft, 97static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
74 unsigned long pck_req, unsigned long *fck, int *lck_div, 98 unsigned long pck_req, unsigned long *fck, int *lck_div,
75 int *pck_div) 99 int *pck_div)
@@ -96,13 +120,12 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
96 120
97 return 0; 121 return 0;
98} 122}
99#endif
100 123
101static int dpi_set_mode(struct omap_dss_device *dssdev) 124static int dpi_set_mode(struct omap_dss_device *dssdev)
102{ 125{
103 struct omap_video_timings *t = &dssdev->panel.timings; 126 struct omap_video_timings *t = &dssdev->panel.timings;
104 int lck_div, pck_div; 127 int lck_div = 0, pck_div = 0;
105 unsigned long fck; 128 unsigned long fck = 0;
106 unsigned long pck; 129 unsigned long pck;
107 bool is_tft; 130 bool is_tft;
108 int r = 0; 131 int r = 0;
@@ -114,13 +137,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
114 137
115 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 138 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
116 139
117#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 140 if (dpi_use_dsi_pll(dssdev))
118 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck, 141 r = dpi_set_dsi_clk(dssdev, is_tft, t->pixel_clock * 1000,
119 &lck_div, &pck_div); 142 &fck, &lck_div, &pck_div);
120#else 143 else
121 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000, &fck, 144 r = dpi_set_dispc_clk(dssdev, is_tft, t->pixel_clock * 1000,
122 &lck_div, &pck_div); 145 &fck, &lck_div, &pck_div);
123#endif
124 if (r) 146 if (r)
125 goto err0; 147 goto err0;
126 148
@@ -179,12 +201,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
179 if (r) 201 if (r)
180 goto err2; 202 goto err2;
181 203
182#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 204 if (dpi_use_dsi_pll(dssdev)) {
183 dss_clk_enable(DSS_CLK_SYSCK); 205 dss_clk_enable(DSS_CLK_SYSCK);
184 r = dsi_pll_init(dssdev, 0, 1); 206 r = dsi_pll_init(dpi.dsidev, 0, 1);
185 if (r) 207 if (r)
186 goto err3; 208 goto err3;
187#endif 209 }
210
188 r = dpi_set_mode(dssdev); 211 r = dpi_set_mode(dssdev);
189 if (r) 212 if (r)
190 goto err4; 213 goto err4;
@@ -196,11 +219,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
196 return 0; 219 return 0;
197 220
198err4: 221err4:
199#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 222 if (dpi_use_dsi_pll(dssdev))
200 dsi_pll_uninit(); 223 dsi_pll_uninit(dpi.dsidev, true);
201err3: 224err3:
202 dss_clk_disable(DSS_CLK_SYSCK); 225 if (dpi_use_dsi_pll(dssdev))
203#endif 226 dss_clk_disable(DSS_CLK_SYSCK);
204err2: 227err2:
205 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 228 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
206 if (cpu_is_omap34xx()) 229 if (cpu_is_omap34xx())
@@ -216,11 +239,11 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
216{ 239{
217 dssdev->manager->disable(dssdev->manager); 240 dssdev->manager->disable(dssdev->manager);
218 241
219#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 242 if (dpi_use_dsi_pll(dssdev)) {
220 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); 243 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
221 dsi_pll_uninit(); 244 dsi_pll_uninit(dpi.dsidev, true);
222 dss_clk_disable(DSS_CLK_SYSCK); 245 dss_clk_disable(DSS_CLK_SYSCK);
223#endif 246 }
224 247
225 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 248 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
226 249
@@ -251,6 +274,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
251 int lck_div, pck_div; 274 int lck_div, pck_div;
252 unsigned long fck; 275 unsigned long fck;
253 unsigned long pck; 276 unsigned long pck;
277 struct dispc_clock_info dispc_cinfo;
254 278
255 if (!dispc_lcd_timings_ok(timings)) 279 if (!dispc_lcd_timings_ok(timings))
256 return -EINVAL; 280 return -EINVAL;
@@ -260,11 +284,9 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
260 284
261 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 285 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
262 286
263#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 287 if (dpi_use_dsi_pll(dssdev)) {
264 {
265 struct dsi_clock_info dsi_cinfo; 288 struct dsi_clock_info dsi_cinfo;
266 struct dispc_clock_info dispc_cinfo; 289 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft,
267 r = dsi_pll_calc_clock_div_pck(is_tft,
268 timings->pixel_clock * 1000, 290 timings->pixel_clock * 1000,
269 &dsi_cinfo, &dispc_cinfo); 291 &dsi_cinfo, &dispc_cinfo);
270 292
@@ -272,13 +294,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
272 return r; 294 return r;
273 295
274 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 296 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
275 lck_div = dispc_cinfo.lck_div; 297 } else {
276 pck_div = dispc_cinfo.pck_div;
277 }
278#else
279 {
280 struct dss_clock_info dss_cinfo; 298 struct dss_clock_info dss_cinfo;
281 struct dispc_clock_info dispc_cinfo;
282 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000, 299 r = dss_calc_clock_div(is_tft, timings->pixel_clock * 1000,
283 &dss_cinfo, &dispc_cinfo); 300 &dss_cinfo, &dispc_cinfo);
284 301
@@ -286,10 +303,10 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
286 return r; 303 return r;
287 304
288 fck = dss_cinfo.fck; 305 fck = dss_cinfo.fck;
289 lck_div = dispc_cinfo.lck_div;
290 pck_div = dispc_cinfo.pck_div;
291 } 306 }
292#endif 307
308 lck_div = dispc_cinfo.lck_div;
309 pck_div = dispc_cinfo.pck_div;
293 310
294 pck = fck / lck_div / pck_div / 1000; 311 pck = fck / lck_div / pck_div / 1000;
295 312
@@ -316,6 +333,12 @@ int dpi_init_display(struct omap_dss_device *dssdev)
316 dpi.vdds_dsi_reg = vdds_dsi; 333 dpi.vdds_dsi_reg = vdds_dsi;
317 } 334 }
318 335
336 if (dpi_use_dsi_pll(dssdev)) {
337 enum omap_dss_clk_source dispc_fclk_src =
338 dssdev->clocks.dispc.dispc_fclk_src;
339 dpi.dsidev = dpi_get_dsidev(dispc_fclk_src);
340 }
341
319 return 0; 342 return 0;
320} 343}
321 344
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 0a7f1a47f8e3..345757cfcbee 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -33,8 +33,11 @@
33#include <linux/regulator/consumer.h> 33#include <linux/regulator/consumer.h>
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/sched.h>
37#include <linux/slab.h>
38#include <linux/debugfs.h>
36 39
37#include <plat/display.h> 40#include <video/omapdss.h>
38#include <plat/clock.h> 41#include <plat/clock.h>
39 42
40#include "dss.h" 43#include "dss.h"
@@ -56,6 +59,7 @@ struct dsi_reg { u16 idx; };
56#define DSI_IRQSTATUS DSI_REG(0x0018) 59#define DSI_IRQSTATUS DSI_REG(0x0018)
57#define DSI_IRQENABLE DSI_REG(0x001C) 60#define DSI_IRQENABLE DSI_REG(0x001C)
58#define DSI_CTRL DSI_REG(0x0040) 61#define DSI_CTRL DSI_REG(0x0040)
62#define DSI_GNQ DSI_REG(0x0044)
59#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) 63#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
60#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) 64#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
61#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) 65#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
@@ -90,6 +94,7 @@ struct dsi_reg { u16 idx; };
90#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) 94#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
91#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) 95#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
92#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) 96#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
97#define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028)
93 98
94/* DSI_PLL_CTRL_SCP */ 99/* DSI_PLL_CTRL_SCP */
95 100
@@ -99,11 +104,11 @@ struct dsi_reg { u16 idx; };
99#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) 104#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
100#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) 105#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
101 106
102#define REG_GET(idx, start, end) \ 107#define REG_GET(dsidev, idx, start, end) \
103 FLD_GET(dsi_read_reg(idx), start, end) 108 FLD_GET(dsi_read_reg(dsidev, idx), start, end)
104 109
105#define REG_FLD_MOD(idx, val, start, end) \ 110#define REG_FLD_MOD(dsidev, idx, val, start, end) \
106 dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end)) 111 dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end))
107 112
108/* Global interrupts */ 113/* Global interrupts */
109#define DSI_IRQ_VC0 (1 << 0) 114#define DSI_IRQ_VC0 (1 << 0)
@@ -147,31 +152,50 @@ struct dsi_reg { u16 idx; };
147#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0) 152#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0)
148#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1) 153#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1)
149#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2) 154#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2)
155#define DSI_CIO_IRQ_ERRSYNCESC4 (1 << 3)
156#define DSI_CIO_IRQ_ERRSYNCESC5 (1 << 4)
150#define DSI_CIO_IRQ_ERRESC1 (1 << 5) 157#define DSI_CIO_IRQ_ERRESC1 (1 << 5)
151#define DSI_CIO_IRQ_ERRESC2 (1 << 6) 158#define DSI_CIO_IRQ_ERRESC2 (1 << 6)
152#define DSI_CIO_IRQ_ERRESC3 (1 << 7) 159#define DSI_CIO_IRQ_ERRESC3 (1 << 7)
160#define DSI_CIO_IRQ_ERRESC4 (1 << 8)
161#define DSI_CIO_IRQ_ERRESC5 (1 << 9)
153#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10) 162#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10)
154#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11) 163#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11)
155#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12) 164#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12)
165#define DSI_CIO_IRQ_ERRCONTROL4 (1 << 13)
166#define DSI_CIO_IRQ_ERRCONTROL5 (1 << 14)
156#define DSI_CIO_IRQ_STATEULPS1 (1 << 15) 167#define DSI_CIO_IRQ_STATEULPS1 (1 << 15)
157#define DSI_CIO_IRQ_STATEULPS2 (1 << 16) 168#define DSI_CIO_IRQ_STATEULPS2 (1 << 16)
158#define DSI_CIO_IRQ_STATEULPS3 (1 << 17) 169#define DSI_CIO_IRQ_STATEULPS3 (1 << 17)
170#define DSI_CIO_IRQ_STATEULPS4 (1 << 18)
171#define DSI_CIO_IRQ_STATEULPS5 (1 << 19)
159#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20) 172#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20)
160#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21) 173#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21)
161#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22) 174#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22)
162#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23) 175#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23)
163#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24) 176#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24)
164#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) 177#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
178#define DSI_CIO_IRQ_ERRCONTENTIONLP0_4 (1 << 26)
179#define DSI_CIO_IRQ_ERRCONTENTIONLP1_4 (1 << 27)
180#define DSI_CIO_IRQ_ERRCONTENTIONLP0_5 (1 << 28)
181#define DSI_CIO_IRQ_ERRCONTENTIONLP1_5 (1 << 29)
165#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) 182#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
166#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) 183#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
167#define DSI_CIO_IRQ_ERROR_MASK \ 184#define DSI_CIO_IRQ_ERROR_MASK \
168 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \ 185 (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \
169 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \ 186 DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \
170 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRCONTROL1 | \ 187 DSI_CIO_IRQ_ERRSYNCESC5 | \
171 DSI_CIO_IRQ_ERRCONTROL2 | DSI_CIO_IRQ_ERRCONTROL3 | \ 188 DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \
189 DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \
190 DSI_CIO_IRQ_ERRESC5 | \
191 DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \
192 DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \
193 DSI_CIO_IRQ_ERRCONTROL5 | \
172 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \ 194 DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \
173 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \ 195 DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \
174 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3) 196 DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \
197 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
198 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
175 199
176#define DSI_DT_DCS_SHORT_WRITE_0 0x05 200#define DSI_DT_DCS_SHORT_WRITE_0 0x05
177#define DSI_DT_DCS_SHORT_WRITE_1 0x15 201#define DSI_DT_DCS_SHORT_WRITE_1 0x15
@@ -208,6 +232,19 @@ enum dsi_vc_mode {
208 DSI_VC_MODE_VP, 232 DSI_VC_MODE_VP,
209}; 233};
210 234
235enum dsi_lane {
236 DSI_CLK_P = 1 << 0,
237 DSI_CLK_N = 1 << 1,
238 DSI_DATA1_P = 1 << 2,
239 DSI_DATA1_N = 1 << 3,
240 DSI_DATA2_P = 1 << 4,
241 DSI_DATA2_N = 1 << 5,
242 DSI_DATA3_P = 1 << 6,
243 DSI_DATA3_N = 1 << 7,
244 DSI_DATA4_P = 1 << 8,
245 DSI_DATA4_N = 1 << 9,
246};
247
211struct dsi_update_region { 248struct dsi_update_region {
212 u16 x, y, w, h; 249 u16 x, y, w, h;
213 struct omap_dss_device *device; 250 struct omap_dss_device *device;
@@ -227,14 +264,16 @@ struct dsi_isr_tables {
227 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; 264 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
228}; 265};
229 266
230static struct 267struct dsi_data {
231{
232 struct platform_device *pdev; 268 struct platform_device *pdev;
233 void __iomem *base; 269 void __iomem *base;
234 int irq; 270 int irq;
235 271
272 void (*dsi_mux_pads)(bool enable);
273
236 struct dsi_clock_info current_cinfo; 274 struct dsi_clock_info current_cinfo;
237 275
276 bool vdds_dsi_enabled;
238 struct regulator *vdds_dsi_reg; 277 struct regulator *vdds_dsi_reg;
239 278
240 struct { 279 struct {
@@ -258,8 +297,7 @@ static struct
258 struct dsi_update_region update_region; 297 struct dsi_update_region update_region;
259 298
260 bool te_enabled; 299 bool te_enabled;
261 300 bool ulps_enabled;
262 struct workqueue_struct *workqueue;
263 301
264 void (*framedone_callback)(int, void *); 302 void (*framedone_callback)(int, void *);
265 void *framedone_data; 303 void *framedone_data;
@@ -292,21 +330,63 @@ static struct
292 unsigned long regm_dispc_max, regm_dsi_max; 330 unsigned long regm_dispc_max, regm_dsi_max;
293 unsigned long fint_min, fint_max; 331 unsigned long fint_min, fint_max;
294 unsigned long lpdiv_max; 332 unsigned long lpdiv_max;
295} dsi; 333
334 int num_data_lanes;
335
336 unsigned scp_clk_refcount;
337};
338
339struct dsi_packet_sent_handler_data {
340 struct platform_device *dsidev;
341 struct completion *completion;
342};
343
344static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
296 345
297#ifdef DEBUG 346#ifdef DEBUG
298static unsigned int dsi_perf; 347static unsigned int dsi_perf;
299module_param_named(dsi_perf, dsi_perf, bool, 0644); 348module_param_named(dsi_perf, dsi_perf, bool, 0644);
300#endif 349#endif
301 350
302static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) 351static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dsidev)
303{ 352{
304 __raw_writel(val, dsi.base + idx.idx); 353 return dev_get_drvdata(&dsidev->dev);
305} 354}
306 355
307static inline u32 dsi_read_reg(const struct dsi_reg idx) 356static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
308{ 357{
309 return __raw_readl(dsi.base + idx.idx); 358 return dsi_pdev_map[dssdev->phy.dsi.module];
359}
360
361struct platform_device *dsi_get_dsidev_from_id(int module)
362{
363 return dsi_pdev_map[module];
364}
365
366static int dsi_get_dsidev_id(struct platform_device *dsidev)
367{
368 /* TEMP: Pass 0 as the dsi module index till the time the dsi platform
369 * device names aren't changed to the form "omapdss_dsi.0",
370 * "omapdss_dsi.1" and so on */
371 BUG_ON(dsidev->id != -1);
372
373 return 0;
374}
375
376static inline void dsi_write_reg(struct platform_device *dsidev,
377 const struct dsi_reg idx, u32 val)
378{
379 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
380
381 __raw_writel(val, dsi->base + idx.idx);
382}
383
384static inline u32 dsi_read_reg(struct platform_device *dsidev,
385 const struct dsi_reg idx)
386{
387 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
388
389 return __raw_readl(dsi->base + idx.idx);
310} 390}
311 391
312 392
@@ -318,21 +398,29 @@ void dsi_restore_context(void)
318{ 398{
319} 399}
320 400
321void dsi_bus_lock(void) 401void dsi_bus_lock(struct omap_dss_device *dssdev)
322{ 402{
323 down(&dsi.bus_lock); 403 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
404 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
405
406 down(&dsi->bus_lock);
324} 407}
325EXPORT_SYMBOL(dsi_bus_lock); 408EXPORT_SYMBOL(dsi_bus_lock);
326 409
327void dsi_bus_unlock(void) 410void dsi_bus_unlock(struct omap_dss_device *dssdev)
328{ 411{
329 up(&dsi.bus_lock); 412 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
413 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
414
415 up(&dsi->bus_lock);
330} 416}
331EXPORT_SYMBOL(dsi_bus_unlock); 417EXPORT_SYMBOL(dsi_bus_unlock);
332 418
333static bool dsi_bus_is_locked(void) 419static bool dsi_bus_is_locked(struct platform_device *dsidev)
334{ 420{
335 return dsi.bus_lock.count == 0; 421 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
422
423 return dsi->bus_lock.count == 0;
336} 424}
337 425
338static void dsi_completion_handler(void *data, u32 mask) 426static void dsi_completion_handler(void *data, u32 mask)
@@ -340,12 +428,12 @@ static void dsi_completion_handler(void *data, u32 mask)
340 complete((struct completion *)data); 428 complete((struct completion *)data);
341} 429}
342 430
343static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, 431static inline int wait_for_bit_change(struct platform_device *dsidev,
344 int value) 432 const struct dsi_reg idx, int bitnum, int value)
345{ 433{
346 int t = 100000; 434 int t = 100000;
347 435
348 while (REG_GET(idx, bitnum, bitnum) != value) { 436 while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
349 if (--t == 0) 437 if (--t == 0)
350 return !value; 438 return !value;
351 } 439 }
@@ -354,18 +442,21 @@ static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
354} 442}
355 443
356#ifdef DEBUG 444#ifdef DEBUG
357static void dsi_perf_mark_setup(void) 445static void dsi_perf_mark_setup(struct platform_device *dsidev)
358{ 446{
359 dsi.perf_setup_time = ktime_get(); 447 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
448 dsi->perf_setup_time = ktime_get();
360} 449}
361 450
362static void dsi_perf_mark_start(void) 451static void dsi_perf_mark_start(struct platform_device *dsidev)
363{ 452{
364 dsi.perf_start_time = ktime_get(); 453 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
454 dsi->perf_start_time = ktime_get();
365} 455}
366 456
367static void dsi_perf_show(const char *name) 457static void dsi_perf_show(struct platform_device *dsidev, const char *name)
368{ 458{
459 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
369 ktime_t t, setup_time, trans_time; 460 ktime_t t, setup_time, trans_time;
370 u32 total_bytes; 461 u32 total_bytes;
371 u32 setup_us, trans_us, total_us; 462 u32 setup_us, trans_us, total_us;
@@ -375,21 +466,21 @@ static void dsi_perf_show(const char *name)
375 466
376 t = ktime_get(); 467 t = ktime_get();
377 468
378 setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); 469 setup_time = ktime_sub(dsi->perf_start_time, dsi->perf_setup_time);
379 setup_us = (u32)ktime_to_us(setup_time); 470 setup_us = (u32)ktime_to_us(setup_time);
380 if (setup_us == 0) 471 if (setup_us == 0)
381 setup_us = 1; 472 setup_us = 1;
382 473
383 trans_time = ktime_sub(t, dsi.perf_start_time); 474 trans_time = ktime_sub(t, dsi->perf_start_time);
384 trans_us = (u32)ktime_to_us(trans_time); 475 trans_us = (u32)ktime_to_us(trans_time);
385 if (trans_us == 0) 476 if (trans_us == 0)
386 trans_us = 1; 477 trans_us = 1;
387 478
388 total_us = setup_us + trans_us; 479 total_us = setup_us + trans_us;
389 480
390 total_bytes = dsi.update_region.w * 481 total_bytes = dsi->update_region.w *
391 dsi.update_region.h * 482 dsi->update_region.h *
392 dsi.update_region.device->ctrl.pixel_size / 8; 483 dsi->update_region.device->ctrl.pixel_size / 8;
393 484
394 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " 485 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
395 "%u bytes, %u kbytes/sec\n", 486 "%u bytes, %u kbytes/sec\n",
@@ -402,9 +493,9 @@ static void dsi_perf_show(const char *name)
402 total_bytes * 1000 / total_us); 493 total_bytes * 1000 / total_us);
403} 494}
404#else 495#else
405#define dsi_perf_mark_setup() 496#define dsi_perf_mark_setup(x)
406#define dsi_perf_mark_start() 497#define dsi_perf_mark_start(x)
407#define dsi_perf_show(x) 498#define dsi_perf_show(x, y)
408#endif 499#endif
409 500
410static void print_irq_status(u32 status) 501static void print_irq_status(u32 status)
@@ -510,38 +601,42 @@ static void print_irq_status_cio(u32 status)
510} 601}
511 602
512#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 603#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
513static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) 604static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus,
605 u32 *vcstatus, u32 ciostatus)
514{ 606{
607 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
515 int i; 608 int i;
516 609
517 spin_lock(&dsi.irq_stats_lock); 610 spin_lock(&dsi->irq_stats_lock);
518 611
519 dsi.irq_stats.irq_count++; 612 dsi->irq_stats.irq_count++;
520 dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); 613 dss_collect_irq_stats(irqstatus, dsi->irq_stats.dsi_irqs);
521 614
522 for (i = 0; i < 4; ++i) 615 for (i = 0; i < 4; ++i)
523 dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]); 616 dss_collect_irq_stats(vcstatus[i], dsi->irq_stats.vc_irqs[i]);
524 617
525 dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); 618 dss_collect_irq_stats(ciostatus, dsi->irq_stats.cio_irqs);
526 619
527 spin_unlock(&dsi.irq_stats_lock); 620 spin_unlock(&dsi->irq_stats_lock);
528} 621}
529#else 622#else
530#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus) 623#define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus)
531#endif 624#endif
532 625
533static int debug_irq; 626static int debug_irq;
534 627
535static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus) 628static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus,
629 u32 *vcstatus, u32 ciostatus)
536{ 630{
631 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
537 int i; 632 int i;
538 633
539 if (irqstatus & DSI_IRQ_ERROR_MASK) { 634 if (irqstatus & DSI_IRQ_ERROR_MASK) {
540 DSSERR("DSI error, irqstatus %x\n", irqstatus); 635 DSSERR("DSI error, irqstatus %x\n", irqstatus);
541 print_irq_status(irqstatus); 636 print_irq_status(irqstatus);
542 spin_lock(&dsi.errors_lock); 637 spin_lock(&dsi->errors_lock);
543 dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK; 638 dsi->errors |= irqstatus & DSI_IRQ_ERROR_MASK;
544 spin_unlock(&dsi.errors_lock); 639 spin_unlock(&dsi->errors_lock);
545 } else if (debug_irq) { 640 } else if (debug_irq) {
546 print_irq_status(irqstatus); 641 print_irq_status(irqstatus);
547 } 642 }
@@ -602,22 +697,27 @@ static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
602 697
603static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) 698static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
604{ 699{
700 struct platform_device *dsidev;
701 struct dsi_data *dsi;
605 u32 irqstatus, vcstatus[4], ciostatus; 702 u32 irqstatus, vcstatus[4], ciostatus;
606 int i; 703 int i;
607 704
608 spin_lock(&dsi.irq_lock); 705 dsidev = (struct platform_device *) arg;
706 dsi = dsi_get_dsidrv_data(dsidev);
707
708 spin_lock(&dsi->irq_lock);
609 709
610 irqstatus = dsi_read_reg(DSI_IRQSTATUS); 710 irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
611 711
612 /* IRQ is not for us */ 712 /* IRQ is not for us */
613 if (!irqstatus) { 713 if (!irqstatus) {
614 spin_unlock(&dsi.irq_lock); 714 spin_unlock(&dsi->irq_lock);
615 return IRQ_NONE; 715 return IRQ_NONE;
616 } 716 }
617 717
618 dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); 718 dsi_write_reg(dsidev, DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
619 /* flush posted write */ 719 /* flush posted write */
620 dsi_read_reg(DSI_IRQSTATUS); 720 dsi_read_reg(dsidev, DSI_IRQSTATUS);
621 721
622 for (i = 0; i < 4; ++i) { 722 for (i = 0; i < 4; ++i) {
623 if ((irqstatus & (1 << i)) == 0) { 723 if ((irqstatus & (1 << i)) == 0) {
@@ -625,45 +725,47 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
625 continue; 725 continue;
626 } 726 }
627 727
628 vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i)); 728 vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
629 729
630 dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]); 730 dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]);
631 /* flush posted write */ 731 /* flush posted write */
632 dsi_read_reg(DSI_VC_IRQSTATUS(i)); 732 dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
633 } 733 }
634 734
635 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { 735 if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
636 ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 736 ciostatus = dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
637 737
638 dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); 738 dsi_write_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
639 /* flush posted write */ 739 /* flush posted write */
640 dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); 740 dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
641 } else { 741 } else {
642 ciostatus = 0; 742 ciostatus = 0;
643 } 743 }
644 744
645#ifdef DSI_CATCH_MISSING_TE 745#ifdef DSI_CATCH_MISSING_TE
646 if (irqstatus & DSI_IRQ_TE_TRIGGER) 746 if (irqstatus & DSI_IRQ_TE_TRIGGER)
647 del_timer(&dsi.te_timer); 747 del_timer(&dsi->te_timer);
648#endif 748#endif
649 749
650 /* make a copy and unlock, so that isrs can unregister 750 /* make a copy and unlock, so that isrs can unregister
651 * themselves */ 751 * themselves */
652 memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables)); 752 memcpy(&dsi->isr_tables_copy, &dsi->isr_tables,
753 sizeof(dsi->isr_tables));
653 754
654 spin_unlock(&dsi.irq_lock); 755 spin_unlock(&dsi->irq_lock);
655 756
656 dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus); 757 dsi_handle_isrs(&dsi->isr_tables_copy, irqstatus, vcstatus, ciostatus);
657 758
658 dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus); 759 dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus);
659 760
660 dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus); 761 dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus);
661 762
662 return IRQ_HANDLED; 763 return IRQ_HANDLED;
663} 764}
664 765
665/* dsi.irq_lock has to be locked by the caller */ 766/* dsi->irq_lock has to be locked by the caller */
666static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array, 767static void _omap_dsi_configure_irqs(struct platform_device *dsidev,
768 struct dsi_isr_data *isr_array,
667 unsigned isr_array_size, u32 default_mask, 769 unsigned isr_array_size, u32 default_mask,
668 const struct dsi_reg enable_reg, 770 const struct dsi_reg enable_reg,
669 const struct dsi_reg status_reg) 771 const struct dsi_reg status_reg)
@@ -684,61 +786,67 @@ static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
684 mask |= isr_data->mask; 786 mask |= isr_data->mask;
685 } 787 }
686 788
687 old_mask = dsi_read_reg(enable_reg); 789 old_mask = dsi_read_reg(dsidev, enable_reg);
688 /* clear the irqstatus for newly enabled irqs */ 790 /* clear the irqstatus for newly enabled irqs */
689 dsi_write_reg(status_reg, (mask ^ old_mask) & mask); 791 dsi_write_reg(dsidev, status_reg, (mask ^ old_mask) & mask);
690 dsi_write_reg(enable_reg, mask); 792 dsi_write_reg(dsidev, enable_reg, mask);
691 793
692 /* flush posted writes */ 794 /* flush posted writes */
693 dsi_read_reg(enable_reg); 795 dsi_read_reg(dsidev, enable_reg);
694 dsi_read_reg(status_reg); 796 dsi_read_reg(dsidev, status_reg);
695} 797}
696 798
697/* dsi.irq_lock has to be locked by the caller */ 799/* dsi->irq_lock has to be locked by the caller */
698static void _omap_dsi_set_irqs(void) 800static void _omap_dsi_set_irqs(struct platform_device *dsidev)
699{ 801{
802 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
700 u32 mask = DSI_IRQ_ERROR_MASK; 803 u32 mask = DSI_IRQ_ERROR_MASK;
701#ifdef DSI_CATCH_MISSING_TE 804#ifdef DSI_CATCH_MISSING_TE
702 mask |= DSI_IRQ_TE_TRIGGER; 805 mask |= DSI_IRQ_TE_TRIGGER;
703#endif 806#endif
704 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table, 807 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table,
705 ARRAY_SIZE(dsi.isr_tables.isr_table), mask, 808 ARRAY_SIZE(dsi->isr_tables.isr_table), mask,
706 DSI_IRQENABLE, DSI_IRQSTATUS); 809 DSI_IRQENABLE, DSI_IRQSTATUS);
707} 810}
708 811
709/* dsi.irq_lock has to be locked by the caller */ 812/* dsi->irq_lock has to be locked by the caller */
710static void _omap_dsi_set_irqs_vc(int vc) 813static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc)
711{ 814{
712 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc], 815 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
713 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]), 816
817 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_vc[vc],
818 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]),
714 DSI_VC_IRQ_ERROR_MASK, 819 DSI_VC_IRQ_ERROR_MASK,
715 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc)); 820 DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
716} 821}
717 822
718/* dsi.irq_lock has to be locked by the caller */ 823/* dsi->irq_lock has to be locked by the caller */
719static void _omap_dsi_set_irqs_cio(void) 824static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev)
720{ 825{
721 _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio, 826 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
722 ARRAY_SIZE(dsi.isr_tables.isr_table_cio), 827
828 _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_cio,
829 ARRAY_SIZE(dsi->isr_tables.isr_table_cio),
723 DSI_CIO_IRQ_ERROR_MASK, 830 DSI_CIO_IRQ_ERROR_MASK,
724 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS); 831 DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
725} 832}
726 833
727static void _dsi_initialize_irq(void) 834static void _dsi_initialize_irq(struct platform_device *dsidev)
728{ 835{
836 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
729 unsigned long flags; 837 unsigned long flags;
730 int vc; 838 int vc;
731 839
732 spin_lock_irqsave(&dsi.irq_lock, flags); 840 spin_lock_irqsave(&dsi->irq_lock, flags);
733 841
734 memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables)); 842 memset(&dsi->isr_tables, 0, sizeof(dsi->isr_tables));
735 843
736 _omap_dsi_set_irqs(); 844 _omap_dsi_set_irqs(dsidev);
737 for (vc = 0; vc < 4; ++vc) 845 for (vc = 0; vc < 4; ++vc)
738 _omap_dsi_set_irqs_vc(vc); 846 _omap_dsi_set_irqs_vc(dsidev, vc);
739 _omap_dsi_set_irqs_cio(); 847 _omap_dsi_set_irqs_cio(dsidev);
740 848
741 spin_unlock_irqrestore(&dsi.irq_lock, flags); 849 spin_unlock_irqrestore(&dsi->irq_lock, flags);
742} 850}
743 851
744static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask, 852static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
@@ -797,126 +905,137 @@ static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
797 return -EINVAL; 905 return -EINVAL;
798} 906}
799 907
800static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask) 908static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr,
909 void *arg, u32 mask)
801{ 910{
911 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
802 unsigned long flags; 912 unsigned long flags;
803 int r; 913 int r;
804 914
805 spin_lock_irqsave(&dsi.irq_lock, flags); 915 spin_lock_irqsave(&dsi->irq_lock, flags);
806 916
807 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table, 917 r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table,
808 ARRAY_SIZE(dsi.isr_tables.isr_table)); 918 ARRAY_SIZE(dsi->isr_tables.isr_table));
809 919
810 if (r == 0) 920 if (r == 0)
811 _omap_dsi_set_irqs(); 921 _omap_dsi_set_irqs(dsidev);
812 922
813 spin_unlock_irqrestore(&dsi.irq_lock, flags); 923 spin_unlock_irqrestore(&dsi->irq_lock, flags);
814 924
815 return r; 925 return r;
816} 926}
817 927
818static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask) 928static int dsi_unregister_isr(struct platform_device *dsidev,
929 omap_dsi_isr_t isr, void *arg, u32 mask)
819{ 930{
931 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
820 unsigned long flags; 932 unsigned long flags;
821 int r; 933 int r;
822 934
823 spin_lock_irqsave(&dsi.irq_lock, flags); 935 spin_lock_irqsave(&dsi->irq_lock, flags);
824 936
825 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table, 937 r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table,
826 ARRAY_SIZE(dsi.isr_tables.isr_table)); 938 ARRAY_SIZE(dsi->isr_tables.isr_table));
827 939
828 if (r == 0) 940 if (r == 0)
829 _omap_dsi_set_irqs(); 941 _omap_dsi_set_irqs(dsidev);
830 942
831 spin_unlock_irqrestore(&dsi.irq_lock, flags); 943 spin_unlock_irqrestore(&dsi->irq_lock, flags);
832 944
833 return r; 945 return r;
834} 946}
835 947
836static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, 948static int dsi_register_isr_vc(struct platform_device *dsidev, int channel,
837 u32 mask) 949 omap_dsi_isr_t isr, void *arg, u32 mask)
838{ 950{
951 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
839 unsigned long flags; 952 unsigned long flags;
840 int r; 953 int r;
841 954
842 spin_lock_irqsave(&dsi.irq_lock, flags); 955 spin_lock_irqsave(&dsi->irq_lock, flags);
843 956
844 r = _dsi_register_isr(isr, arg, mask, 957 r = _dsi_register_isr(isr, arg, mask,
845 dsi.isr_tables.isr_table_vc[channel], 958 dsi->isr_tables.isr_table_vc[channel],
846 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); 959 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
847 960
848 if (r == 0) 961 if (r == 0)
849 _omap_dsi_set_irqs_vc(channel); 962 _omap_dsi_set_irqs_vc(dsidev, channel);
850 963
851 spin_unlock_irqrestore(&dsi.irq_lock, flags); 964 spin_unlock_irqrestore(&dsi->irq_lock, flags);
852 965
853 return r; 966 return r;
854} 967}
855 968
856static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, 969static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel,
857 u32 mask) 970 omap_dsi_isr_t isr, void *arg, u32 mask)
858{ 971{
972 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
859 unsigned long flags; 973 unsigned long flags;
860 int r; 974 int r;
861 975
862 spin_lock_irqsave(&dsi.irq_lock, flags); 976 spin_lock_irqsave(&dsi->irq_lock, flags);
863 977
864 r = _dsi_unregister_isr(isr, arg, mask, 978 r = _dsi_unregister_isr(isr, arg, mask,
865 dsi.isr_tables.isr_table_vc[channel], 979 dsi->isr_tables.isr_table_vc[channel],
866 ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); 980 ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
867 981
868 if (r == 0) 982 if (r == 0)
869 _omap_dsi_set_irqs_vc(channel); 983 _omap_dsi_set_irqs_vc(dsidev, channel);
870 984
871 spin_unlock_irqrestore(&dsi.irq_lock, flags); 985 spin_unlock_irqrestore(&dsi->irq_lock, flags);
872 986
873 return r; 987 return r;
874} 988}
875 989
876static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) 990static int dsi_register_isr_cio(struct platform_device *dsidev,
991 omap_dsi_isr_t isr, void *arg, u32 mask)
877{ 992{
993 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
878 unsigned long flags; 994 unsigned long flags;
879 int r; 995 int r;
880 996
881 spin_lock_irqsave(&dsi.irq_lock, flags); 997 spin_lock_irqsave(&dsi->irq_lock, flags);
882 998
883 r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, 999 r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
884 ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); 1000 ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
885 1001
886 if (r == 0) 1002 if (r == 0)
887 _omap_dsi_set_irqs_cio(); 1003 _omap_dsi_set_irqs_cio(dsidev);
888 1004
889 spin_unlock_irqrestore(&dsi.irq_lock, flags); 1005 spin_unlock_irqrestore(&dsi->irq_lock, flags);
890 1006
891 return r; 1007 return r;
892} 1008}
893 1009
894static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) 1010static int dsi_unregister_isr_cio(struct platform_device *dsidev,
1011 omap_dsi_isr_t isr, void *arg, u32 mask)
895{ 1012{
1013 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
896 unsigned long flags; 1014 unsigned long flags;
897 int r; 1015 int r;
898 1016
899 spin_lock_irqsave(&dsi.irq_lock, flags); 1017 spin_lock_irqsave(&dsi->irq_lock, flags);
900 1018
901 r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, 1019 r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
902 ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); 1020 ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
903 1021
904 if (r == 0) 1022 if (r == 0)
905 _omap_dsi_set_irqs_cio(); 1023 _omap_dsi_set_irqs_cio(dsidev);
906 1024
907 spin_unlock_irqrestore(&dsi.irq_lock, flags); 1025 spin_unlock_irqrestore(&dsi->irq_lock, flags);
908 1026
909 return r; 1027 return r;
910} 1028}
911 1029
912static u32 dsi_get_errors(void) 1030static u32 dsi_get_errors(struct platform_device *dsidev)
913{ 1031{
1032 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
914 unsigned long flags; 1033 unsigned long flags;
915 u32 e; 1034 u32 e;
916 spin_lock_irqsave(&dsi.errors_lock, flags); 1035 spin_lock_irqsave(&dsi->errors_lock, flags);
917 e = dsi.errors; 1036 e = dsi->errors;
918 dsi.errors = 0; 1037 dsi->errors = 0;
919 spin_unlock_irqrestore(&dsi.errors_lock, flags); 1038 spin_unlock_irqrestore(&dsi->errors_lock, flags);
920 return e; 1039 return e;
921} 1040}
922 1041
@@ -930,23 +1049,27 @@ static inline void enable_clocks(bool enable)
930} 1049}
931 1050
932/* source clock for DSI PLL. this could also be PCLKFREE */ 1051/* source clock for DSI PLL. this could also be PCLKFREE */
933static inline void dsi_enable_pll_clock(bool enable) 1052static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1053 bool enable)
934{ 1054{
1055 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1056
935 if (enable) 1057 if (enable)
936 dss_clk_enable(DSS_CLK_SYSCK); 1058 dss_clk_enable(DSS_CLK_SYSCK);
937 else 1059 else
938 dss_clk_disable(DSS_CLK_SYSCK); 1060 dss_clk_disable(DSS_CLK_SYSCK);
939 1061
940 if (enable && dsi.pll_locked) { 1062 if (enable && dsi->pll_locked) {
941 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) 1063 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
942 DSSERR("cannot lock PLL when enabling clocks\n"); 1064 DSSERR("cannot lock PLL when enabling clocks\n");
943 } 1065 }
944} 1066}
945 1067
946#ifdef DEBUG 1068#ifdef DEBUG
947static void _dsi_print_reset_status(void) 1069static void _dsi_print_reset_status(struct platform_device *dsidev)
948{ 1070{
949 u32 l; 1071 u32 l;
1072 int b0, b1, b2;
950 1073
951 if (!dss_debug) 1074 if (!dss_debug)
952 return; 1075 return;
@@ -954,35 +1077,47 @@ static void _dsi_print_reset_status(void)
954 /* A dummy read using the SCP interface to any DSIPHY register is 1077 /* A dummy read using the SCP interface to any DSIPHY register is
955 * required after DSIPHY reset to complete the reset of the DSI complex 1078 * required after DSIPHY reset to complete the reset of the DSI complex
956 * I/O. */ 1079 * I/O. */
957 l = dsi_read_reg(DSI_DSIPHY_CFG5); 1080 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
958 1081
959 printk(KERN_DEBUG "DSI resets: "); 1082 printk(KERN_DEBUG "DSI resets: ");
960 1083
961 l = dsi_read_reg(DSI_PLL_STATUS); 1084 l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
962 printk("PLL (%d) ", FLD_GET(l, 0, 0)); 1085 printk("PLL (%d) ", FLD_GET(l, 0, 0));
963 1086
964 l = dsi_read_reg(DSI_COMPLEXIO_CFG1); 1087 l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
965 printk("CIO (%d) ", FLD_GET(l, 29, 29)); 1088 printk("CIO (%d) ", FLD_GET(l, 29, 29));
966 1089
967 l = dsi_read_reg(DSI_DSIPHY_CFG5); 1090 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
968 printk("PHY (%x, %d, %d, %d)\n", 1091 b0 = 28;
969 FLD_GET(l, 28, 26), 1092 b1 = 27;
1093 b2 = 26;
1094 } else {
1095 b0 = 24;
1096 b1 = 25;
1097 b2 = 26;
1098 }
1099
1100 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
1101 printk("PHY (%x%x%x, %d, %d, %d)\n",
1102 FLD_GET(l, b0, b0),
1103 FLD_GET(l, b1, b1),
1104 FLD_GET(l, b2, b2),
970 FLD_GET(l, 29, 29), 1105 FLD_GET(l, 29, 29),
971 FLD_GET(l, 30, 30), 1106 FLD_GET(l, 30, 30),
972 FLD_GET(l, 31, 31)); 1107 FLD_GET(l, 31, 31));
973} 1108}
974#else 1109#else
975#define _dsi_print_reset_status() 1110#define _dsi_print_reset_status(x)
976#endif 1111#endif
977 1112
978static inline int dsi_if_enable(bool enable) 1113static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
979{ 1114{
980 DSSDBG("dsi_if_enable(%d)\n", enable); 1115 DSSDBG("dsi_if_enable(%d)\n", enable);
981 1116
982 enable = enable ? 1 : 0; 1117 enable = enable ? 1 : 0;
983 REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */ 1118 REG_FLD_MOD(dsidev, DSI_CTRL, enable, 0, 0); /* IF_EN */
984 1119
985 if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) { 1120 if (wait_for_bit_change(dsidev, DSI_CTRL, 0, enable) != enable) {
986 DSSERR("Failed to set dsi_if_enable to %d\n", enable); 1121 DSSERR("Failed to set dsi_if_enable to %d\n", enable);
987 return -EIO; 1122 return -EIO;
988 } 1123 }
@@ -990,31 +1125,38 @@ static inline int dsi_if_enable(bool enable)
990 return 0; 1125 return 0;
991} 1126}
992 1127
993unsigned long dsi_get_pll_hsdiv_dispc_rate(void) 1128unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
994{ 1129{
995 return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; 1130 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1131
1132 return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk;
996} 1133}
997 1134
998static unsigned long dsi_get_pll_hsdiv_dsi_rate(void) 1135static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
999{ 1136{
1000 return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; 1137 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1138
1139 return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk;
1001} 1140}
1002 1141
1003static unsigned long dsi_get_txbyteclkhs(void) 1142static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
1004{ 1143{
1005 return dsi.current_cinfo.clkin4ddr / 16; 1144 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1145
1146 return dsi->current_cinfo.clkin4ddr / 16;
1006} 1147}
1007 1148
1008static unsigned long dsi_fclk_rate(void) 1149static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1009{ 1150{
1010 unsigned long r; 1151 unsigned long r;
1152 int dsi_module = dsi_get_dsidev_id(dsidev);
1011 1153
1012 if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) { 1154 if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) {
1013 /* DSI FCLK source is DSS_CLK_FCK */ 1155 /* DSI FCLK source is DSS_CLK_FCK */
1014 r = dss_clk_get_rate(DSS_CLK_FCK); 1156 r = dss_clk_get_rate(DSS_CLK_FCK);
1015 } else { 1157 } else {
1016 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ 1158 /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
1017 r = dsi_get_pll_hsdiv_dsi_rate(); 1159 r = dsi_get_pll_hsdiv_dsi_rate(dsidev);
1018 } 1160 }
1019 1161
1020 return r; 1162 return r;
@@ -1022,31 +1164,50 @@ static unsigned long dsi_fclk_rate(void)
1022 1164
1023static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) 1165static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
1024{ 1166{
1167 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1168 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1025 unsigned long dsi_fclk; 1169 unsigned long dsi_fclk;
1026 unsigned lp_clk_div; 1170 unsigned lp_clk_div;
1027 unsigned long lp_clk; 1171 unsigned long lp_clk;
1028 1172
1029 lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; 1173 lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
1030 1174
1031 if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max) 1175 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
1032 return -EINVAL; 1176 return -EINVAL;
1033 1177
1034 dsi_fclk = dsi_fclk_rate(); 1178 dsi_fclk = dsi_fclk_rate(dsidev);
1035 1179
1036 lp_clk = dsi_fclk / 2 / lp_clk_div; 1180 lp_clk = dsi_fclk / 2 / lp_clk_div;
1037 1181
1038 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); 1182 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
1039 dsi.current_cinfo.lp_clk = lp_clk; 1183 dsi->current_cinfo.lp_clk = lp_clk;
1040 dsi.current_cinfo.lp_clk_div = lp_clk_div; 1184 dsi->current_cinfo.lp_clk_div = lp_clk_div;
1041 1185
1042 REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0); /* LP_CLK_DIVISOR */ 1186 /* LP_CLK_DIVISOR */
1187 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
1043 1188
1044 REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 1189 /* LP_RX_SYNCHRO_ENABLE */
1045 21, 21); /* LP_RX_SYNCHRO_ENABLE */ 1190 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 21, 21);
1046 1191
1047 return 0; 1192 return 0;
1048} 1193}
1049 1194
1195static void dsi_enable_scp_clk(struct platform_device *dsidev)
1196{
1197 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1198
1199 if (dsi->scp_clk_refcount++ == 0)
1200 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */
1201}
1202
1203static void dsi_disable_scp_clk(struct platform_device *dsidev)
1204{
1205 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1206
1207 WARN_ON(dsi->scp_clk_refcount == 0);
1208 if (--dsi->scp_clk_refcount == 0)
1209 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */
1210}
1050 1211
1051enum dsi_pll_power_state { 1212enum dsi_pll_power_state {
1052 DSI_PLL_POWER_OFF = 0x0, 1213 DSI_PLL_POWER_OFF = 0x0,
@@ -1055,14 +1216,21 @@ enum dsi_pll_power_state {
1055 DSI_PLL_POWER_ON_DIV = 0x3, 1216 DSI_PLL_POWER_ON_DIV = 0x3,
1056}; 1217};
1057 1218
1058static int dsi_pll_power(enum dsi_pll_power_state state) 1219static int dsi_pll_power(struct platform_device *dsidev,
1220 enum dsi_pll_power_state state)
1059{ 1221{
1060 int t = 0; 1222 int t = 0;
1061 1223
1062 REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ 1224 /* DSI-PLL power command 0x3 is not working */
1225 if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) &&
1226 state == DSI_PLL_POWER_ON_DIV)
1227 state = DSI_PLL_POWER_ON_ALL;
1228
1229 /* PLL_PWR_CMD */
1230 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, state, 31, 30);
1063 1231
1064 /* PLL_PWR_STATUS */ 1232 /* PLL_PWR_STATUS */
1065 while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { 1233 while (FLD_GET(dsi_read_reg(dsidev, DSI_CLK_CTRL), 29, 28) != state) {
1066 if (++t > 1000) { 1234 if (++t > 1000) {
1067 DSSERR("Failed to set DSI PLL power mode to %d\n", 1235 DSSERR("Failed to set DSI PLL power mode to %d\n",
1068 state); 1236 state);
@@ -1078,16 +1246,19 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
1078static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, 1246static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1079 struct dsi_clock_info *cinfo) 1247 struct dsi_clock_info *cinfo)
1080{ 1248{
1081 if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max) 1249 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1250 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1251
1252 if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
1082 return -EINVAL; 1253 return -EINVAL;
1083 1254
1084 if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max) 1255 if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max)
1085 return -EINVAL; 1256 return -EINVAL;
1086 1257
1087 if (cinfo->regm_dispc > dsi.regm_dispc_max) 1258 if (cinfo->regm_dispc > dsi->regm_dispc_max)
1088 return -EINVAL; 1259 return -EINVAL;
1089 1260
1090 if (cinfo->regm_dsi > dsi.regm_dsi_max) 1261 if (cinfo->regm_dsi > dsi->regm_dsi_max)
1091 return -EINVAL; 1262 return -EINVAL;
1092 1263
1093 if (cinfo->use_sys_clk) { 1264 if (cinfo->use_sys_clk) {
@@ -1106,7 +1277,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1106 1277
1107 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); 1278 cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
1108 1279
1109 if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min) 1280 if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
1110 return -EINVAL; 1281 return -EINVAL;
1111 1282
1112 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; 1283 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -1129,10 +1300,11 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1129 return 0; 1300 return 0;
1130} 1301}
1131 1302
1132int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 1303int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
1133 struct dsi_clock_info *dsi_cinfo, 1304 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
1134 struct dispc_clock_info *dispc_cinfo) 1305 struct dispc_clock_info *dispc_cinfo)
1135{ 1306{
1307 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1136 struct dsi_clock_info cur, best; 1308 struct dsi_clock_info cur, best;
1137 struct dispc_clock_info best_dispc; 1309 struct dispc_clock_info best_dispc;
1138 int min_fck_per_pck; 1310 int min_fck_per_pck;
@@ -1143,10 +1315,10 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
1143 1315
1144 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); 1316 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1145 1317
1146 if (req_pck == dsi.cache_req_pck && 1318 if (req_pck == dsi->cache_req_pck &&
1147 dsi.cache_cinfo.clkin == dss_sys_clk) { 1319 dsi->cache_cinfo.clkin == dss_sys_clk) {
1148 DSSDBG("DSI clock info found from cache\n"); 1320 DSSDBG("DSI clock info found from cache\n");
1149 *dsi_cinfo = dsi.cache_cinfo; 1321 *dsi_cinfo = dsi->cache_cinfo;
1150 dispc_find_clk_divs(is_tft, req_pck, 1322 dispc_find_clk_divs(is_tft, req_pck,
1151 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); 1323 dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
1152 return 0; 1324 return 0;
@@ -1176,17 +1348,17 @@ retry:
1176 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ 1348 /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
1177 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ 1349 /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
1178 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ 1350 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
1179 for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) { 1351 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
1180 if (cur.highfreq == 0) 1352 if (cur.highfreq == 0)
1181 cur.fint = cur.clkin / cur.regn; 1353 cur.fint = cur.clkin / cur.regn;
1182 else 1354 else
1183 cur.fint = cur.clkin / (2 * cur.regn); 1355 cur.fint = cur.clkin / (2 * cur.regn);
1184 1356
1185 if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min) 1357 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
1186 continue; 1358 continue;
1187 1359
1188 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ 1360 /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
1189 for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) { 1361 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
1190 unsigned long a, b; 1362 unsigned long a, b;
1191 1363
1192 a = 2 * cur.regm * (cur.clkin/1000); 1364 a = 2 * cur.regm * (cur.clkin/1000);
@@ -1198,8 +1370,8 @@ retry:
1198 1370
1199 /* dsi_pll_hsdiv_dispc_clk(MHz) = 1371 /* dsi_pll_hsdiv_dispc_clk(MHz) =
1200 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ 1372 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
1201 for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max; 1373 for (cur.regm_dispc = 1; cur.regm_dispc <
1202 ++cur.regm_dispc) { 1374 dsi->regm_dispc_max; ++cur.regm_dispc) {
1203 struct dispc_clock_info cur_dispc; 1375 struct dispc_clock_info cur_dispc;
1204 cur.dsi_pll_hsdiv_dispc_clk = 1376 cur.dsi_pll_hsdiv_dispc_clk =
1205 cur.clkin4ddr / cur.regm_dispc; 1377 cur.clkin4ddr / cur.regm_dispc;
@@ -1259,34 +1431,39 @@ found:
1259 if (dispc_cinfo) 1431 if (dispc_cinfo)
1260 *dispc_cinfo = best_dispc; 1432 *dispc_cinfo = best_dispc;
1261 1433
1262 dsi.cache_req_pck = req_pck; 1434 dsi->cache_req_pck = req_pck;
1263 dsi.cache_clk_freq = 0; 1435 dsi->cache_clk_freq = 0;
1264 dsi.cache_cinfo = best; 1436 dsi->cache_cinfo = best;
1265 1437
1266 return 0; 1438 return 0;
1267} 1439}
1268 1440
1269int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) 1441int dsi_pll_set_clock_div(struct platform_device *dsidev,
1442 struct dsi_clock_info *cinfo)
1270{ 1443{
1444 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1271 int r = 0; 1445 int r = 0;
1272 u32 l; 1446 u32 l;
1273 int f; 1447 int f = 0;
1274 u8 regn_start, regn_end, regm_start, regm_end; 1448 u8 regn_start, regn_end, regm_start, regm_end;
1275 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; 1449 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
1276 1450
1277 DSSDBGF(); 1451 DSSDBGF();
1278 1452
1279 dsi.current_cinfo.fint = cinfo->fint; 1453 dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk;
1280 dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; 1454 dsi->current_cinfo.highfreq = cinfo->highfreq;
1281 dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = 1455
1456 dsi->current_cinfo.fint = cinfo->fint;
1457 dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
1458 dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
1282 cinfo->dsi_pll_hsdiv_dispc_clk; 1459 cinfo->dsi_pll_hsdiv_dispc_clk;
1283 dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk = 1460 dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk =
1284 cinfo->dsi_pll_hsdiv_dsi_clk; 1461 cinfo->dsi_pll_hsdiv_dsi_clk;
1285 1462
1286 dsi.current_cinfo.regn = cinfo->regn; 1463 dsi->current_cinfo.regn = cinfo->regn;
1287 dsi.current_cinfo.regm = cinfo->regm; 1464 dsi->current_cinfo.regm = cinfo->regm;
1288 dsi.current_cinfo.regm_dispc = cinfo->regm_dispc; 1465 dsi->current_cinfo.regm_dispc = cinfo->regm_dispc;
1289 dsi.current_cinfo.regm_dsi = cinfo->regm_dsi; 1466 dsi->current_cinfo.regm_dsi = cinfo->regm_dsi;
1290 1467
1291 DSSDBG("DSI Fint %ld\n", cinfo->fint); 1468 DSSDBG("DSI Fint %ld\n", cinfo->fint);
1292 1469
@@ -1309,12 +1486,12 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1309 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); 1486 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1310 1487
1311 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, 1488 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1312 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), 1489 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1313 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), 1490 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1314 cinfo->dsi_pll_hsdiv_dispc_clk); 1491 cinfo->dsi_pll_hsdiv_dispc_clk);
1315 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, 1492 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1316 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), 1493 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1317 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), 1494 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1318 cinfo->dsi_pll_hsdiv_dsi_clk); 1495 cinfo->dsi_pll_hsdiv_dsi_clk);
1319 1496
1320 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end); 1497 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
@@ -1324,9 +1501,10 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1324 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start, 1501 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1325 &regm_dsi_end); 1502 &regm_dsi_end);
1326 1503
1327 REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ 1504 /* DSI_PLL_AUTOMODE = manual */
1505 REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
1328 1506
1329 l = dsi_read_reg(DSI_PLL_CONFIGURATION1); 1507 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
1330 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ 1508 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1331 /* DSI_PLL_REGN */ 1509 /* DSI_PLL_REGN */
1332 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); 1510 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
@@ -1338,22 +1516,22 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1338 /* DSIPROTO_CLOCK_DIV */ 1516 /* DSIPROTO_CLOCK_DIV */
1339 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, 1517 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1340 regm_dsi_start, regm_dsi_end); 1518 regm_dsi_start, regm_dsi_end);
1341 dsi_write_reg(DSI_PLL_CONFIGURATION1, l); 1519 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
1342 1520
1343 BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max); 1521 BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
1344 if (cinfo->fint < 1000000) 1522
1345 f = 0x3; 1523 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
1346 else if (cinfo->fint < 1250000) 1524 f = cinfo->fint < 1000000 ? 0x3 :
1347 f = 0x4; 1525 cinfo->fint < 1250000 ? 0x4 :
1348 else if (cinfo->fint < 1500000) 1526 cinfo->fint < 1500000 ? 0x5 :
1349 f = 0x5; 1527 cinfo->fint < 1750000 ? 0x6 :
1350 else if (cinfo->fint < 1750000) 1528 0x7;
1351 f = 0x6; 1529 }
1352 else 1530
1353 f = 0x7; 1531 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1354 1532
1355 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1533 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
1356 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ 1534 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1357 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, 1535 l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1,
1358 11, 11); /* DSI_PLL_CLKSEL */ 1536 11, 11); /* DSI_PLL_CLKSEL */
1359 l = FLD_MOD(l, cinfo->highfreq, 1537 l = FLD_MOD(l, cinfo->highfreq,
@@ -1361,25 +1539,25 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1361 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ 1539 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
1362 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ 1540 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
1363 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ 1541 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
1364 dsi_write_reg(DSI_PLL_CONFIGURATION2, l); 1542 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1365 1543
1366 REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ 1544 REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
1367 1545
1368 if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) { 1546 if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) {
1369 DSSERR("dsi pll go bit not going down.\n"); 1547 DSSERR("dsi pll go bit not going down.\n");
1370 r = -EIO; 1548 r = -EIO;
1371 goto err; 1549 goto err;
1372 } 1550 }
1373 1551
1374 if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { 1552 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) {
1375 DSSERR("cannot lock PLL\n"); 1553 DSSERR("cannot lock PLL\n");
1376 r = -EIO; 1554 r = -EIO;
1377 goto err; 1555 goto err;
1378 } 1556 }
1379 1557
1380 dsi.pll_locked = 1; 1558 dsi->pll_locked = 1;
1381 1559
1382 l = dsi_read_reg(DSI_PLL_CONFIGURATION2); 1560 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1383 l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ 1561 l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */
1384 l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ 1562 l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */
1385 l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ 1563 l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */
@@ -1394,52 +1572,53 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
1394 l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ 1572 l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */
1395 l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ 1573 l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */
1396 l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ 1574 l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
1397 dsi_write_reg(DSI_PLL_CONFIGURATION2, l); 1575 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1398 1576
1399 DSSDBG("PLL config done\n"); 1577 DSSDBG("PLL config done\n");
1400err: 1578err:
1401 return r; 1579 return r;
1402} 1580}
1403 1581
1404int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, 1582int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1405 bool enable_hsdiv) 1583 bool enable_hsdiv)
1406{ 1584{
1585 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1407 int r = 0; 1586 int r = 0;
1408 enum dsi_pll_power_state pwstate; 1587 enum dsi_pll_power_state pwstate;
1409 1588
1410 DSSDBG("PLL init\n"); 1589 DSSDBG("PLL init\n");
1411 1590
1412#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL 1591 if (dsi->vdds_dsi_reg == NULL) {
1413 /*
1414 * HACK: this is just a quick hack to get the USE_DSI_PLL
1415 * option working. USE_DSI_PLL is itself a big hack, and
1416 * should be removed.
1417 */
1418 if (dsi.vdds_dsi_reg == NULL) {
1419 struct regulator *vdds_dsi; 1592 struct regulator *vdds_dsi;
1420 1593
1421 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); 1594 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
1422 1595
1423 if (IS_ERR(vdds_dsi)) { 1596 if (IS_ERR(vdds_dsi)) {
1424 DSSERR("can't get VDDS_DSI regulator\n"); 1597 DSSERR("can't get VDDS_DSI regulator\n");
1425 return PTR_ERR(vdds_dsi); 1598 return PTR_ERR(vdds_dsi);
1426 } 1599 }
1427 1600
1428 dsi.vdds_dsi_reg = vdds_dsi; 1601 dsi->vdds_dsi_reg = vdds_dsi;
1429 } 1602 }
1430#endif
1431 1603
1432 enable_clocks(1); 1604 enable_clocks(1);
1433 dsi_enable_pll_clock(1); 1605 dsi_enable_pll_clock(dsidev, 1);
1606 /*
1607 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
1608 */
1609 dsi_enable_scp_clk(dsidev);
1434 1610
1435 r = regulator_enable(dsi.vdds_dsi_reg); 1611 if (!dsi->vdds_dsi_enabled) {
1436 if (r) 1612 r = regulator_enable(dsi->vdds_dsi_reg);
1437 goto err0; 1613 if (r)
1614 goto err0;
1615 dsi->vdds_dsi_enabled = true;
1616 }
1438 1617
1439 /* XXX PLL does not come out of reset without this... */ 1618 /* XXX PLL does not come out of reset without this... */
1440 dispc_pck_free_enable(1); 1619 dispc_pck_free_enable(1);
1441 1620
1442 if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { 1621 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 0, 1) != 1) {
1443 DSSERR("PLL not coming out of reset.\n"); 1622 DSSERR("PLL not coming out of reset.\n");
1444 r = -ENODEV; 1623 r = -ENODEV;
1445 dispc_pck_free_enable(0); 1624 dispc_pck_free_enable(0);
@@ -1459,7 +1638,7 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1459 else 1638 else
1460 pwstate = DSI_PLL_POWER_OFF; 1639 pwstate = DSI_PLL_POWER_OFF;
1461 1640
1462 r = dsi_pll_power(pwstate); 1641 r = dsi_pll_power(dsidev, pwstate);
1463 1642
1464 if (r) 1643 if (r)
1465 goto err1; 1644 goto err1;
@@ -1468,42 +1647,53 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1468 1647
1469 return 0; 1648 return 0;
1470err1: 1649err1:
1471 regulator_disable(dsi.vdds_dsi_reg); 1650 if (dsi->vdds_dsi_enabled) {
1651 regulator_disable(dsi->vdds_dsi_reg);
1652 dsi->vdds_dsi_enabled = false;
1653 }
1472err0: 1654err0:
1655 dsi_disable_scp_clk(dsidev);
1473 enable_clocks(0); 1656 enable_clocks(0);
1474 dsi_enable_pll_clock(0); 1657 dsi_enable_pll_clock(dsidev, 0);
1475 return r; 1658 return r;
1476} 1659}
1477 1660
1478void dsi_pll_uninit(void) 1661void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1479{ 1662{
1663 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1664
1665 dsi->pll_locked = 0;
1666 dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
1667 if (disconnect_lanes) {
1668 WARN_ON(!dsi->vdds_dsi_enabled);
1669 regulator_disable(dsi->vdds_dsi_reg);
1670 dsi->vdds_dsi_enabled = false;
1671 }
1672
1673 dsi_disable_scp_clk(dsidev);
1480 enable_clocks(0); 1674 enable_clocks(0);
1481 dsi_enable_pll_clock(0); 1675 dsi_enable_pll_clock(dsidev, 0);
1482 1676
1483 dsi.pll_locked = 0;
1484 dsi_pll_power(DSI_PLL_POWER_OFF);
1485 regulator_disable(dsi.vdds_dsi_reg);
1486 DSSDBG("PLL uninit done\n"); 1677 DSSDBG("PLL uninit done\n");
1487} 1678}
1488 1679
1489void dsi_dump_clocks(struct seq_file *s) 1680static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1681 struct seq_file *s)
1490{ 1682{
1491 int clksel; 1683 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1492 struct dsi_clock_info *cinfo = &dsi.current_cinfo; 1684 struct dsi_clock_info *cinfo = &dsi->current_cinfo;
1493 enum dss_clk_source dispc_clk_src, dsi_clk_src; 1685 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
1686 int dsi_module = dsi_get_dsidev_id(dsidev);
1494 1687
1495 dispc_clk_src = dss_get_dispc_clk_source(); 1688 dispc_clk_src = dss_get_dispc_clk_source();
1496 dsi_clk_src = dss_get_dsi_clk_source(); 1689 dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
1497 1690
1498 enable_clocks(1); 1691 enable_clocks(1);
1499 1692
1500 clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11); 1693 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
1501
1502 seq_printf(s, "- DSI PLL -\n");
1503 1694
1504 seq_printf(s, "dsi pll source = %s\n", 1695 seq_printf(s, "dsi pll source = %s\n",
1505 clksel == 0 ? 1696 cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree");
1506 "dss_sys_clk" : "pclkfree");
1507 1697
1508 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1698 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn);
1509 1699
@@ -1515,7 +1705,7 @@ void dsi_dump_clocks(struct seq_file *s)
1515 dss_feat_get_clk_source_name(dispc_clk_src), 1705 dss_feat_get_clk_source_name(dispc_clk_src),
1516 cinfo->dsi_pll_hsdiv_dispc_clk, 1706 cinfo->dsi_pll_hsdiv_dispc_clk,
1517 cinfo->regm_dispc, 1707 cinfo->regm_dispc,
1518 dispc_clk_src == DSS_CLK_SRC_FCK ? 1708 dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1519 "off" : "on"); 1709 "off" : "on");
1520 1710
1521 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n", 1711 seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
@@ -1523,45 +1713,55 @@ void dsi_dump_clocks(struct seq_file *s)
1523 dss_feat_get_clk_source_name(dsi_clk_src), 1713 dss_feat_get_clk_source_name(dsi_clk_src),
1524 cinfo->dsi_pll_hsdiv_dsi_clk, 1714 cinfo->dsi_pll_hsdiv_dsi_clk,
1525 cinfo->regm_dsi, 1715 cinfo->regm_dsi,
1526 dsi_clk_src == DSS_CLK_SRC_FCK ? 1716 dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1527 "off" : "on"); 1717 "off" : "on");
1528 1718
1529 seq_printf(s, "- DSI -\n"); 1719 seq_printf(s, "- DSI%d -\n", dsi_module + 1);
1530 1720
1531 seq_printf(s, "dsi fclk source = %s (%s)\n", 1721 seq_printf(s, "dsi fclk source = %s (%s)\n",
1532 dss_get_generic_clk_source_name(dsi_clk_src), 1722 dss_get_generic_clk_source_name(dsi_clk_src),
1533 dss_feat_get_clk_source_name(dsi_clk_src)); 1723 dss_feat_get_clk_source_name(dsi_clk_src));
1534 1724
1535 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); 1725 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
1536 1726
1537 seq_printf(s, "DDR_CLK\t\t%lu\n", 1727 seq_printf(s, "DDR_CLK\t\t%lu\n",
1538 cinfo->clkin4ddr / 4); 1728 cinfo->clkin4ddr / 4);
1539 1729
1540 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs()); 1730 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
1541 1731
1542 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1732 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk);
1543 1733
1544 seq_printf(s, "VP_CLK\t\t%lu\n"
1545 "VP_PCLK\t\t%lu\n",
1546 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD),
1547 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD));
1548
1549 enable_clocks(0); 1734 enable_clocks(0);
1550} 1735}
1551 1736
1737void dsi_dump_clocks(struct seq_file *s)
1738{
1739 struct platform_device *dsidev;
1740 int i;
1741
1742 for (i = 0; i < MAX_NUM_DSI; i++) {
1743 dsidev = dsi_get_dsidev_from_id(i);
1744 if (dsidev)
1745 dsi_dump_dsidev_clocks(dsidev, s);
1746 }
1747}
1748
1552#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 1749#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
1553void dsi_dump_irqs(struct seq_file *s) 1750static void dsi_dump_dsidev_irqs(struct platform_device *dsidev,
1751 struct seq_file *s)
1554{ 1752{
1753 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1555 unsigned long flags; 1754 unsigned long flags;
1556 struct dsi_irq_stats stats; 1755 struct dsi_irq_stats stats;
1756 int dsi_module = dsi_get_dsidev_id(dsidev);
1557 1757
1558 spin_lock_irqsave(&dsi.irq_stats_lock, flags); 1758 spin_lock_irqsave(&dsi->irq_stats_lock, flags);
1559 1759
1560 stats = dsi.irq_stats; 1760 stats = dsi->irq_stats;
1561 memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); 1761 memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats));
1562 dsi.irq_stats.last_reset = jiffies; 1762 dsi->irq_stats.last_reset = jiffies;
1563 1763
1564 spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); 1764 spin_unlock_irqrestore(&dsi->irq_stats_lock, flags);
1565 1765
1566 seq_printf(s, "period %u ms\n", 1766 seq_printf(s, "period %u ms\n",
1567 jiffies_to_msecs(jiffies - stats.last_reset)); 1767 jiffies_to_msecs(jiffies - stats.last_reset));
@@ -1570,7 +1770,7 @@ void dsi_dump_irqs(struct seq_file *s)
1570#define PIS(x) \ 1770#define PIS(x) \
1571 seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); 1771 seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
1572 1772
1573 seq_printf(s, "-- DSI interrupts --\n"); 1773 seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1);
1574 PIS(VC0); 1774 PIS(VC0);
1575 PIS(VC1); 1775 PIS(VC1);
1576 PIS(VC2); 1776 PIS(VC2);
@@ -1636,13 +1836,45 @@ void dsi_dump_irqs(struct seq_file *s)
1636 PIS(ULPSACTIVENOT_ALL1); 1836 PIS(ULPSACTIVENOT_ALL1);
1637#undef PIS 1837#undef PIS
1638} 1838}
1839
1840static void dsi1_dump_irqs(struct seq_file *s)
1841{
1842 struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
1843
1844 dsi_dump_dsidev_irqs(dsidev, s);
1845}
1846
1847static void dsi2_dump_irqs(struct seq_file *s)
1848{
1849 struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
1850
1851 dsi_dump_dsidev_irqs(dsidev, s);
1852}
1853
1854void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
1855 const struct file_operations *debug_fops)
1856{
1857 struct platform_device *dsidev;
1858
1859 dsidev = dsi_get_dsidev_from_id(0);
1860 if (dsidev)
1861 debugfs_create_file("dsi1_irqs", S_IRUGO, debugfs_dir,
1862 &dsi1_dump_irqs, debug_fops);
1863
1864 dsidev = dsi_get_dsidev_from_id(1);
1865 if (dsidev)
1866 debugfs_create_file("dsi2_irqs", S_IRUGO, debugfs_dir,
1867 &dsi2_dump_irqs, debug_fops);
1868}
1639#endif 1869#endif
1640 1870
1641void dsi_dump_regs(struct seq_file *s) 1871static void dsi_dump_dsidev_regs(struct platform_device *dsidev,
1872 struct seq_file *s)
1642{ 1873{
1643#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) 1874#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
1644 1875
1645 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 1876 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
1877 dsi_enable_scp_clk(dsidev);
1646 1878
1647 DUMPREG(DSI_REVISION); 1879 DUMPREG(DSI_REVISION);
1648 DUMPREG(DSI_SYSCONFIG); 1880 DUMPREG(DSI_SYSCONFIG);
@@ -1714,25 +1946,57 @@ void dsi_dump_regs(struct seq_file *s)
1714 DUMPREG(DSI_PLL_CONFIGURATION1); 1946 DUMPREG(DSI_PLL_CONFIGURATION1);
1715 DUMPREG(DSI_PLL_CONFIGURATION2); 1947 DUMPREG(DSI_PLL_CONFIGURATION2);
1716 1948
1949 dsi_disable_scp_clk(dsidev);
1717 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 1950 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
1718#undef DUMPREG 1951#undef DUMPREG
1719} 1952}
1720 1953
1721enum dsi_complexio_power_state { 1954static void dsi1_dump_regs(struct seq_file *s)
1955{
1956 struct platform_device *dsidev = dsi_get_dsidev_from_id(0);
1957
1958 dsi_dump_dsidev_regs(dsidev, s);
1959}
1960
1961static void dsi2_dump_regs(struct seq_file *s)
1962{
1963 struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
1964
1965 dsi_dump_dsidev_regs(dsidev, s);
1966}
1967
1968void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
1969 const struct file_operations *debug_fops)
1970{
1971 struct platform_device *dsidev;
1972
1973 dsidev = dsi_get_dsidev_from_id(0);
1974 if (dsidev)
1975 debugfs_create_file("dsi1_regs", S_IRUGO, debugfs_dir,
1976 &dsi1_dump_regs, debug_fops);
1977
1978 dsidev = dsi_get_dsidev_from_id(1);
1979 if (dsidev)
1980 debugfs_create_file("dsi2_regs", S_IRUGO, debugfs_dir,
1981 &dsi2_dump_regs, debug_fops);
1982}
1983enum dsi_cio_power_state {
1722 DSI_COMPLEXIO_POWER_OFF = 0x0, 1984 DSI_COMPLEXIO_POWER_OFF = 0x0,
1723 DSI_COMPLEXIO_POWER_ON = 0x1, 1985 DSI_COMPLEXIO_POWER_ON = 0x1,
1724 DSI_COMPLEXIO_POWER_ULPS = 0x2, 1986 DSI_COMPLEXIO_POWER_ULPS = 0x2,
1725}; 1987};
1726 1988
1727static int dsi_complexio_power(enum dsi_complexio_power_state state) 1989static int dsi_cio_power(struct platform_device *dsidev,
1990 enum dsi_cio_power_state state)
1728{ 1991{
1729 int t = 0; 1992 int t = 0;
1730 1993
1731 /* PWR_CMD */ 1994 /* PWR_CMD */
1732 REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27); 1995 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27);
1733 1996
1734 /* PWR_STATUS */ 1997 /* PWR_STATUS */
1735 while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { 1998 while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1),
1999 26, 25) != state) {
1736 if (++t > 1000) { 2000 if (++t > 1000) {
1737 DSSERR("failed to set complexio power state to " 2001 DSSERR("failed to set complexio power state to "
1738 "%d\n", state); 2002 "%d\n", state);
@@ -1744,9 +2008,70 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state)
1744 return 0; 2008 return 0;
1745} 2009}
1746 2010
1747static void dsi_complexio_config(struct omap_dss_device *dssdev) 2011/* Number of data lanes present on DSI interface */
2012static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
1748{ 2013{
2014 /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
2015 * of data lanes as 2 by default */
2016 if (dss_has_feature(FEAT_DSI_GNQ))
2017 return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
2018 else
2019 return 2;
2020}
2021
2022/* Number of data lanes used by the dss device */
2023static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
2024{
2025 int num_data_lanes = 0;
2026
2027 if (dssdev->phy.dsi.data1_lane != 0)
2028 num_data_lanes++;
2029 if (dssdev->phy.dsi.data2_lane != 0)
2030 num_data_lanes++;
2031 if (dssdev->phy.dsi.data3_lane != 0)
2032 num_data_lanes++;
2033 if (dssdev->phy.dsi.data4_lane != 0)
2034 num_data_lanes++;
2035
2036 return num_data_lanes;
2037}
2038
2039static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
2040{
2041 int val;
2042
2043 /* line buffer on OMAP3 is 1024 x 24bits */
2044 /* XXX: for some reason using full buffer size causes
2045 * considerable TX slowdown with update sizes that fill the
2046 * whole buffer */
2047 if (!dss_has_feature(FEAT_DSI_GNQ))
2048 return 1023 * 3;
2049
2050 val = REG_GET(dsidev, DSI_GNQ, 14, 12); /* VP1_LINE_BUFFER_SIZE */
2051
2052 switch (val) {
2053 case 1:
2054 return 512 * 3; /* 512x24 bits */
2055 case 2:
2056 return 682 * 3; /* 682x24 bits */
2057 case 3:
2058 return 853 * 3; /* 853x24 bits */
2059 case 4:
2060 return 1024 * 3; /* 1024x24 bits */
2061 case 5:
2062 return 1194 * 3; /* 1194x24 bits */
2063 case 6:
2064 return 1365 * 3; /* 1365x24 bits */
2065 default:
2066 BUG();
2067 }
2068}
2069
2070static void dsi_set_lane_config(struct omap_dss_device *dssdev)
2071{
2072 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1749 u32 r; 2073 u32 r;
2074 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
1750 2075
1751 int clk_lane = dssdev->phy.dsi.clk_lane; 2076 int clk_lane = dssdev->phy.dsi.clk_lane;
1752 int data1_lane = dssdev->phy.dsi.data1_lane; 2077 int data1_lane = dssdev->phy.dsi.data1_lane;
@@ -1755,14 +2080,28 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev)
1755 int data1_pol = dssdev->phy.dsi.data1_pol; 2080 int data1_pol = dssdev->phy.dsi.data1_pol;
1756 int data2_pol = dssdev->phy.dsi.data2_pol; 2081 int data2_pol = dssdev->phy.dsi.data2_pol;
1757 2082
1758 r = dsi_read_reg(DSI_COMPLEXIO_CFG1); 2083 r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
1759 r = FLD_MOD(r, clk_lane, 2, 0); 2084 r = FLD_MOD(r, clk_lane, 2, 0);
1760 r = FLD_MOD(r, clk_pol, 3, 3); 2085 r = FLD_MOD(r, clk_pol, 3, 3);
1761 r = FLD_MOD(r, data1_lane, 6, 4); 2086 r = FLD_MOD(r, data1_lane, 6, 4);
1762 r = FLD_MOD(r, data1_pol, 7, 7); 2087 r = FLD_MOD(r, data1_pol, 7, 7);
1763 r = FLD_MOD(r, data2_lane, 10, 8); 2088 r = FLD_MOD(r, data2_lane, 10, 8);
1764 r = FLD_MOD(r, data2_pol, 11, 11); 2089 r = FLD_MOD(r, data2_pol, 11, 11);
1765 dsi_write_reg(DSI_COMPLEXIO_CFG1, r); 2090 if (num_data_lanes_dssdev > 2) {
2091 int data3_lane = dssdev->phy.dsi.data3_lane;
2092 int data3_pol = dssdev->phy.dsi.data3_pol;
2093
2094 r = FLD_MOD(r, data3_lane, 14, 12);
2095 r = FLD_MOD(r, data3_pol, 15, 15);
2096 }
2097 if (num_data_lanes_dssdev > 3) {
2098 int data4_lane = dssdev->phy.dsi.data4_lane;
2099 int data4_pol = dssdev->phy.dsi.data4_pol;
2100
2101 r = FLD_MOD(r, data4_lane, 18, 16);
2102 r = FLD_MOD(r, data4_pol, 19, 19);
2103 }
2104 dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
1766 2105
1767 /* The configuration of the DSI complex I/O (number of data lanes, 2106 /* The configuration of the DSI complex I/O (number of data lanes,
1768 position, differential order) should not be changed while 2107 position, differential order) should not be changed while
@@ -1776,27 +2115,31 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev)
1776 DSI complex I/O configuration is unknown. */ 2115 DSI complex I/O configuration is unknown. */
1777 2116
1778 /* 2117 /*
1779 REG_FLD_MOD(DSI_CTRL, 1, 0, 0); 2118 REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
1780 REG_FLD_MOD(DSI_CTRL, 0, 0, 0); 2119 REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
1781 REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); 2120 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
1782 REG_FLD_MOD(DSI_CTRL, 1, 0, 0); 2121 REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
1783 */ 2122 */
1784} 2123}
1785 2124
1786static inline unsigned ns2ddr(unsigned ns) 2125static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
1787{ 2126{
2127 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2128
1788 /* convert time in ns to ddr ticks, rounding up */ 2129 /* convert time in ns to ddr ticks, rounding up */
1789 unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; 2130 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
1790 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; 2131 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
1791} 2132}
1792 2133
1793static inline unsigned ddr2ns(unsigned ddr) 2134static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
1794{ 2135{
1795 unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; 2136 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2137
2138 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
1796 return ddr * 1000 * 1000 / (ddr_clk / 1000); 2139 return ddr * 1000 * 1000 / (ddr_clk / 1000);
1797} 2140}
1798 2141
1799static void dsi_complexio_timings(void) 2142static void dsi_cio_timings(struct platform_device *dsidev)
1800{ 2143{
1801 u32 r; 2144 u32 r;
1802 u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; 2145 u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
@@ -1808,139 +2151,323 @@ static void dsi_complexio_timings(void)
1808 /* 1 * DDR_CLK = 2 * UI */ 2151 /* 1 * DDR_CLK = 2 * UI */
1809 2152
1810 /* min 40ns + 4*UI max 85ns + 6*UI */ 2153 /* min 40ns + 4*UI max 85ns + 6*UI */
1811 ths_prepare = ns2ddr(70) + 2; 2154 ths_prepare = ns2ddr(dsidev, 70) + 2;
1812 2155
1813 /* min 145ns + 10*UI */ 2156 /* min 145ns + 10*UI */
1814 ths_prepare_ths_zero = ns2ddr(175) + 2; 2157 ths_prepare_ths_zero = ns2ddr(dsidev, 175) + 2;
1815 2158
1816 /* min max(8*UI, 60ns+4*UI) */ 2159 /* min max(8*UI, 60ns+4*UI) */
1817 ths_trail = ns2ddr(60) + 5; 2160 ths_trail = ns2ddr(dsidev, 60) + 5;
1818 2161
1819 /* min 100ns */ 2162 /* min 100ns */
1820 ths_exit = ns2ddr(145); 2163 ths_exit = ns2ddr(dsidev, 145);
1821 2164
1822 /* tlpx min 50n */ 2165 /* tlpx min 50n */
1823 tlpx_half = ns2ddr(25); 2166 tlpx_half = ns2ddr(dsidev, 25);
1824 2167
1825 /* min 60ns */ 2168 /* min 60ns */
1826 tclk_trail = ns2ddr(60) + 2; 2169 tclk_trail = ns2ddr(dsidev, 60) + 2;
1827 2170
1828 /* min 38ns, max 95ns */ 2171 /* min 38ns, max 95ns */
1829 tclk_prepare = ns2ddr(65); 2172 tclk_prepare = ns2ddr(dsidev, 65);
1830 2173
1831 /* min tclk-prepare + tclk-zero = 300ns */ 2174 /* min tclk-prepare + tclk-zero = 300ns */
1832 tclk_zero = ns2ddr(260); 2175 tclk_zero = ns2ddr(dsidev, 260);
1833 2176
1834 DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n", 2177 DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n",
1835 ths_prepare, ddr2ns(ths_prepare), 2178 ths_prepare, ddr2ns(dsidev, ths_prepare),
1836 ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero)); 2179 ths_prepare_ths_zero, ddr2ns(dsidev, ths_prepare_ths_zero));
1837 DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n", 2180 DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n",
1838 ths_trail, ddr2ns(ths_trail), 2181 ths_trail, ddr2ns(dsidev, ths_trail),
1839 ths_exit, ddr2ns(ths_exit)); 2182 ths_exit, ddr2ns(dsidev, ths_exit));
1840 2183
1841 DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), " 2184 DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), "
1842 "tclk_zero %u (%uns)\n", 2185 "tclk_zero %u (%uns)\n",
1843 tlpx_half, ddr2ns(tlpx_half), 2186 tlpx_half, ddr2ns(dsidev, tlpx_half),
1844 tclk_trail, ddr2ns(tclk_trail), 2187 tclk_trail, ddr2ns(dsidev, tclk_trail),
1845 tclk_zero, ddr2ns(tclk_zero)); 2188 tclk_zero, ddr2ns(dsidev, tclk_zero));
1846 DSSDBG("tclk_prepare %u (%uns)\n", 2189 DSSDBG("tclk_prepare %u (%uns)\n",
1847 tclk_prepare, ddr2ns(tclk_prepare)); 2190 tclk_prepare, ddr2ns(dsidev, tclk_prepare));
1848 2191
1849 /* program timings */ 2192 /* program timings */
1850 2193
1851 r = dsi_read_reg(DSI_DSIPHY_CFG0); 2194 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
1852 r = FLD_MOD(r, ths_prepare, 31, 24); 2195 r = FLD_MOD(r, ths_prepare, 31, 24);
1853 r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16); 2196 r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
1854 r = FLD_MOD(r, ths_trail, 15, 8); 2197 r = FLD_MOD(r, ths_trail, 15, 8);
1855 r = FLD_MOD(r, ths_exit, 7, 0); 2198 r = FLD_MOD(r, ths_exit, 7, 0);
1856 dsi_write_reg(DSI_DSIPHY_CFG0, r); 2199 dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r);
1857 2200
1858 r = dsi_read_reg(DSI_DSIPHY_CFG1); 2201 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
1859 r = FLD_MOD(r, tlpx_half, 22, 16); 2202 r = FLD_MOD(r, tlpx_half, 22, 16);
1860 r = FLD_MOD(r, tclk_trail, 15, 8); 2203 r = FLD_MOD(r, tclk_trail, 15, 8);
1861 r = FLD_MOD(r, tclk_zero, 7, 0); 2204 r = FLD_MOD(r, tclk_zero, 7, 0);
1862 dsi_write_reg(DSI_DSIPHY_CFG1, r); 2205 dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
1863 2206
1864 r = dsi_read_reg(DSI_DSIPHY_CFG2); 2207 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
1865 r = FLD_MOD(r, tclk_prepare, 7, 0); 2208 r = FLD_MOD(r, tclk_prepare, 7, 0);
1866 dsi_write_reg(DSI_DSIPHY_CFG2, r); 2209 dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
1867} 2210}
1868 2211
2212static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
2213 enum dsi_lane lanes)
2214{
2215 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2216 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2217 int clk_lane = dssdev->phy.dsi.clk_lane;
2218 int data1_lane = dssdev->phy.dsi.data1_lane;
2219 int data2_lane = dssdev->phy.dsi.data2_lane;
2220 int data3_lane = dssdev->phy.dsi.data3_lane;
2221 int data4_lane = dssdev->phy.dsi.data4_lane;
2222 int clk_pol = dssdev->phy.dsi.clk_pol;
2223 int data1_pol = dssdev->phy.dsi.data1_pol;
2224 int data2_pol = dssdev->phy.dsi.data2_pol;
2225 int data3_pol = dssdev->phy.dsi.data3_pol;
2226 int data4_pol = dssdev->phy.dsi.data4_pol;
2227
2228 u32 l = 0;
2229 u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26;
2230
2231 if (lanes & DSI_CLK_P)
2232 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
2233 if (lanes & DSI_CLK_N)
2234 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0));
2235
2236 if (lanes & DSI_DATA1_P)
2237 l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1));
2238 if (lanes & DSI_DATA1_N)
2239 l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0));
2240
2241 if (lanes & DSI_DATA2_P)
2242 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1));
2243 if (lanes & DSI_DATA2_N)
2244 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
2245
2246 if (lanes & DSI_DATA3_P)
2247 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
2248 if (lanes & DSI_DATA3_N)
2249 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
2250
2251 if (lanes & DSI_DATA4_P)
2252 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
2253 if (lanes & DSI_DATA4_N)
2254 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
2255 /*
2256 * Bits in REGLPTXSCPDAT4TO0DXDY:
2257 * 17: DY0 18: DX0
2258 * 19: DY1 20: DX1
2259 * 21: DY2 22: DX2
2260 * 23: DY3 24: DX3
2261 * 25: DY4 26: DX4
2262 */
2263
2264 /* Set the lane override configuration */
2265
2266 /* REGLPTXSCPDAT4TO0DXDY */
2267 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, lptxscp_start, 17);
1869 2268
1870static int dsi_complexio_init(struct omap_dss_device *dssdev) 2269 /* Enable lane override */
2270
2271 /* ENLPTXSCPDAT */
2272 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 1, 27, 27);
2273}
2274
2275static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
1871{ 2276{
1872 int r = 0; 2277 /* Disable lane override */
2278 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
2279 /* Reset the lane override configuration */
2280 /* REGLPTXSCPDAT4TO0DXDY */
2281 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17);
2282}
2283
2284static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
2285{
2286 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2287 int t;
2288 int bits[3];
2289 bool in_use[3];
2290
2291 if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
2292 bits[0] = 28;
2293 bits[1] = 27;
2294 bits[2] = 26;
2295 } else {
2296 bits[0] = 24;
2297 bits[1] = 25;
2298 bits[2] = 26;
2299 }
2300
2301 in_use[0] = false;
2302 in_use[1] = false;
2303 in_use[2] = false;
2304
2305 if (dssdev->phy.dsi.clk_lane != 0)
2306 in_use[dssdev->phy.dsi.clk_lane - 1] = true;
2307 if (dssdev->phy.dsi.data1_lane != 0)
2308 in_use[dssdev->phy.dsi.data1_lane - 1] = true;
2309 if (dssdev->phy.dsi.data2_lane != 0)
2310 in_use[dssdev->phy.dsi.data2_lane - 1] = true;
2311
2312 t = 100000;
2313 while (true) {
2314 u32 l;
2315 int i;
2316 int ok;
2317
2318 l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
2319
2320 ok = 0;
2321 for (i = 0; i < 3; ++i) {
2322 if (!in_use[i] || (l & (1 << bits[i])))
2323 ok++;
2324 }
2325
2326 if (ok == 3)
2327 break;
2328
2329 if (--t == 0) {
2330 for (i = 0; i < 3; ++i) {
2331 if (!in_use[i] || (l & (1 << bits[i])))
2332 continue;
2333
2334 DSSERR("CIO TXCLKESC%d domain not coming " \
2335 "out of reset\n", i);
2336 }
2337 return -EIO;
2338 }
2339 }
2340
2341 return 0;
2342}
2343
2344static int dsi_cio_init(struct omap_dss_device *dssdev)
2345{
2346 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2347 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2348 int r;
2349 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
2350 u32 l;
1873 2351
1874 DSSDBG("dsi_complexio_init\n"); 2352 DSSDBGF();
1875 2353
1876 /* CIO_CLK_ICG, enable L3 clk to CIO */ 2354 if (dsi->dsi_mux_pads)
1877 REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); 2355 dsi->dsi_mux_pads(true);
2356
2357 dsi_enable_scp_clk(dsidev);
1878 2358
1879 /* A dummy read using the SCP interface to any DSIPHY register is 2359 /* A dummy read using the SCP interface to any DSIPHY register is
1880 * required after DSIPHY reset to complete the reset of the DSI complex 2360 * required after DSIPHY reset to complete the reset of the DSI complex
1881 * I/O. */ 2361 * I/O. */
1882 dsi_read_reg(DSI_DSIPHY_CFG5); 2362 dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
1883 2363
1884 if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) { 2364 if (wait_for_bit_change(dsidev, DSI_DSIPHY_CFG5, 30, 1) != 1) {
1885 DSSERR("ComplexIO PHY not coming out of reset.\n"); 2365 DSSERR("CIO SCP Clock domain not coming out of reset.\n");
1886 r = -ENODEV; 2366 r = -EIO;
1887 goto err; 2367 goto err_scp_clk_dom;
1888 } 2368 }
1889 2369
1890 dsi_complexio_config(dssdev); 2370 dsi_set_lane_config(dssdev);
2371
2372 /* set TX STOP MODE timer to maximum for this operation */
2373 l = dsi_read_reg(dsidev, DSI_TIMING1);
2374 l = FLD_MOD(l, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2375 l = FLD_MOD(l, 1, 14, 14); /* STOP_STATE_X16_IO */
2376 l = FLD_MOD(l, 1, 13, 13); /* STOP_STATE_X4_IO */
2377 l = FLD_MOD(l, 0x1fff, 12, 0); /* STOP_STATE_COUNTER_IO */
2378 dsi_write_reg(dsidev, DSI_TIMING1, l);
1891 2379
1892 r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON); 2380 if (dsi->ulps_enabled) {
2381 u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
1893 2382
2383 DSSDBG("manual ulps exit\n");
2384
2385 /* ULPS is exited by Mark-1 state for 1ms, followed by
2386 * stop state. DSS HW cannot do this via the normal
2387 * ULPS exit sequence, as after reset the DSS HW thinks
2388 * that we are not in ULPS mode, and refuses to send the
2389 * sequence. So we need to send the ULPS exit sequence
2390 * manually.
2391 */
2392
2393 if (num_data_lanes_dssdev > 2)
2394 lane_mask |= DSI_DATA3_P;
2395
2396 if (num_data_lanes_dssdev > 3)
2397 lane_mask |= DSI_DATA4_P;
2398
2399 dsi_cio_enable_lane_override(dssdev, lane_mask);
2400 }
2401
2402 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
1894 if (r) 2403 if (r)
1895 goto err; 2404 goto err_cio_pwr;
1896 2405
1897 if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) { 2406 if (wait_for_bit_change(dsidev, DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
1898 DSSERR("ComplexIO not coming out of reset.\n"); 2407 DSSERR("CIO PWR clock domain not coming out of reset.\n");
1899 r = -ENODEV; 2408 r = -ENODEV;
1900 goto err; 2409 goto err_cio_pwr_dom;
1901 } 2410 }
1902 2411
1903 if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { 2412 dsi_if_enable(dsidev, true);
1904 DSSERR("ComplexIO LDO power down.\n"); 2413 dsi_if_enable(dsidev, false);
1905 r = -ENODEV; 2414 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
1906 goto err; 2415
2416 r = dsi_cio_wait_tx_clk_esc_reset(dssdev);
2417 if (r)
2418 goto err_tx_clk_esc_rst;
2419
2420 if (dsi->ulps_enabled) {
2421 /* Keep Mark-1 state for 1ms (as per DSI spec) */
2422 ktime_t wait = ns_to_ktime(1000 * 1000);
2423 set_current_state(TASK_UNINTERRUPTIBLE);
2424 schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
2425
2426 /* Disable the override. The lanes should be set to Mark-11
2427 * state by the HW */
2428 dsi_cio_disable_lane_override(dsidev);
1907 } 2429 }
1908 2430
1909 dsi_complexio_timings(); 2431 /* FORCE_TX_STOP_MODE_IO */
2432 REG_FLD_MOD(dsidev, DSI_TIMING1, 0, 15, 15);
1910 2433
1911 /* 2434 dsi_cio_timings(dsidev);
1912 The configuration of the DSI complex I/O (number of data lanes, 2435
1913 position, differential order) should not be changed while 2436 dsi->ulps_enabled = false;
1914 DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the
1915 hardware to recognize a new configuration of the complex I/O (done
1916 in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow
1917 this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next
1918 reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20]
1919 LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN
1920 bit to 1. If the sequence is not followed, the DSi complex I/O
1921 configuration is undetermined.
1922 */
1923 dsi_if_enable(1);
1924 dsi_if_enable(0);
1925 REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
1926 dsi_if_enable(1);
1927 dsi_if_enable(0);
1928 2437
1929 DSSDBG("CIO init done\n"); 2438 DSSDBG("CIO init done\n");
1930err: 2439
2440 return 0;
2441
2442err_tx_clk_esc_rst:
2443 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */
2444err_cio_pwr_dom:
2445 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2446err_cio_pwr:
2447 if (dsi->ulps_enabled)
2448 dsi_cio_disable_lane_override(dsidev);
2449err_scp_clk_dom:
2450 dsi_disable_scp_clk(dsidev);
2451 if (dsi->dsi_mux_pads)
2452 dsi->dsi_mux_pads(false);
1931 return r; 2453 return r;
1932} 2454}
1933 2455
1934static void dsi_complexio_uninit(void) 2456static void dsi_cio_uninit(struct platform_device *dsidev)
1935{ 2457{
1936 dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF); 2458 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2459
2460 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2461 dsi_disable_scp_clk(dsidev);
2462 if (dsi->dsi_mux_pads)
2463 dsi->dsi_mux_pads(false);
1937} 2464}
1938 2465
1939static int _dsi_wait_reset(void) 2466static int _dsi_wait_reset(struct platform_device *dsidev)
1940{ 2467{
1941 int t = 0; 2468 int t = 0;
1942 2469
1943 while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { 2470 while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
1944 if (++t > 5) { 2471 if (++t > 5) {
1945 DSSERR("soft reset failed\n"); 2472 DSSERR("soft reset failed\n");
1946 return -ENODEV; 2473 return -ENODEV;
@@ -1951,28 +2478,30 @@ static int _dsi_wait_reset(void)
1951 return 0; 2478 return 0;
1952} 2479}
1953 2480
1954static int _dsi_reset(void) 2481static int _dsi_reset(struct platform_device *dsidev)
1955{ 2482{
1956 /* Soft reset */ 2483 /* Soft reset */
1957 REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1); 2484 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
1958 return _dsi_wait_reset(); 2485 return _dsi_wait_reset(dsidev);
1959} 2486}
1960 2487
1961static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, 2488static void dsi_config_tx_fifo(struct platform_device *dsidev,
2489 enum fifo_size size1, enum fifo_size size2,
1962 enum fifo_size size3, enum fifo_size size4) 2490 enum fifo_size size3, enum fifo_size size4)
1963{ 2491{
2492 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1964 u32 r = 0; 2493 u32 r = 0;
1965 int add = 0; 2494 int add = 0;
1966 int i; 2495 int i;
1967 2496
1968 dsi.vc[0].fifo_size = size1; 2497 dsi->vc[0].fifo_size = size1;
1969 dsi.vc[1].fifo_size = size2; 2498 dsi->vc[1].fifo_size = size2;
1970 dsi.vc[2].fifo_size = size3; 2499 dsi->vc[2].fifo_size = size3;
1971 dsi.vc[3].fifo_size = size4; 2500 dsi->vc[3].fifo_size = size4;
1972 2501
1973 for (i = 0; i < 4; i++) { 2502 for (i = 0; i < 4; i++) {
1974 u8 v; 2503 u8 v;
1975 int size = dsi.vc[i].fifo_size; 2504 int size = dsi->vc[i].fifo_size;
1976 2505
1977 if (add + size > 4) { 2506 if (add + size > 4) {
1978 DSSERR("Illegal FIFO configuration\n"); 2507 DSSERR("Illegal FIFO configuration\n");
@@ -1985,24 +2514,26 @@ static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
1985 add += size; 2514 add += size;
1986 } 2515 }
1987 2516
1988 dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r); 2517 dsi_write_reg(dsidev, DSI_TX_FIFO_VC_SIZE, r);
1989} 2518}
1990 2519
1991static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2, 2520static void dsi_config_rx_fifo(struct platform_device *dsidev,
2521 enum fifo_size size1, enum fifo_size size2,
1992 enum fifo_size size3, enum fifo_size size4) 2522 enum fifo_size size3, enum fifo_size size4)
1993{ 2523{
2524 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1994 u32 r = 0; 2525 u32 r = 0;
1995 int add = 0; 2526 int add = 0;
1996 int i; 2527 int i;
1997 2528
1998 dsi.vc[0].fifo_size = size1; 2529 dsi->vc[0].fifo_size = size1;
1999 dsi.vc[1].fifo_size = size2; 2530 dsi->vc[1].fifo_size = size2;
2000 dsi.vc[2].fifo_size = size3; 2531 dsi->vc[2].fifo_size = size3;
2001 dsi.vc[3].fifo_size = size4; 2532 dsi->vc[3].fifo_size = size4;
2002 2533
2003 for (i = 0; i < 4; i++) { 2534 for (i = 0; i < 4; i++) {
2004 u8 v; 2535 u8 v;
2005 int size = dsi.vc[i].fifo_size; 2536 int size = dsi->vc[i].fifo_size;
2006 2537
2007 if (add + size > 4) { 2538 if (add + size > 4) {
2008 DSSERR("Illegal FIFO configuration\n"); 2539 DSSERR("Illegal FIFO configuration\n");
@@ -2015,18 +2546,18 @@ static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
2015 add += size; 2546 add += size;
2016 } 2547 }
2017 2548
2018 dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r); 2549 dsi_write_reg(dsidev, DSI_RX_FIFO_VC_SIZE, r);
2019} 2550}
2020 2551
2021static int dsi_force_tx_stop_mode_io(void) 2552static int dsi_force_tx_stop_mode_io(struct platform_device *dsidev)
2022{ 2553{
2023 u32 r; 2554 u32 r;
2024 2555
2025 r = dsi_read_reg(DSI_TIMING1); 2556 r = dsi_read_reg(dsidev, DSI_TIMING1);
2026 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 2557 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2027 dsi_write_reg(DSI_TIMING1, r); 2558 dsi_write_reg(dsidev, DSI_TIMING1, r);
2028 2559
2029 if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) { 2560 if (wait_for_bit_change(dsidev, DSI_TIMING1, 15, 0) != 0) {
2030 DSSERR("TX_STOP bit not going down\n"); 2561 DSSERR("TX_STOP bit not going down\n");
2031 return -EIO; 2562 return -EIO;
2032 } 2563 }
@@ -2034,16 +2565,135 @@ static int dsi_force_tx_stop_mode_io(void)
2034 return 0; 2565 return 0;
2035} 2566}
2036 2567
2037static int dsi_vc_enable(int channel, bool enable) 2568static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel)
2569{
2570 return REG_GET(dsidev, DSI_VC_CTRL(channel), 0, 0);
2571}
2572
2573static void dsi_packet_sent_handler_vp(void *data, u32 mask)
2574{
2575 struct dsi_packet_sent_handler_data *vp_data =
2576 (struct dsi_packet_sent_handler_data *) data;
2577 struct dsi_data *dsi = dsi_get_dsidrv_data(vp_data->dsidev);
2578 const int channel = dsi->update_channel;
2579 u8 bit = dsi->te_enabled ? 30 : 31;
2580
2581 if (REG_GET(vp_data->dsidev, DSI_VC_TE(channel), bit, bit) == 0)
2582 complete(vp_data->completion);
2583}
2584
2585static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
2586{
2587 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2588 DECLARE_COMPLETION_ONSTACK(completion);
2589 struct dsi_packet_sent_handler_data vp_data = { dsidev, &completion };
2590 int r = 0;
2591 u8 bit;
2592
2593 bit = dsi->te_enabled ? 30 : 31;
2594
2595 r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2596 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2597 if (r)
2598 goto err0;
2599
2600 /* Wait for completion only if TE_EN/TE_START is still set */
2601 if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit)) {
2602 if (wait_for_completion_timeout(&completion,
2603 msecs_to_jiffies(10)) == 0) {
2604 DSSERR("Failed to complete previous frame transfer\n");
2605 r = -EIO;
2606 goto err1;
2607 }
2608 }
2609
2610 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2611 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2612
2613 return 0;
2614err1:
2615 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
2616 &vp_data, DSI_VC_IRQ_PACKET_SENT);
2617err0:
2618 return r;
2619}
2620
2621static void dsi_packet_sent_handler_l4(void *data, u32 mask)
2622{
2623 struct dsi_packet_sent_handler_data *l4_data =
2624 (struct dsi_packet_sent_handler_data *) data;
2625 struct dsi_data *dsi = dsi_get_dsidrv_data(l4_data->dsidev);
2626 const int channel = dsi->update_channel;
2627
2628 if (REG_GET(l4_data->dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
2629 complete(l4_data->completion);
2630}
2631
2632static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel)
2633{
2634 DECLARE_COMPLETION_ONSTACK(completion);
2635 struct dsi_packet_sent_handler_data l4_data = { dsidev, &completion };
2636 int r = 0;
2637
2638 r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2639 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2640 if (r)
2641 goto err0;
2642
2643 /* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
2644 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5)) {
2645 if (wait_for_completion_timeout(&completion,
2646 msecs_to_jiffies(10)) == 0) {
2647 DSSERR("Failed to complete previous l4 transfer\n");
2648 r = -EIO;
2649 goto err1;
2650 }
2651 }
2652
2653 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2654 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2655
2656 return 0;
2657err1:
2658 dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
2659 &l4_data, DSI_VC_IRQ_PACKET_SENT);
2660err0:
2661 return r;
2662}
2663
2664static int dsi_sync_vc(struct platform_device *dsidev, int channel)
2665{
2666 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2667
2668 WARN_ON(!dsi_bus_is_locked(dsidev));
2669
2670 WARN_ON(in_interrupt());
2671
2672 if (!dsi_vc_is_enabled(dsidev, channel))
2673 return 0;
2674
2675 switch (dsi->vc[channel].mode) {
2676 case DSI_VC_MODE_VP:
2677 return dsi_sync_vc_vp(dsidev, channel);
2678 case DSI_VC_MODE_L4:
2679 return dsi_sync_vc_l4(dsidev, channel);
2680 default:
2681 BUG();
2682 }
2683}
2684
2685static int dsi_vc_enable(struct platform_device *dsidev, int channel,
2686 bool enable)
2038{ 2687{
2039 DSSDBG("dsi_vc_enable channel %d, enable %d\n", 2688 DSSDBG("dsi_vc_enable channel %d, enable %d\n",
2040 channel, enable); 2689 channel, enable);
2041 2690
2042 enable = enable ? 1 : 0; 2691 enable = enable ? 1 : 0;
2043 2692
2044 REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0); 2693 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 0, 0);
2045 2694
2046 if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) { 2695 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel),
2696 0, enable) != enable) {
2047 DSSERR("Failed to set dsi_vc_enable to %d\n", enable); 2697 DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
2048 return -EIO; 2698 return -EIO;
2049 } 2699 }
@@ -2051,13 +2701,13 @@ static int dsi_vc_enable(int channel, bool enable)
2051 return 0; 2701 return 0;
2052} 2702}
2053 2703
2054static void dsi_vc_initial_config(int channel) 2704static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
2055{ 2705{
2056 u32 r; 2706 u32 r;
2057 2707
2058 DSSDBGF("%d", channel); 2708 DSSDBGF("%d", channel);
2059 2709
2060 r = dsi_read_reg(DSI_VC_CTRL(channel)); 2710 r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
2061 2711
2062 if (FLD_GET(r, 15, 15)) /* VC_BUSY */ 2712 if (FLD_GET(r, 15, 15)) /* VC_BUSY */
2063 DSSERR("VC(%d) busy when trying to configure it!\n", 2713 DSSERR("VC(%d) busy when trying to configure it!\n",
@@ -2070,85 +2720,107 @@ static void dsi_vc_initial_config(int channel)
2070 r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ 2720 r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
2071 r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ 2721 r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
2072 r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ 2722 r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
2723 if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
2724 r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
2073 2725
2074 r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ 2726 r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
2075 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2727 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
2076 2728
2077 dsi_write_reg(DSI_VC_CTRL(channel), r); 2729 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
2078} 2730}
2079 2731
2080static int dsi_vc_config_l4(int channel) 2732static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
2081{ 2733{
2082 if (dsi.vc[channel].mode == DSI_VC_MODE_L4) 2734 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2735
2736 if (dsi->vc[channel].mode == DSI_VC_MODE_L4)
2083 return 0; 2737 return 0;
2084 2738
2085 DSSDBGF("%d", channel); 2739 DSSDBGF("%d", channel);
2086 2740
2087 dsi_vc_enable(channel, 0); 2741 dsi_sync_vc(dsidev, channel);
2742
2743 dsi_vc_enable(dsidev, channel, 0);
2088 2744
2089 /* VC_BUSY */ 2745 /* VC_BUSY */
2090 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { 2746 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
2091 DSSERR("vc(%d) busy when trying to config for L4\n", channel); 2747 DSSERR("vc(%d) busy when trying to config for L4\n", channel);
2092 return -EIO; 2748 return -EIO;
2093 } 2749 }
2094 2750
2095 REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ 2751 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
2752
2753 /* DCS_CMD_ENABLE */
2754 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
2755 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30);
2096 2756
2097 dsi_vc_enable(channel, 1); 2757 dsi_vc_enable(dsidev, channel, 1);
2098 2758
2099 dsi.vc[channel].mode = DSI_VC_MODE_L4; 2759 dsi->vc[channel].mode = DSI_VC_MODE_L4;
2100 2760
2101 return 0; 2761 return 0;
2102} 2762}
2103 2763
2104static int dsi_vc_config_vp(int channel) 2764static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
2105{ 2765{
2106 if (dsi.vc[channel].mode == DSI_VC_MODE_VP) 2766 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2767
2768 if (dsi->vc[channel].mode == DSI_VC_MODE_VP)
2107 return 0; 2769 return 0;
2108 2770
2109 DSSDBGF("%d", channel); 2771 DSSDBGF("%d", channel);
2110 2772
2111 dsi_vc_enable(channel, 0); 2773 dsi_sync_vc(dsidev, channel);
2774
2775 dsi_vc_enable(dsidev, channel, 0);
2112 2776
2113 /* VC_BUSY */ 2777 /* VC_BUSY */
2114 if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { 2778 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
2115 DSSERR("vc(%d) busy when trying to config for VP\n", channel); 2779 DSSERR("vc(%d) busy when trying to config for VP\n", channel);
2116 return -EIO; 2780 return -EIO;
2117 } 2781 }
2118 2782
2119 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ 2783 /* SOURCE, 1 = video port */
2784 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1);
2785
2786 /* DCS_CMD_ENABLE */
2787 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
2788 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30);
2120 2789
2121 dsi_vc_enable(channel, 1); 2790 dsi_vc_enable(dsidev, channel, 1);
2122 2791
2123 dsi.vc[channel].mode = DSI_VC_MODE_VP; 2792 dsi->vc[channel].mode = DSI_VC_MODE_VP;
2124 2793
2125 return 0; 2794 return 0;
2126} 2795}
2127 2796
2128 2797
2129void omapdss_dsi_vc_enable_hs(int channel, bool enable) 2798void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
2799 bool enable)
2130{ 2800{
2801 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2802
2131 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); 2803 DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
2132 2804
2133 WARN_ON(!dsi_bus_is_locked()); 2805 WARN_ON(!dsi_bus_is_locked(dsidev));
2134 2806
2135 dsi_vc_enable(channel, 0); 2807 dsi_vc_enable(dsidev, channel, 0);
2136 dsi_if_enable(0); 2808 dsi_if_enable(dsidev, 0);
2137 2809
2138 REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9); 2810 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 9, 9);
2139 2811
2140 dsi_vc_enable(channel, 1); 2812 dsi_vc_enable(dsidev, channel, 1);
2141 dsi_if_enable(1); 2813 dsi_if_enable(dsidev, 1);
2142 2814
2143 dsi_force_tx_stop_mode_io(); 2815 dsi_force_tx_stop_mode_io(dsidev);
2144} 2816}
2145EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); 2817EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
2146 2818
2147static void dsi_vc_flush_long_data(int channel) 2819static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel)
2148{ 2820{
2149 while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2821 while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
2150 u32 val; 2822 u32 val;
2151 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2823 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
2152 DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n", 2824 DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
2153 (val >> 0) & 0xff, 2825 (val >> 0) & 0xff,
2154 (val >> 8) & 0xff, 2826 (val >> 8) & 0xff,
@@ -2194,13 +2866,14 @@ static void dsi_show_rx_ack_with_err(u16 err)
2194 DSSERR("\t\tDSI Protocol Violation\n"); 2866 DSSERR("\t\tDSI Protocol Violation\n");
2195} 2867}
2196 2868
2197static u16 dsi_vc_flush_receive_data(int channel) 2869static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
2870 int channel)
2198{ 2871{
2199 /* RX_FIFO_NOT_EMPTY */ 2872 /* RX_FIFO_NOT_EMPTY */
2200 while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { 2873 while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
2201 u32 val; 2874 u32 val;
2202 u8 dt; 2875 u8 dt;
2203 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 2876 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
2204 DSSERR("\trawval %#08x\n", val); 2877 DSSERR("\trawval %#08x\n", val);
2205 dt = FLD_GET(val, 5, 0); 2878 dt = FLD_GET(val, 5, 0);
2206 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2879 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -2215,7 +2888,7 @@ static u16 dsi_vc_flush_receive_data(int channel)
2215 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 2888 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
2216 DSSERR("\tDCS long response, len %d\n", 2889 DSSERR("\tDCS long response, len %d\n",
2217 FLD_GET(val, 23, 8)); 2890 FLD_GET(val, 23, 8));
2218 dsi_vc_flush_long_data(channel); 2891 dsi_vc_flush_long_data(dsidev, channel);
2219 } else { 2892 } else {
2220 DSSERR("\tunknown datatype 0x%02x\n", dt); 2893 DSSERR("\tunknown datatype 0x%02x\n", dt);
2221 } 2894 }
@@ -2223,40 +2896,44 @@ static u16 dsi_vc_flush_receive_data(int channel)
2223 return 0; 2896 return 0;
2224} 2897}
2225 2898
2226static int dsi_vc_send_bta(int channel) 2899static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
2227{ 2900{
2228 if (dsi.debug_write || dsi.debug_read) 2901 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2902
2903 if (dsi->debug_write || dsi->debug_read)
2229 DSSDBG("dsi_vc_send_bta %d\n", channel); 2904 DSSDBG("dsi_vc_send_bta %d\n", channel);
2230 2905
2231 WARN_ON(!dsi_bus_is_locked()); 2906 WARN_ON(!dsi_bus_is_locked(dsidev));
2232 2907
2233 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 2908 /* RX_FIFO_NOT_EMPTY */
2909 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
2234 DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); 2910 DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
2235 dsi_vc_flush_receive_data(channel); 2911 dsi_vc_flush_receive_data(dsidev, channel);
2236 } 2912 }
2237 2913
2238 REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ 2914 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
2239 2915
2240 return 0; 2916 return 0;
2241} 2917}
2242 2918
2243int dsi_vc_send_bta_sync(int channel) 2919int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
2244{ 2920{
2921 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2245 DECLARE_COMPLETION_ONSTACK(completion); 2922 DECLARE_COMPLETION_ONSTACK(completion);
2246 int r = 0; 2923 int r = 0;
2247 u32 err; 2924 u32 err;
2248 2925
2249 r = dsi_register_isr_vc(channel, dsi_completion_handler, 2926 r = dsi_register_isr_vc(dsidev, channel, dsi_completion_handler,
2250 &completion, DSI_VC_IRQ_BTA); 2927 &completion, DSI_VC_IRQ_BTA);
2251 if (r) 2928 if (r)
2252 goto err0; 2929 goto err0;
2253 2930
2254 r = dsi_register_isr(dsi_completion_handler, &completion, 2931 r = dsi_register_isr(dsidev, dsi_completion_handler, &completion,
2255 DSI_IRQ_ERROR_MASK); 2932 DSI_IRQ_ERROR_MASK);
2256 if (r) 2933 if (r)
2257 goto err1; 2934 goto err1;
2258 2935
2259 r = dsi_vc_send_bta(channel); 2936 r = dsi_vc_send_bta(dsidev, channel);
2260 if (r) 2937 if (r)
2261 goto err2; 2938 goto err2;
2262 2939
@@ -2267,41 +2944,42 @@ int dsi_vc_send_bta_sync(int channel)
2267 goto err2; 2944 goto err2;
2268 } 2945 }
2269 2946
2270 err = dsi_get_errors(); 2947 err = dsi_get_errors(dsidev);
2271 if (err) { 2948 if (err) {
2272 DSSERR("Error while sending BTA: %x\n", err); 2949 DSSERR("Error while sending BTA: %x\n", err);
2273 r = -EIO; 2950 r = -EIO;
2274 goto err2; 2951 goto err2;
2275 } 2952 }
2276err2: 2953err2:
2277 dsi_unregister_isr(dsi_completion_handler, &completion, 2954 dsi_unregister_isr(dsidev, dsi_completion_handler, &completion,
2278 DSI_IRQ_ERROR_MASK); 2955 DSI_IRQ_ERROR_MASK);
2279err1: 2956err1:
2280 dsi_unregister_isr_vc(channel, dsi_completion_handler, 2957 dsi_unregister_isr_vc(dsidev, channel, dsi_completion_handler,
2281 &completion, DSI_VC_IRQ_BTA); 2958 &completion, DSI_VC_IRQ_BTA);
2282err0: 2959err0:
2283 return r; 2960 return r;
2284} 2961}
2285EXPORT_SYMBOL(dsi_vc_send_bta_sync); 2962EXPORT_SYMBOL(dsi_vc_send_bta_sync);
2286 2963
2287static inline void dsi_vc_write_long_header(int channel, u8 data_type, 2964static inline void dsi_vc_write_long_header(struct platform_device *dsidev,
2288 u16 len, u8 ecc) 2965 int channel, u8 data_type, u16 len, u8 ecc)
2289{ 2966{
2967 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2290 u32 val; 2968 u32 val;
2291 u8 data_id; 2969 u8 data_id;
2292 2970
2293 WARN_ON(!dsi_bus_is_locked()); 2971 WARN_ON(!dsi_bus_is_locked(dsidev));
2294 2972
2295 data_id = data_type | dsi.vc[channel].vc_id << 6; 2973 data_id = data_type | dsi->vc[channel].vc_id << 6;
2296 2974
2297 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | 2975 val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
2298 FLD_VAL(ecc, 31, 24); 2976 FLD_VAL(ecc, 31, 24);
2299 2977
2300 dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val); 2978 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(channel), val);
2301} 2979}
2302 2980
2303static inline void dsi_vc_write_long_payload(int channel, 2981static inline void dsi_vc_write_long_payload(struct platform_device *dsidev,
2304 u8 b1, u8 b2, u8 b3, u8 b4) 2982 int channel, u8 b1, u8 b2, u8 b3, u8 b4)
2305{ 2983{
2306 u32 val; 2984 u32 val;
2307 2985
@@ -2310,34 +2988,35 @@ static inline void dsi_vc_write_long_payload(int channel,
2310/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n", 2988/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
2311 b1, b2, b3, b4, val); */ 2989 b1, b2, b3, b4, val); */
2312 2990
2313 dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val); 2991 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
2314} 2992}
2315 2993
2316static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, 2994static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
2317 u8 ecc) 2995 u8 data_type, u8 *data, u16 len, u8 ecc)
2318{ 2996{
2319 /*u32 val; */ 2997 /*u32 val; */
2998 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2320 int i; 2999 int i;
2321 u8 *p; 3000 u8 *p;
2322 int r = 0; 3001 int r = 0;
2323 u8 b1, b2, b3, b4; 3002 u8 b1, b2, b3, b4;
2324 3003
2325 if (dsi.debug_write) 3004 if (dsi->debug_write)
2326 DSSDBG("dsi_vc_send_long, %d bytes\n", len); 3005 DSSDBG("dsi_vc_send_long, %d bytes\n", len);
2327 3006
2328 /* len + header */ 3007 /* len + header */
2329 if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) { 3008 if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
2330 DSSERR("unable to send long packet: packet too long.\n"); 3009 DSSERR("unable to send long packet: packet too long.\n");
2331 return -EINVAL; 3010 return -EINVAL;
2332 } 3011 }
2333 3012
2334 dsi_vc_config_l4(channel); 3013 dsi_vc_config_l4(dsidev, channel);
2335 3014
2336 dsi_vc_write_long_header(channel, data_type, len, ecc); 3015 dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc);
2337 3016
2338 p = data; 3017 p = data;
2339 for (i = 0; i < len >> 2; i++) { 3018 for (i = 0; i < len >> 2; i++) {
2340 if (dsi.debug_write) 3019 if (dsi->debug_write)
2341 DSSDBG("\tsending full packet %d\n", i); 3020 DSSDBG("\tsending full packet %d\n", i);
2342 3021
2343 b1 = *p++; 3022 b1 = *p++;
@@ -2345,14 +3024,14 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2345 b3 = *p++; 3024 b3 = *p++;
2346 b4 = *p++; 3025 b4 = *p++;
2347 3026
2348 dsi_vc_write_long_payload(channel, b1, b2, b3, b4); 3027 dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, b4);
2349 } 3028 }
2350 3029
2351 i = len % 4; 3030 i = len % 4;
2352 if (i) { 3031 if (i) {
2353 b1 = 0; b2 = 0; b3 = 0; 3032 b1 = 0; b2 = 0; b3 = 0;
2354 3033
2355 if (dsi.debug_write) 3034 if (dsi->debug_write)
2356 DSSDBG("\tsending remainder bytes %d\n", i); 3035 DSSDBG("\tsending remainder bytes %d\n", i);
2357 3036
2358 switch (i) { 3037 switch (i) {
@@ -2370,62 +3049,69 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
2370 break; 3049 break;
2371 } 3050 }
2372 3051
2373 dsi_vc_write_long_payload(channel, b1, b2, b3, 0); 3052 dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, 0);
2374 } 3053 }
2375 3054
2376 return r; 3055 return r;
2377} 3056}
2378 3057
2379static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) 3058static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
3059 u8 data_type, u16 data, u8 ecc)
2380{ 3060{
3061 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2381 u32 r; 3062 u32 r;
2382 u8 data_id; 3063 u8 data_id;
2383 3064
2384 WARN_ON(!dsi_bus_is_locked()); 3065 WARN_ON(!dsi_bus_is_locked(dsidev));
2385 3066
2386 if (dsi.debug_write) 3067 if (dsi->debug_write)
2387 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", 3068 DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
2388 channel, 3069 channel,
2389 data_type, data & 0xff, (data >> 8) & 0xff); 3070 data_type, data & 0xff, (data >> 8) & 0xff);
2390 3071
2391 dsi_vc_config_l4(channel); 3072 dsi_vc_config_l4(dsidev, channel);
2392 3073
2393 if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) { 3074 if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) {
2394 DSSERR("ERROR FIFO FULL, aborting transfer\n"); 3075 DSSERR("ERROR FIFO FULL, aborting transfer\n");
2395 return -EINVAL; 3076 return -EINVAL;
2396 } 3077 }
2397 3078
2398 data_id = data_type | dsi.vc[channel].vc_id << 6; 3079 data_id = data_type | dsi->vc[channel].vc_id << 6;
2399 3080
2400 r = (data_id << 0) | (data << 8) | (ecc << 24); 3081 r = (data_id << 0) | (data << 8) | (ecc << 24);
2401 3082
2402 dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r); 3083 dsi_write_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel), r);
2403 3084
2404 return 0; 3085 return 0;
2405} 3086}
2406 3087
2407int dsi_vc_send_null(int channel) 3088int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
2408{ 3089{
3090 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2409 u8 nullpkg[] = {0, 0, 0, 0}; 3091 u8 nullpkg[] = {0, 0, 0, 0};
2410 return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); 3092
3093 return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg,
3094 4, 0);
2411} 3095}
2412EXPORT_SYMBOL(dsi_vc_send_null); 3096EXPORT_SYMBOL(dsi_vc_send_null);
2413 3097
2414int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len) 3098int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
3099 u8 *data, int len)
2415{ 3100{
3101 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2416 int r; 3102 int r;
2417 3103
2418 BUG_ON(len == 0); 3104 BUG_ON(len == 0);
2419 3105
2420 if (len == 1) { 3106 if (len == 1) {
2421 r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0, 3107 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0,
2422 data[0], 0); 3108 data[0], 0);
2423 } else if (len == 2) { 3109 } else if (len == 2) {
2424 r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1, 3110 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1,
2425 data[0] | (data[1] << 8), 0); 3111 data[0] | (data[1] << 8), 0);
2426 } else { 3112 } else {
2427 /* 0x39 = DCS Long Write */ 3113 /* 0x39 = DCS Long Write */
2428 r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE, 3114 r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
2429 data, len, 0); 3115 data, len, 0);
2430 } 3116 }
2431 3117
@@ -2433,21 +3119,24 @@ int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
2433} 3119}
2434EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); 3120EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
2435 3121
2436int dsi_vc_dcs_write(int channel, u8 *data, int len) 3122int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
3123 int len)
2437{ 3124{
3125 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2438 int r; 3126 int r;
2439 3127
2440 r = dsi_vc_dcs_write_nosync(channel, data, len); 3128 r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len);
2441 if (r) 3129 if (r)
2442 goto err; 3130 goto err;
2443 3131
2444 r = dsi_vc_send_bta_sync(channel); 3132 r = dsi_vc_send_bta_sync(dssdev, channel);
2445 if (r) 3133 if (r)
2446 goto err; 3134 goto err;
2447 3135
2448 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ 3136 /* RX_FIFO_NOT_EMPTY */
3137 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
2449 DSSERR("rx fifo not empty after write, dumping data:\n"); 3138 DSSERR("rx fifo not empty after write, dumping data:\n");
2450 dsi_vc_flush_receive_data(channel); 3139 dsi_vc_flush_receive_data(dsidev, channel);
2451 r = -EIO; 3140 r = -EIO;
2452 goto err; 3141 goto err;
2453 } 3142 }
@@ -2460,47 +3149,51 @@ err:
2460} 3149}
2461EXPORT_SYMBOL(dsi_vc_dcs_write); 3150EXPORT_SYMBOL(dsi_vc_dcs_write);
2462 3151
2463int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd) 3152int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
2464{ 3153{
2465 return dsi_vc_dcs_write(channel, &dcs_cmd, 1); 3154 return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
2466} 3155}
2467EXPORT_SYMBOL(dsi_vc_dcs_write_0); 3156EXPORT_SYMBOL(dsi_vc_dcs_write_0);
2468 3157
2469int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param) 3158int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3159 u8 param)
2470{ 3160{
2471 u8 buf[2]; 3161 u8 buf[2];
2472 buf[0] = dcs_cmd; 3162 buf[0] = dcs_cmd;
2473 buf[1] = param; 3163 buf[1] = param;
2474 return dsi_vc_dcs_write(channel, buf, 2); 3164 return dsi_vc_dcs_write(dssdev, channel, buf, 2);
2475} 3165}
2476EXPORT_SYMBOL(dsi_vc_dcs_write_1); 3166EXPORT_SYMBOL(dsi_vc_dcs_write_1);
2477 3167
2478int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) 3168int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3169 u8 *buf, int buflen)
2479{ 3170{
3171 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3172 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2480 u32 val; 3173 u32 val;
2481 u8 dt; 3174 u8 dt;
2482 int r; 3175 int r;
2483 3176
2484 if (dsi.debug_read) 3177 if (dsi->debug_read)
2485 DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); 3178 DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
2486 3179
2487 r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); 3180 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0);
2488 if (r) 3181 if (r)
2489 goto err; 3182 goto err;
2490 3183
2491 r = dsi_vc_send_bta_sync(channel); 3184 r = dsi_vc_send_bta_sync(dssdev, channel);
2492 if (r) 3185 if (r)
2493 goto err; 3186 goto err;
2494 3187
2495 /* RX_FIFO_NOT_EMPTY */ 3188 /* RX_FIFO_NOT_EMPTY */
2496 if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { 3189 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
2497 DSSERR("RX fifo empty when trying to read.\n"); 3190 DSSERR("RX fifo empty when trying to read.\n");
2498 r = -EIO; 3191 r = -EIO;
2499 goto err; 3192 goto err;
2500 } 3193 }
2501 3194
2502 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 3195 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
2503 if (dsi.debug_read) 3196 if (dsi->debug_read)
2504 DSSDBG("\theader: %08x\n", val); 3197 DSSDBG("\theader: %08x\n", val);
2505 dt = FLD_GET(val, 5, 0); 3198 dt = FLD_GET(val, 5, 0);
2506 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 3199 if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -2511,7 +3204,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2511 3204
2512 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 3205 } else if (dt == DSI_DT_RX_SHORT_READ_1) {
2513 u8 data = FLD_GET(val, 15, 8); 3206 u8 data = FLD_GET(val, 15, 8);
2514 if (dsi.debug_read) 3207 if (dsi->debug_read)
2515 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 3208 DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
2516 3209
2517 if (buflen < 1) { 3210 if (buflen < 1) {
@@ -2524,7 +3217,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2524 return 1; 3217 return 1;
2525 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 3218 } else if (dt == DSI_DT_RX_SHORT_READ_2) {
2526 u16 data = FLD_GET(val, 23, 8); 3219 u16 data = FLD_GET(val, 23, 8);
2527 if (dsi.debug_read) 3220 if (dsi->debug_read)
2528 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 3221 DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
2529 3222
2530 if (buflen < 2) { 3223 if (buflen < 2) {
@@ -2539,7 +3232,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2539 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 3232 } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
2540 int w; 3233 int w;
2541 int len = FLD_GET(val, 23, 8); 3234 int len = FLD_GET(val, 23, 8);
2542 if (dsi.debug_read) 3235 if (dsi->debug_read)
2543 DSSDBG("\tDCS long response, len %d\n", len); 3236 DSSDBG("\tDCS long response, len %d\n", len);
2544 3237
2545 if (len > buflen) { 3238 if (len > buflen) {
@@ -2550,8 +3243,9 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
2550 /* two byte checksum ends the packet, not included in len */ 3243 /* two byte checksum ends the packet, not included in len */
2551 for (w = 0; w < len + 2;) { 3244 for (w = 0; w < len + 2;) {
2552 int b; 3245 int b;
2553 val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); 3246 val = dsi_read_reg(dsidev,
2554 if (dsi.debug_read) 3247 DSI_VC_SHORT_PACKET_HEADER(channel));
3248 if (dsi->debug_read)
2555 DSSDBG("\t\t%02x %02x %02x %02x\n", 3249 DSSDBG("\t\t%02x %02x %02x %02x\n",
2556 (val >> 0) & 0xff, 3250 (val >> 0) & 0xff,
2557 (val >> 8) & 0xff, 3251 (val >> 8) & 0xff,
@@ -2582,11 +3276,12 @@ err:
2582} 3276}
2583EXPORT_SYMBOL(dsi_vc_dcs_read); 3277EXPORT_SYMBOL(dsi_vc_dcs_read);
2584 3278
2585int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) 3279int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3280 u8 *data)
2586{ 3281{
2587 int r; 3282 int r;
2588 3283
2589 r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1); 3284 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1);
2590 3285
2591 if (r < 0) 3286 if (r < 0)
2592 return r; 3287 return r;
@@ -2598,12 +3293,13 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
2598} 3293}
2599EXPORT_SYMBOL(dsi_vc_dcs_read_1); 3294EXPORT_SYMBOL(dsi_vc_dcs_read_1);
2600 3295
2601int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2) 3296int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3297 u8 *data1, u8 *data2)
2602{ 3298{
2603 u8 buf[2]; 3299 u8 buf[2];
2604 int r; 3300 int r;
2605 3301
2606 r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2); 3302 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2);
2607 3303
2608 if (r < 0) 3304 if (r < 0)
2609 return r; 3305 return r;
@@ -2618,14 +3314,94 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
2618} 3314}
2619EXPORT_SYMBOL(dsi_vc_dcs_read_2); 3315EXPORT_SYMBOL(dsi_vc_dcs_read_2);
2620 3316
2621int dsi_vc_set_max_rx_packet_size(int channel, u16 len) 3317int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
3318 u16 len)
2622{ 3319{
2623 return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE, 3320 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3321
3322 return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
2624 len, 0); 3323 len, 0);
2625} 3324}
2626EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); 3325EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
2627 3326
2628static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16) 3327static int dsi_enter_ulps(struct platform_device *dsidev)
3328{
3329 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3330 DECLARE_COMPLETION_ONSTACK(completion);
3331 int r;
3332
3333 DSSDBGF();
3334
3335 WARN_ON(!dsi_bus_is_locked(dsidev));
3336
3337 WARN_ON(dsi->ulps_enabled);
3338
3339 if (dsi->ulps_enabled)
3340 return 0;
3341
3342 if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
3343 DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
3344 return -EIO;
3345 }
3346
3347 dsi_sync_vc(dsidev, 0);
3348 dsi_sync_vc(dsidev, 1);
3349 dsi_sync_vc(dsidev, 2);
3350 dsi_sync_vc(dsidev, 3);
3351
3352 dsi_force_tx_stop_mode_io(dsidev);
3353
3354 dsi_vc_enable(dsidev, 0, false);
3355 dsi_vc_enable(dsidev, 1, false);
3356 dsi_vc_enable(dsidev, 2, false);
3357 dsi_vc_enable(dsidev, 3, false);
3358
3359 if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 16, 16)) { /* HS_BUSY */
3360 DSSERR("HS busy when enabling ULPS\n");
3361 return -EIO;
3362 }
3363
3364 if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 17, 17)) { /* LP_BUSY */
3365 DSSERR("LP busy when enabling ULPS\n");
3366 return -EIO;
3367 }
3368
3369 r = dsi_register_isr_cio(dsidev, dsi_completion_handler, &completion,
3370 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3371 if (r)
3372 return r;
3373
3374 /* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
3375 /* LANEx_ULPS_SIG2 */
3376 REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
3377 7, 5);
3378
3379 if (wait_for_completion_timeout(&completion,
3380 msecs_to_jiffies(1000)) == 0) {
3381 DSSERR("ULPS enable timeout\n");
3382 r = -EIO;
3383 goto err;
3384 }
3385
3386 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3387 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3388
3389 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
3390
3391 dsi_if_enable(dsidev, false);
3392
3393 dsi->ulps_enabled = true;
3394
3395 return 0;
3396
3397err:
3398 dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
3399 DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
3400 return r;
3401}
3402
3403static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
3404 unsigned ticks, bool x4, bool x16)
2629{ 3405{
2630 unsigned long fck; 3406 unsigned long fck;
2631 unsigned long total_ticks; 3407 unsigned long total_ticks;
@@ -2634,14 +3410,14 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2634 BUG_ON(ticks > 0x1fff); 3410 BUG_ON(ticks > 0x1fff);
2635 3411
2636 /* ticks in DSI_FCK */ 3412 /* ticks in DSI_FCK */
2637 fck = dsi_fclk_rate(); 3413 fck = dsi_fclk_rate(dsidev);
2638 3414
2639 r = dsi_read_reg(DSI_TIMING2); 3415 r = dsi_read_reg(dsidev, DSI_TIMING2);
2640 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ 3416 r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
2641 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */ 3417 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */
2642 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */ 3418 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */
2643 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ 3419 r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
2644 dsi_write_reg(DSI_TIMING2, r); 3420 dsi_write_reg(dsidev, DSI_TIMING2, r);
2645 3421
2646 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3422 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2647 3423
@@ -2651,7 +3427,8 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
2651 (total_ticks * 1000) / (fck / 1000 / 1000)); 3427 (total_ticks * 1000) / (fck / 1000 / 1000));
2652} 3428}
2653 3429
2654static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16) 3430static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
3431 bool x8, bool x16)
2655{ 3432{
2656 unsigned long fck; 3433 unsigned long fck;
2657 unsigned long total_ticks; 3434 unsigned long total_ticks;
@@ -2660,14 +3437,14 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2660 BUG_ON(ticks > 0x1fff); 3437 BUG_ON(ticks > 0x1fff);
2661 3438
2662 /* ticks in DSI_FCK */ 3439 /* ticks in DSI_FCK */
2663 fck = dsi_fclk_rate(); 3440 fck = dsi_fclk_rate(dsidev);
2664 3441
2665 r = dsi_read_reg(DSI_TIMING1); 3442 r = dsi_read_reg(dsidev, DSI_TIMING1);
2666 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ 3443 r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
2667 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */ 3444 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
2668 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */ 3445 r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
2669 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ 3446 r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
2670 dsi_write_reg(DSI_TIMING1, r); 3447 dsi_write_reg(dsidev, DSI_TIMING1, r);
2671 3448
2672 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1); 3449 total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1);
2673 3450
@@ -2677,7 +3454,8 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
2677 (total_ticks * 1000) / (fck / 1000 / 1000)); 3454 (total_ticks * 1000) / (fck / 1000 / 1000));
2678} 3455}
2679 3456
2680static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16) 3457static void dsi_set_stop_state_counter(struct platform_device *dsidev,
3458 unsigned ticks, bool x4, bool x16)
2681{ 3459{
2682 unsigned long fck; 3460 unsigned long fck;
2683 unsigned long total_ticks; 3461 unsigned long total_ticks;
@@ -2686,14 +3464,14 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2686 BUG_ON(ticks > 0x1fff); 3464 BUG_ON(ticks > 0x1fff);
2687 3465
2688 /* ticks in DSI_FCK */ 3466 /* ticks in DSI_FCK */
2689 fck = dsi_fclk_rate(); 3467 fck = dsi_fclk_rate(dsidev);
2690 3468
2691 r = dsi_read_reg(DSI_TIMING1); 3469 r = dsi_read_reg(dsidev, DSI_TIMING1);
2692 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ 3470 r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
2693 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */ 3471 r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */
2694 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */ 3472 r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */
2695 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ 3473 r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
2696 dsi_write_reg(DSI_TIMING1, r); 3474 dsi_write_reg(dsidev, DSI_TIMING1, r);
2697 3475
2698 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3476 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2699 3477
@@ -2703,7 +3481,8 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
2703 (total_ticks * 1000) / (fck / 1000 / 1000)); 3481 (total_ticks * 1000) / (fck / 1000 / 1000));
2704} 3482}
2705 3483
2706static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16) 3484static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
3485 unsigned ticks, bool x4, bool x16)
2707{ 3486{
2708 unsigned long fck; 3487 unsigned long fck;
2709 unsigned long total_ticks; 3488 unsigned long total_ticks;
@@ -2712,14 +3491,14 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2712 BUG_ON(ticks > 0x1fff); 3491 BUG_ON(ticks > 0x1fff);
2713 3492
2714 /* ticks in TxByteClkHS */ 3493 /* ticks in TxByteClkHS */
2715 fck = dsi_get_txbyteclkhs(); 3494 fck = dsi_get_txbyteclkhs(dsidev);
2716 3495
2717 r = dsi_read_reg(DSI_TIMING2); 3496 r = dsi_read_reg(dsidev, DSI_TIMING2);
2718 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ 3497 r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
2719 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */ 3498 r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */
2720 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */ 3499 r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */
2721 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ 3500 r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
2722 dsi_write_reg(DSI_TIMING2, r); 3501 dsi_write_reg(dsidev, DSI_TIMING2, r);
2723 3502
2724 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); 3503 total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
2725 3504
@@ -2730,24 +3509,25 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
2730} 3509}
2731static int dsi_proto_config(struct omap_dss_device *dssdev) 3510static int dsi_proto_config(struct omap_dss_device *dssdev)
2732{ 3511{
3512 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2733 u32 r; 3513 u32 r;
2734 int buswidth = 0; 3514 int buswidth = 0;
2735 3515
2736 dsi_config_tx_fifo(DSI_FIFO_SIZE_32, 3516 dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32,
2737 DSI_FIFO_SIZE_32, 3517 DSI_FIFO_SIZE_32,
2738 DSI_FIFO_SIZE_32, 3518 DSI_FIFO_SIZE_32,
2739 DSI_FIFO_SIZE_32); 3519 DSI_FIFO_SIZE_32);
2740 3520
2741 dsi_config_rx_fifo(DSI_FIFO_SIZE_32, 3521 dsi_config_rx_fifo(dsidev, DSI_FIFO_SIZE_32,
2742 DSI_FIFO_SIZE_32, 3522 DSI_FIFO_SIZE_32,
2743 DSI_FIFO_SIZE_32, 3523 DSI_FIFO_SIZE_32,
2744 DSI_FIFO_SIZE_32); 3524 DSI_FIFO_SIZE_32);
2745 3525
2746 /* XXX what values for the timeouts? */ 3526 /* XXX what values for the timeouts? */
2747 dsi_set_stop_state_counter(0x1000, false, false); 3527 dsi_set_stop_state_counter(dsidev, 0x1000, false, false);
2748 dsi_set_ta_timeout(0x1fff, true, true); 3528 dsi_set_ta_timeout(dsidev, 0x1fff, true, true);
2749 dsi_set_lp_rx_timeout(0x1fff, true, true); 3529 dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
2750 dsi_set_hs_tx_timeout(0x1fff, true, true); 3530 dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
2751 3531
2752 switch (dssdev->ctrl.pixel_size) { 3532 switch (dssdev->ctrl.pixel_size) {
2753 case 16: 3533 case 16:
@@ -2763,7 +3543,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2763 BUG(); 3543 BUG();
2764 } 3544 }
2765 3545
2766 r = dsi_read_reg(DSI_CTRL); 3546 r = dsi_read_reg(dsidev, DSI_CTRL);
2767 r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */ 3547 r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */
2768 r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */ 3548 r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */
2769 r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */ 3549 r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */
@@ -2773,21 +3553,25 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
2773 r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ 3553 r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */
2774 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ 3554 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
2775 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ 3555 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
2776 r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ 3556 if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
2777 r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */ 3557 r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */
3558 /* DCS_CMD_CODE, 1=start, 0=continue */
3559 r = FLD_MOD(r, 0, 25, 25);
3560 }
2778 3561
2779 dsi_write_reg(DSI_CTRL, r); 3562 dsi_write_reg(dsidev, DSI_CTRL, r);
2780 3563
2781 dsi_vc_initial_config(0); 3564 dsi_vc_initial_config(dsidev, 0);
2782 dsi_vc_initial_config(1); 3565 dsi_vc_initial_config(dsidev, 1);
2783 dsi_vc_initial_config(2); 3566 dsi_vc_initial_config(dsidev, 2);
2784 dsi_vc_initial_config(3); 3567 dsi_vc_initial_config(dsidev, 3);
2785 3568
2786 return 0; 3569 return 0;
2787} 3570}
2788 3571
2789static void dsi_proto_timings(struct omap_dss_device *dssdev) 3572static void dsi_proto_timings(struct omap_dss_device *dssdev)
2790{ 3573{
3574 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2791 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; 3575 unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
2792 unsigned tclk_pre, tclk_post; 3576 unsigned tclk_pre, tclk_post;
2793 unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; 3577 unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
@@ -2797,32 +3581,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2797 unsigned ths_eot; 3581 unsigned ths_eot;
2798 u32 r; 3582 u32 r;
2799 3583
2800 r = dsi_read_reg(DSI_DSIPHY_CFG0); 3584 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
2801 ths_prepare = FLD_GET(r, 31, 24); 3585 ths_prepare = FLD_GET(r, 31, 24);
2802 ths_prepare_ths_zero = FLD_GET(r, 23, 16); 3586 ths_prepare_ths_zero = FLD_GET(r, 23, 16);
2803 ths_zero = ths_prepare_ths_zero - ths_prepare; 3587 ths_zero = ths_prepare_ths_zero - ths_prepare;
2804 ths_trail = FLD_GET(r, 15, 8); 3588 ths_trail = FLD_GET(r, 15, 8);
2805 ths_exit = FLD_GET(r, 7, 0); 3589 ths_exit = FLD_GET(r, 7, 0);
2806 3590
2807 r = dsi_read_reg(DSI_DSIPHY_CFG1); 3591 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
2808 tlpx = FLD_GET(r, 22, 16) * 2; 3592 tlpx = FLD_GET(r, 22, 16) * 2;
2809 tclk_trail = FLD_GET(r, 15, 8); 3593 tclk_trail = FLD_GET(r, 15, 8);
2810 tclk_zero = FLD_GET(r, 7, 0); 3594 tclk_zero = FLD_GET(r, 7, 0);
2811 3595
2812 r = dsi_read_reg(DSI_DSIPHY_CFG2); 3596 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
2813 tclk_prepare = FLD_GET(r, 7, 0); 3597 tclk_prepare = FLD_GET(r, 7, 0);
2814 3598
2815 /* min 8*UI */ 3599 /* min 8*UI */
2816 tclk_pre = 20; 3600 tclk_pre = 20;
2817 /* min 60ns + 52*UI */ 3601 /* min 60ns + 52*UI */
2818 tclk_post = ns2ddr(60) + 26; 3602 tclk_post = ns2ddr(dsidev, 60) + 26;
2819 3603
2820 /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */ 3604 ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev));
2821 if (dssdev->phy.dsi.data1_lane != 0 &&
2822 dssdev->phy.dsi.data2_lane != 0)
2823 ths_eot = 2;
2824 else
2825 ths_eot = 4;
2826 3605
2827 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, 3606 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
2828 4); 3607 4);
@@ -2831,10 +3610,10 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2831 BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255); 3610 BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255);
2832 BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255); 3611 BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255);
2833 3612
2834 r = dsi_read_reg(DSI_CLK_TIMING); 3613 r = dsi_read_reg(dsidev, DSI_CLK_TIMING);
2835 r = FLD_MOD(r, ddr_clk_pre, 15, 8); 3614 r = FLD_MOD(r, ddr_clk_pre, 15, 8);
2836 r = FLD_MOD(r, ddr_clk_post, 7, 0); 3615 r = FLD_MOD(r, ddr_clk_post, 7, 0);
2837 dsi_write_reg(DSI_CLK_TIMING, r); 3616 dsi_write_reg(dsidev, DSI_CLK_TIMING, r);
2838 3617
2839 DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n", 3618 DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n",
2840 ddr_clk_pre, 3619 ddr_clk_pre,
@@ -2848,7 +3627,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2848 3627
2849 r = FLD_VAL(enter_hs_mode_lat, 31, 16) | 3628 r = FLD_VAL(enter_hs_mode_lat, 31, 16) |
2850 FLD_VAL(exit_hs_mode_lat, 15, 0); 3629 FLD_VAL(exit_hs_mode_lat, 15, 0);
2851 dsi_write_reg(DSI_VM_TIMING7, r); 3630 dsi_write_reg(dsidev, DSI_VM_TIMING7, r);
2852 3631
2853 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", 3632 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
2854 enter_hs_mode_lat, exit_hs_mode_lat); 3633 enter_hs_mode_lat, exit_hs_mode_lat);
@@ -2858,25 +3637,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
2858#define DSI_DECL_VARS \ 3637#define DSI_DECL_VARS \
2859 int __dsi_cb = 0; u32 __dsi_cv = 0; 3638 int __dsi_cb = 0; u32 __dsi_cv = 0;
2860 3639
2861#define DSI_FLUSH(ch) \ 3640#define DSI_FLUSH(dsidev, ch) \
2862 if (__dsi_cb > 0) { \ 3641 if (__dsi_cb > 0) { \
2863 /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ 3642 /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \
2864 dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ 3643 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
2865 __dsi_cb = __dsi_cv = 0; \ 3644 __dsi_cb = __dsi_cv = 0; \
2866 } 3645 }
2867 3646
2868#define DSI_PUSH(ch, data) \ 3647#define DSI_PUSH(dsidev, ch, data) \
2869 do { \ 3648 do { \
2870 __dsi_cv |= (data) << (__dsi_cb * 8); \ 3649 __dsi_cv |= (data) << (__dsi_cb * 8); \
2871 /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \ 3650 /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
2872 if (++__dsi_cb > 3) \ 3651 if (++__dsi_cb > 3) \
2873 DSI_FLUSH(ch); \ 3652 DSI_FLUSH(dsidev, ch); \
2874 } while (0) 3653 } while (0)
2875 3654
2876static int dsi_update_screen_l4(struct omap_dss_device *dssdev, 3655static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2877 int x, int y, int w, int h) 3656 int x, int y, int w, int h)
2878{ 3657{
2879 /* Note: supports only 24bit colors in 32bit container */ 3658 /* Note: supports only 24bit colors in 32bit container */
3659 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3660 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2880 int first = 1; 3661 int first = 1;
2881 int fifo_stalls = 0; 3662 int fifo_stalls = 0;
2882 int max_dsi_packet_size; 3663 int max_dsi_packet_size;
@@ -2915,7 +3696,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2915 * in fifo */ 3696 * in fifo */
2916 3697
2917 /* When using CPU, max long packet size is TX buffer size */ 3698 /* When using CPU, max long packet size is TX buffer size */
2918 max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4; 3699 max_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4;
2919 3700
2920 /* we seem to get better perf if we divide the tx fifo to half, 3701 /* we seem to get better perf if we divide the tx fifo to half,
2921 and while the other half is being sent, we fill the other half 3702 and while the other half is being sent, we fill the other half
@@ -2944,35 +3725,36 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2944#if 1 3725#if 1
2945 /* using fifo not empty */ 3726 /* using fifo not empty */
2946 /* TX_FIFO_NOT_EMPTY */ 3727 /* TX_FIFO_NOT_EMPTY */
2947 while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { 3728 while (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(0)), 5, 5)) {
2948 fifo_stalls++; 3729 fifo_stalls++;
2949 if (fifo_stalls > 0xfffff) { 3730 if (fifo_stalls > 0xfffff) {
2950 DSSERR("fifo stalls overflow, pixels left %d\n", 3731 DSSERR("fifo stalls overflow, pixels left %d\n",
2951 pixels_left); 3732 pixels_left);
2952 dsi_if_enable(0); 3733 dsi_if_enable(dsidev, 0);
2953 return -EIO; 3734 return -EIO;
2954 } 3735 }
2955 udelay(1); 3736 udelay(1);
2956 } 3737 }
2957#elif 1 3738#elif 1
2958 /* using fifo emptiness */ 3739 /* using fifo emptiness */
2959 while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 < 3740 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
2960 max_dsi_packet_size) { 3741 max_dsi_packet_size) {
2961 fifo_stalls++; 3742 fifo_stalls++;
2962 if (fifo_stalls > 0xfffff) { 3743 if (fifo_stalls > 0xfffff) {
2963 DSSERR("fifo stalls overflow, pixels left %d\n", 3744 DSSERR("fifo stalls overflow, pixels left %d\n",
2964 pixels_left); 3745 pixels_left);
2965 dsi_if_enable(0); 3746 dsi_if_enable(dsidev, 0);
2966 return -EIO; 3747 return -EIO;
2967 } 3748 }
2968 } 3749 }
2969#else 3750#else
2970 while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) { 3751 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS,
3752 7, 0) + 1) * 4 == 0) {
2971 fifo_stalls++; 3753 fifo_stalls++;
2972 if (fifo_stalls > 0xfffff) { 3754 if (fifo_stalls > 0xfffff) {
2973 DSSERR("fifo stalls overflow, pixels left %d\n", 3755 DSSERR("fifo stalls overflow, pixels left %d\n",
2974 pixels_left); 3756 pixels_left);
2975 dsi_if_enable(0); 3757 dsi_if_enable(dsidev, 0);
2976 return -EIO; 3758 return -EIO;
2977 } 3759 }
2978 } 3760 }
@@ -2981,17 +3763,17 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
2981 3763
2982 pixels_left -= pixels; 3764 pixels_left -= pixels;
2983 3765
2984 dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE, 3766 dsi_vc_write_long_header(dsidev, 0, DSI_DT_DCS_LONG_WRITE,
2985 1 + pixels * bytespp, 0); 3767 1 + pixels * bytespp, 0);
2986 3768
2987 DSI_PUSH(0, dcs_cmd); 3769 DSI_PUSH(dsidev, 0, dcs_cmd);
2988 3770
2989 while (pixels-- > 0) { 3771 while (pixels-- > 0) {
2990 u32 pix = __raw_readl(data++); 3772 u32 pix = __raw_readl(data++);
2991 3773
2992 DSI_PUSH(0, (pix >> 16) & 0xff); 3774 DSI_PUSH(dsidev, 0, (pix >> 16) & 0xff);
2993 DSI_PUSH(0, (pix >> 8) & 0xff); 3775 DSI_PUSH(dsidev, 0, (pix >> 8) & 0xff);
2994 DSI_PUSH(0, (pix >> 0) & 0xff); 3776 DSI_PUSH(dsidev, 0, (pix >> 0) & 0xff);
2995 3777
2996 current_x++; 3778 current_x++;
2997 if (current_x == x+w) { 3779 if (current_x == x+w) {
@@ -3000,7 +3782,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
3000 } 3782 }
3001 } 3783 }
3002 3784
3003 DSI_FLUSH(0); 3785 DSI_FLUSH(dsidev, 0);
3004 } 3786 }
3005 3787
3006 return 0; 3788 return 0;
@@ -3009,6 +3791,8 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
3009static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, 3791static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3010 u16 x, u16 y, u16 w, u16 h) 3792 u16 x, u16 y, u16 w, u16 h)
3011{ 3793{
3794 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3795 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3012 unsigned bytespp; 3796 unsigned bytespp;
3013 unsigned bytespl; 3797 unsigned bytespl;
3014 unsigned bytespf; 3798 unsigned bytespf;
@@ -3017,16 +3801,13 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3017 unsigned packet_len; 3801 unsigned packet_len;
3018 u32 l; 3802 u32 l;
3019 int r; 3803 int r;
3020 const unsigned channel = dsi.update_channel; 3804 const unsigned channel = dsi->update_channel;
3021 /* line buffer is 1024 x 24bits */ 3805 const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
3022 /* XXX: for some reason using full buffer size causes considerable TX
3023 * slowdown with update sizes that fill the whole buffer */
3024 const unsigned line_buf_size = 1023 * 3;
3025 3806
3026 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", 3807 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
3027 x, y, w, h); 3808 x, y, w, h);
3028 3809
3029 dsi_vc_config_vp(channel); 3810 dsi_vc_config_vp(dsidev, channel);
3030 3811
3031 bytespp = dssdev->ctrl.pixel_size / 8; 3812 bytespp = dssdev->ctrl.pixel_size / 8;
3032 bytespl = w * bytespp; 3813 bytespl = w * bytespp;
@@ -3047,15 +3828,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3047 total_len += (bytespf % packet_payload) + 1; 3828 total_len += (bytespf % packet_payload) + 1;
3048 3829
3049 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 3830 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
3050 dsi_write_reg(DSI_VC_TE(channel), l); 3831 dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
3051 3832
3052 dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); 3833 dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
3834 packet_len, 0);
3053 3835
3054 if (dsi.te_enabled) 3836 if (dsi->te_enabled)
3055 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ 3837 l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
3056 else 3838 else
3057 l = FLD_MOD(l, 1, 31, 31); /* TE_START */ 3839 l = FLD_MOD(l, 1, 31, 31); /* TE_START */
3058 dsi_write_reg(DSI_VC_TE(channel), l); 3840 dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
3059 3841
3060 /* We put SIDLEMODE to no-idle for the duration of the transfer, 3842 /* We put SIDLEMODE to no-idle for the duration of the transfer,
3061 * because DSS interrupts are not capable of waking up the CPU and the 3843 * because DSS interrupts are not capable of waking up the CPU and the
@@ -3065,23 +3847,23 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3065 */ 3847 */
3066 dispc_disable_sidle(); 3848 dispc_disable_sidle();
3067 3849
3068 dsi_perf_mark_start(); 3850 dsi_perf_mark_start(dsidev);
3069 3851
3070 r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work, 3852 r = schedule_delayed_work(&dsi->framedone_timeout_work,
3071 msecs_to_jiffies(250)); 3853 msecs_to_jiffies(250));
3072 BUG_ON(r == 0); 3854 BUG_ON(r == 0);
3073 3855
3074 dss_start_update(dssdev); 3856 dss_start_update(dssdev);
3075 3857
3076 if (dsi.te_enabled) { 3858 if (dsi->te_enabled) {
3077 /* disable LP_RX_TO, so that we can receive TE. Time to wait 3859 /* disable LP_RX_TO, so that we can receive TE. Time to wait
3078 * for TE is longer than the timer allows */ 3860 * for TE is longer than the timer allows */
3079 REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ 3861 REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
3080 3862
3081 dsi_vc_send_bta(channel); 3863 dsi_vc_send_bta(dsidev, channel);
3082 3864
3083#ifdef DSI_CATCH_MISSING_TE 3865#ifdef DSI_CATCH_MISSING_TE
3084 mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250)); 3866 mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
3085#endif 3867#endif
3086 } 3868 }
3087} 3869}
@@ -3093,41 +3875,28 @@ static void dsi_te_timeout(unsigned long arg)
3093} 3875}
3094#endif 3876#endif
3095 3877
3096static void dsi_framedone_bta_callback(void *data, u32 mask); 3878static void dsi_handle_framedone(struct platform_device *dsidev, int error)
3097
3098static void dsi_handle_framedone(int error)
3099{ 3879{
3100 const int channel = dsi.update_channel; 3880 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3101
3102 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback,
3103 NULL, DSI_VC_IRQ_BTA);
3104
3105 cancel_delayed_work(&dsi.framedone_timeout_work);
3106 3881
3107 /* SIDLEMODE back to smart-idle */ 3882 /* SIDLEMODE back to smart-idle */
3108 dispc_enable_sidle(); 3883 dispc_enable_sidle();
3109 3884
3110 if (dsi.te_enabled) { 3885 if (dsi->te_enabled) {
3111 /* enable LP_RX_TO again after the TE */ 3886 /* enable LP_RX_TO again after the TE */
3112 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ 3887 REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
3113 } 3888 }
3114 3889
3115 /* RX_FIFO_NOT_EMPTY */ 3890 dsi->framedone_callback(error, dsi->framedone_data);
3116 if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
3117 DSSERR("Received error during frame transfer:\n");
3118 dsi_vc_flush_receive_data(channel);
3119 if (!error)
3120 error = -EIO;
3121 }
3122
3123 dsi.framedone_callback(error, dsi.framedone_data);
3124 3891
3125 if (!error) 3892 if (!error)
3126 dsi_perf_show("DISPC"); 3893 dsi_perf_show(dsidev, "DISPC");
3127} 3894}
3128 3895
3129static void dsi_framedone_timeout_work_callback(struct work_struct *work) 3896static void dsi_framedone_timeout_work_callback(struct work_struct *work)
3130{ 3897{
3898 struct dsi_data *dsi = container_of(work, struct dsi_data,
3899 framedone_timeout_work.work);
3131 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after 3900 /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
3132 * 250ms which would conflict with this timeout work. What should be 3901 * 250ms which would conflict with this timeout work. What should be
3133 * done is first cancel the transfer on the HW, and then cancel the 3902 * done is first cancel the transfer on the HW, and then cancel the
@@ -3137,70 +3906,34 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
3137 3906
3138 DSSERR("Framedone not received for 250ms!\n"); 3907 DSSERR("Framedone not received for 250ms!\n");
3139 3908
3140 dsi_handle_framedone(-ETIMEDOUT); 3909 dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
3141}
3142
3143static void dsi_framedone_bta_callback(void *data, u32 mask)
3144{
3145 dsi_handle_framedone(0);
3146
3147#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
3148 dispc_fake_vsync_irq();
3149#endif
3150} 3910}
3151 3911
3152static void dsi_framedone_irq_callback(void *data, u32 mask) 3912static void dsi_framedone_irq_callback(void *data, u32 mask)
3153{ 3913{
3154 const int channel = dsi.update_channel; 3914 struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
3155 int r; 3915 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3916 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3156 3917
3157 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and 3918 /* Note: We get FRAMEDONE when DISPC has finished sending pixels and
3158 * turns itself off. However, DSI still has the pixels in its buffers, 3919 * turns itself off. However, DSI still has the pixels in its buffers,
3159 * and is sending the data. 3920 * and is sending the data.
3160 */ 3921 */
3161 3922
3162 if (dsi.te_enabled) { 3923 __cancel_delayed_work(&dsi->framedone_timeout_work);
3163 /* enable LP_RX_TO again after the TE */
3164 REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
3165 }
3166
3167 /* Send BTA after the frame. We need this for the TE to work, as TE
3168 * trigger is only sent for BTAs without preceding packet. Thus we need
3169 * to BTA after the pixel packets so that next BTA will cause TE
3170 * trigger.
3171 *
3172 * This is not needed when TE is not in use, but we do it anyway to
3173 * make sure that the transfer has been completed. It would be more
3174 * optimal, but more complex, to wait only just before starting next
3175 * transfer.
3176 *
3177 * Also, as there's no interrupt telling when the transfer has been
3178 * done and the channel could be reconfigured, the only way is to
3179 * busyloop until TE_SIZE is zero. With BTA we can do this
3180 * asynchronously.
3181 * */
3182
3183 r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback,
3184 NULL, DSI_VC_IRQ_BTA);
3185 if (r) {
3186 DSSERR("Failed to register BTA ISR\n");
3187 dsi_handle_framedone(-EIO);
3188 return;
3189 }
3190 3924
3191 r = dsi_vc_send_bta(channel); 3925 dsi_handle_framedone(dsidev, 0);
3192 if (r) { 3926
3193 DSSERR("BTA after framedone failed\n"); 3927#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
3194 dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback, 3928 dispc_fake_vsync_irq();
3195 NULL, DSI_VC_IRQ_BTA); 3929#endif
3196 dsi_handle_framedone(-EIO);
3197 }
3198} 3930}
3199 3931
3200int omap_dsi_prepare_update(struct omap_dss_device *dssdev, 3932int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3201 u16 *x, u16 *y, u16 *w, u16 *h, 3933 u16 *x, u16 *y, u16 *w, u16 *h,
3202 bool enlarge_update_area) 3934 bool enlarge_update_area)
3203{ 3935{
3936 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3204 u16 dw, dh; 3937 u16 dw, dh;
3205 3938
3206 dssdev->driver->get_resolution(dssdev, &dw, &dh); 3939 dssdev->driver->get_resolution(dssdev, &dw, &dh);
@@ -3220,7 +3953,7 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3220 if (*w == 0 || *h == 0) 3953 if (*w == 0 || *h == 0)
3221 return -EINVAL; 3954 return -EINVAL;
3222 3955
3223 dsi_perf_mark_setup(); 3956 dsi_perf_mark_setup(dsidev);
3224 3957
3225 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 3958 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
3226 dss_setup_partial_planes(dssdev, x, y, w, h, 3959 dss_setup_partial_planes(dssdev, x, y, w, h,
@@ -3237,7 +3970,10 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
3237 u16 x, u16 y, u16 w, u16 h, 3970 u16 x, u16 y, u16 w, u16 h,
3238 void (*callback)(int, void *), void *data) 3971 void (*callback)(int, void *), void *data)
3239{ 3972{
3240 dsi.update_channel = channel; 3973 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3974 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3975
3976 dsi->update_channel = channel;
3241 3977
3242 /* OMAP DSS cannot send updates of odd widths. 3978 /* OMAP DSS cannot send updates of odd widths.
3243 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON 3979 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
@@ -3246,14 +3982,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
3246 BUG_ON(x % 2 == 1); 3982 BUG_ON(x % 2 == 1);
3247 3983
3248 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 3984 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
3249 dsi.framedone_callback = callback; 3985 dsi->framedone_callback = callback;
3250 dsi.framedone_data = data; 3986 dsi->framedone_data = data;
3251 3987
3252 dsi.update_region.x = x; 3988 dsi->update_region.x = x;
3253 dsi.update_region.y = y; 3989 dsi->update_region.y = y;
3254 dsi.update_region.w = w; 3990 dsi->update_region.w = w;
3255 dsi.update_region.h = h; 3991 dsi->update_region.h = h;
3256 dsi.update_region.device = dssdev; 3992 dsi->update_region.device = dssdev;
3257 3993
3258 dsi_update_screen_dispc(dssdev, x, y, w, h); 3994 dsi_update_screen_dispc(dssdev, x, y, w, h);
3259 } else { 3995 } else {
@@ -3263,7 +3999,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
3263 if (r) 3999 if (r)
3264 return r; 4000 return r;
3265 4001
3266 dsi_perf_show("L4"); 4002 dsi_perf_show(dsidev, "L4");
3267 callback(0, data); 4003 callback(0, data);
3268 } 4004 }
3269 4005
@@ -3276,9 +4012,13 @@ EXPORT_SYMBOL(omap_dsi_update);
3276static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4012static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
3277{ 4013{
3278 int r; 4014 int r;
4015 u32 irq;
4016
4017 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4018 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
3279 4019
3280 r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL, 4020 r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
3281 DISPC_IRQ_FRAMEDONE); 4021 irq);
3282 if (r) { 4022 if (r) {
3283 DSSERR("can't get FRAMEDONE irq\n"); 4023 DSSERR("can't get FRAMEDONE irq\n");
3284 return r; 4024 return r;
@@ -3311,28 +4051,34 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
3311 4051
3312static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4052static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
3313{ 4053{
3314 omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL, 4054 u32 irq;
3315 DISPC_IRQ_FRAMEDONE); 4055
4056 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4057 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4058
4059 omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
4060 irq);
3316} 4061}
3317 4062
3318static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4063static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
3319{ 4064{
4065 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3320 struct dsi_clock_info cinfo; 4066 struct dsi_clock_info cinfo;
3321 int r; 4067 int r;
3322 4068
3323 /* we always use DSS_CLK_SYSCK as input clock */ 4069 /* we always use DSS_CLK_SYSCK as input clock */
3324 cinfo.use_sys_clk = true; 4070 cinfo.use_sys_clk = true;
3325 cinfo.regn = dssdev->phy.dsi.div.regn; 4071 cinfo.regn = dssdev->clocks.dsi.regn;
3326 cinfo.regm = dssdev->phy.dsi.div.regm; 4072 cinfo.regm = dssdev->clocks.dsi.regm;
3327 cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc; 4073 cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc;
3328 cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi; 4074 cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi;
3329 r = dsi_calc_clock_rates(dssdev, &cinfo); 4075 r = dsi_calc_clock_rates(dssdev, &cinfo);
3330 if (r) { 4076 if (r) {
3331 DSSERR("Failed to calc dsi clocks\n"); 4077 DSSERR("Failed to calc dsi clocks\n");
3332 return r; 4078 return r;
3333 } 4079 }
3334 4080
3335 r = dsi_pll_set_clock_div(&cinfo); 4081 r = dsi_pll_set_clock_div(dsidev, &cinfo);
3336 if (r) { 4082 if (r) {
3337 DSSERR("Failed to set dsi clocks\n"); 4083 DSSERR("Failed to set dsi clocks\n");
3338 return r; 4084 return r;
@@ -3343,14 +4089,15 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
3343 4089
3344static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) 4090static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3345{ 4091{
4092 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3346 struct dispc_clock_info dispc_cinfo; 4093 struct dispc_clock_info dispc_cinfo;
3347 int r; 4094 int r;
3348 unsigned long long fck; 4095 unsigned long long fck;
3349 4096
3350 fck = dsi_get_pll_hsdiv_dispc_rate(); 4097 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
3351 4098
3352 dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; 4099 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
3353 dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; 4100 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
3354 4101
3355 r = dispc_calc_clock_rates(fck, &dispc_cinfo); 4102 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
3356 if (r) { 4103 if (r) {
@@ -3369,11 +4116,11 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
3369 4116
3370static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4117static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3371{ 4118{
4119 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4120 int dsi_module = dsi_get_dsidev_id(dsidev);
3372 int r; 4121 int r;
3373 4122
3374 _dsi_print_reset_status(); 4123 r = dsi_pll_init(dsidev, true, true);
3375
3376 r = dsi_pll_init(dssdev, true, true);
3377 if (r) 4124 if (r)
3378 goto err0; 4125 goto err0;
3379 4126
@@ -3381,8 +4128,10 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3381 if (r) 4128 if (r)
3382 goto err1; 4129 goto err1;
3383 4130
3384 dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); 4131 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
3385 dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI); 4132 dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src);
4133 dss_select_lcd_clk_source(dssdev->manager->id,
4134 dssdev->clocks.dispc.channel.lcd_clk_src);
3386 4135
3387 DSSDBG("PLL OK\n"); 4136 DSSDBG("PLL OK\n");
3388 4137
@@ -3390,82 +4139,92 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
3390 if (r) 4139 if (r)
3391 goto err2; 4140 goto err2;
3392 4141
3393 r = dsi_complexio_init(dssdev); 4142 r = dsi_cio_init(dssdev);
3394 if (r) 4143 if (r)
3395 goto err2; 4144 goto err2;
3396 4145
3397 _dsi_print_reset_status(); 4146 _dsi_print_reset_status(dsidev);
3398 4147
3399 dsi_proto_timings(dssdev); 4148 dsi_proto_timings(dssdev);
3400 dsi_set_lp_clk_divisor(dssdev); 4149 dsi_set_lp_clk_divisor(dssdev);
3401 4150
3402 if (1) 4151 if (1)
3403 _dsi_print_reset_status(); 4152 _dsi_print_reset_status(dsidev);
3404 4153
3405 r = dsi_proto_config(dssdev); 4154 r = dsi_proto_config(dssdev);
3406 if (r) 4155 if (r)
3407 goto err3; 4156 goto err3;
3408 4157
3409 /* enable interface */ 4158 /* enable interface */
3410 dsi_vc_enable(0, 1); 4159 dsi_vc_enable(dsidev, 0, 1);
3411 dsi_vc_enable(1, 1); 4160 dsi_vc_enable(dsidev, 1, 1);
3412 dsi_vc_enable(2, 1); 4161 dsi_vc_enable(dsidev, 2, 1);
3413 dsi_vc_enable(3, 1); 4162 dsi_vc_enable(dsidev, 3, 1);
3414 dsi_if_enable(1); 4163 dsi_if_enable(dsidev, 1);
3415 dsi_force_tx_stop_mode_io(); 4164 dsi_force_tx_stop_mode_io(dsidev);
3416 4165
3417 return 0; 4166 return 0;
3418err3: 4167err3:
3419 dsi_complexio_uninit(); 4168 dsi_cio_uninit(dsidev);
3420err2: 4169err2:
3421 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); 4170 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
3422 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); 4171 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
3423err1: 4172err1:
3424 dsi_pll_uninit(); 4173 dsi_pll_uninit(dsidev, true);
3425err0: 4174err0:
3426 return r; 4175 return r;
3427} 4176}
3428 4177
3429static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 4178static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4179 bool disconnect_lanes, bool enter_ulps)
3430{ 4180{
3431 /* disable interface */ 4181 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3432 dsi_if_enable(0); 4182 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3433 dsi_vc_enable(0, 0); 4183 int dsi_module = dsi_get_dsidev_id(dsidev);
3434 dsi_vc_enable(1, 0);
3435 dsi_vc_enable(2, 0);
3436 dsi_vc_enable(3, 0);
3437 4184
3438 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); 4185 if (enter_ulps && !dsi->ulps_enabled)
3439 dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); 4186 dsi_enter_ulps(dsidev);
3440 dsi_complexio_uninit(); 4187
3441 dsi_pll_uninit(); 4188 /* disable interface */
4189 dsi_if_enable(dsidev, 0);
4190 dsi_vc_enable(dsidev, 0, 0);
4191 dsi_vc_enable(dsidev, 1, 0);
4192 dsi_vc_enable(dsidev, 2, 0);
4193 dsi_vc_enable(dsidev, 3, 0);
4194
4195 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4196 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
4197 dsi_cio_uninit(dsidev);
4198 dsi_pll_uninit(dsidev, disconnect_lanes);
3442} 4199}
3443 4200
3444static int dsi_core_init(void) 4201static int dsi_core_init(struct platform_device *dsidev)
3445{ 4202{
3446 /* Autoidle */ 4203 /* Autoidle */
3447 REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0); 4204 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0);
3448 4205
3449 /* ENWAKEUP */ 4206 /* ENWAKEUP */
3450 REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2); 4207 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2);
3451 4208
3452 /* SIDLEMODE smart-idle */ 4209 /* SIDLEMODE smart-idle */
3453 REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3); 4210 REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3);
3454 4211
3455 _dsi_initialize_irq(); 4212 _dsi_initialize_irq(dsidev);
3456 4213
3457 return 0; 4214 return 0;
3458} 4215}
3459 4216
3460int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) 4217int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3461{ 4218{
4219 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4220 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3462 int r = 0; 4221 int r = 0;
3463 4222
3464 DSSDBG("dsi_display_enable\n"); 4223 DSSDBG("dsi_display_enable\n");
3465 4224
3466 WARN_ON(!dsi_bus_is_locked()); 4225 WARN_ON(!dsi_bus_is_locked(dsidev));
3467 4226
3468 mutex_lock(&dsi.lock); 4227 mutex_lock(&dsi->lock);
3469 4228
3470 r = omap_dss_start_device(dssdev); 4229 r = omap_dss_start_device(dssdev);
3471 if (r) { 4230 if (r) {
@@ -3474,13 +4233,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3474 } 4233 }
3475 4234
3476 enable_clocks(1); 4235 enable_clocks(1);
3477 dsi_enable_pll_clock(1); 4236 dsi_enable_pll_clock(dsidev, 1);
3478 4237
3479 r = _dsi_reset(); 4238 r = _dsi_reset(dsidev);
3480 if (r) 4239 if (r)
3481 goto err1; 4240 goto err1;
3482 4241
3483 dsi_core_init(); 4242 dsi_core_init(dsidev);
3484 4243
3485 r = dsi_display_init_dispc(dssdev); 4244 r = dsi_display_init_dispc(dssdev);
3486 if (r) 4245 if (r)
@@ -3490,7 +4249,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
3490 if (r) 4249 if (r)
3491 goto err2; 4250 goto err2;
3492 4251
3493 mutex_unlock(&dsi.lock); 4252 mutex_unlock(&dsi->lock);
3494 4253
3495 return 0; 4254 return 0;
3496 4255
@@ -3498,39 +4257,46 @@ err2:
3498 dsi_display_uninit_dispc(dssdev); 4257 dsi_display_uninit_dispc(dssdev);
3499err1: 4258err1:
3500 enable_clocks(0); 4259 enable_clocks(0);
3501 dsi_enable_pll_clock(0); 4260 dsi_enable_pll_clock(dsidev, 0);
3502 omap_dss_stop_device(dssdev); 4261 omap_dss_stop_device(dssdev);
3503err0: 4262err0:
3504 mutex_unlock(&dsi.lock); 4263 mutex_unlock(&dsi->lock);
3505 DSSDBG("dsi_display_enable FAILED\n"); 4264 DSSDBG("dsi_display_enable FAILED\n");
3506 return r; 4265 return r;
3507} 4266}
3508EXPORT_SYMBOL(omapdss_dsi_display_enable); 4267EXPORT_SYMBOL(omapdss_dsi_display_enable);
3509 4268
3510void omapdss_dsi_display_disable(struct omap_dss_device *dssdev) 4269void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4270 bool disconnect_lanes, bool enter_ulps)
3511{ 4271{
4272 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4273 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4274
3512 DSSDBG("dsi_display_disable\n"); 4275 DSSDBG("dsi_display_disable\n");
3513 4276
3514 WARN_ON(!dsi_bus_is_locked()); 4277 WARN_ON(!dsi_bus_is_locked(dsidev));
3515 4278
3516 mutex_lock(&dsi.lock); 4279 mutex_lock(&dsi->lock);
3517 4280
3518 dsi_display_uninit_dispc(dssdev); 4281 dsi_display_uninit_dispc(dssdev);
3519 4282
3520 dsi_display_uninit_dsi(dssdev); 4283 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
3521 4284
3522 enable_clocks(0); 4285 enable_clocks(0);
3523 dsi_enable_pll_clock(0); 4286 dsi_enable_pll_clock(dsidev, 0);
3524 4287
3525 omap_dss_stop_device(dssdev); 4288 omap_dss_stop_device(dssdev);
3526 4289
3527 mutex_unlock(&dsi.lock); 4290 mutex_unlock(&dsi->lock);
3528} 4291}
3529EXPORT_SYMBOL(omapdss_dsi_display_disable); 4292EXPORT_SYMBOL(omapdss_dsi_display_disable);
3530 4293
3531int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) 4294int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
3532{ 4295{
3533 dsi.te_enabled = enable; 4296 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4297 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4298
4299 dsi->te_enabled = enable;
3534 return 0; 4300 return 0;
3535} 4301}
3536EXPORT_SYMBOL(omapdss_dsi_enable_te); 4302EXPORT_SYMBOL(omapdss_dsi_enable_te);
@@ -3550,23 +4316,33 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
3550 4316
3551int dsi_init_display(struct omap_dss_device *dssdev) 4317int dsi_init_display(struct omap_dss_device *dssdev)
3552{ 4318{
4319 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4320 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4321 int dsi_module = dsi_get_dsidev_id(dsidev);
4322
3553 DSSDBG("DSI init\n"); 4323 DSSDBG("DSI init\n");
3554 4324
3555 /* XXX these should be figured out dynamically */ 4325 /* XXX these should be figured out dynamically */
3556 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 4326 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
3557 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 4327 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
3558 4328
3559 if (dsi.vdds_dsi_reg == NULL) { 4329 if (dsi->vdds_dsi_reg == NULL) {
3560 struct regulator *vdds_dsi; 4330 struct regulator *vdds_dsi;
3561 4331
3562 vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); 4332 vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
3563 4333
3564 if (IS_ERR(vdds_dsi)) { 4334 if (IS_ERR(vdds_dsi)) {
3565 DSSERR("can't get VDDS_DSI regulator\n"); 4335 DSSERR("can't get VDDS_DSI regulator\n");
3566 return PTR_ERR(vdds_dsi); 4336 return PTR_ERR(vdds_dsi);
3567 } 4337 }
3568 4338
3569 dsi.vdds_dsi_reg = vdds_dsi; 4339 dsi->vdds_dsi_reg = vdds_dsi;
4340 }
4341
4342 if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
4343 DSSERR("DSI%d can't support more than %d data lanes\n",
4344 dsi_module + 1, dsi->num_data_lanes);
4345 return -EINVAL;
3570 } 4346 }
3571 4347
3572 return 0; 4348 return 0;
@@ -3574,11 +4350,13 @@ int dsi_init_display(struct omap_dss_device *dssdev)
3574 4350
3575int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) 4351int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
3576{ 4352{
4353 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4354 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3577 int i; 4355 int i;
3578 4356
3579 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { 4357 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
3580 if (!dsi.vc[i].dssdev) { 4358 if (!dsi->vc[i].dssdev) {
3581 dsi.vc[i].dssdev = dssdev; 4359 dsi->vc[i].dssdev = dssdev;
3582 *channel = i; 4360 *channel = i;
3583 return 0; 4361 return 0;
3584 } 4362 }
@@ -3591,6 +4369,9 @@ EXPORT_SYMBOL(omap_dsi_request_vc);
3591 4369
3592int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) 4370int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3593{ 4371{
4372 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4373 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4374
3594 if (vc_id < 0 || vc_id > 3) { 4375 if (vc_id < 0 || vc_id > 3) {
3595 DSSERR("VC ID out of range\n"); 4376 DSSERR("VC ID out of range\n");
3596 return -EINVAL; 4377 return -EINVAL;
@@ -3601,13 +4382,13 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
3601 return -EINVAL; 4382 return -EINVAL;
3602 } 4383 }
3603 4384
3604 if (dsi.vc[channel].dssdev != dssdev) { 4385 if (dsi->vc[channel].dssdev != dssdev) {
3605 DSSERR("Virtual Channel not allocated to display %s\n", 4386 DSSERR("Virtual Channel not allocated to display %s\n",
3606 dssdev->name); 4387 dssdev->name);
3607 return -EINVAL; 4388 return -EINVAL;
3608 } 4389 }
3609 4390
3610 dsi.vc[channel].vc_id = vc_id; 4391 dsi->vc[channel].vc_id = vc_id;
3611 4392
3612 return 0; 4393 return 0;
3613} 4394}
@@ -3615,143 +4396,172 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id);
3615 4396
3616void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) 4397void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
3617{ 4398{
4399 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4400 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4401
3618 if ((channel >= 0 && channel <= 3) && 4402 if ((channel >= 0 && channel <= 3) &&
3619 dsi.vc[channel].dssdev == dssdev) { 4403 dsi->vc[channel].dssdev == dssdev) {
3620 dsi.vc[channel].dssdev = NULL; 4404 dsi->vc[channel].dssdev = NULL;
3621 dsi.vc[channel].vc_id = 0; 4405 dsi->vc[channel].vc_id = 0;
3622 } 4406 }
3623} 4407}
3624EXPORT_SYMBOL(omap_dsi_release_vc); 4408EXPORT_SYMBOL(omap_dsi_release_vc);
3625 4409
3626void dsi_wait_pll_hsdiv_dispc_active(void) 4410void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
3627{ 4411{
3628 if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) 4412 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1)
3629 DSSERR("%s (%s) not active\n", 4413 DSSERR("%s (%s) not active\n",
3630 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), 4414 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
3631 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); 4415 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
3632} 4416}
3633 4417
3634void dsi_wait_pll_hsdiv_dsi_active(void) 4418void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
3635{ 4419{
3636 if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) 4420 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1)
3637 DSSERR("%s (%s) not active\n", 4421 DSSERR("%s (%s) not active\n",
3638 dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), 4422 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
3639 dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); 4423 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
3640} 4424}
3641 4425
3642static void dsi_calc_clock_param_ranges(void) 4426static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
3643{ 4427{
3644 dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); 4428 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3645 dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); 4429
3646 dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); 4430 dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
3647 dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); 4431 dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
3648 dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); 4432 dsi->regm_dispc_max =
3649 dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); 4433 dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
3650 dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); 4434 dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
4435 dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
4436 dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
4437 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
3651} 4438}
3652 4439
3653static int dsi_init(struct platform_device *pdev) 4440static int dsi_init(struct platform_device *dsidev)
3654{ 4441{
4442 struct omap_display_platform_data *dss_plat_data;
4443 struct omap_dss_board_info *board_info;
3655 u32 rev; 4444 u32 rev;
3656 int r, i; 4445 int r, i, dsi_module = dsi_get_dsidev_id(dsidev);
3657 struct resource *dsi_mem; 4446 struct resource *dsi_mem;
4447 struct dsi_data *dsi;
4448
4449 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
4450 if (!dsi) {
4451 r = -ENOMEM;
4452 goto err0;
4453 }
4454
4455 dsi->pdev = dsidev;
4456 dsi_pdev_map[dsi_module] = dsidev;
4457 dev_set_drvdata(&dsidev->dev, dsi);
4458
4459 dss_plat_data = dsidev->dev.platform_data;
4460 board_info = dss_plat_data->board_data;
4461 dsi->dsi_mux_pads = board_info->dsi_mux_pads;
3658 4462
3659 spin_lock_init(&dsi.irq_lock); 4463 spin_lock_init(&dsi->irq_lock);
3660 spin_lock_init(&dsi.errors_lock); 4464 spin_lock_init(&dsi->errors_lock);
3661 dsi.errors = 0; 4465 dsi->errors = 0;
3662 4466
3663#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 4467#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
3664 spin_lock_init(&dsi.irq_stats_lock); 4468 spin_lock_init(&dsi->irq_stats_lock);
3665 dsi.irq_stats.last_reset = jiffies; 4469 dsi->irq_stats.last_reset = jiffies;
3666#endif 4470#endif
3667 4471
3668 mutex_init(&dsi.lock); 4472 mutex_init(&dsi->lock);
3669 sema_init(&dsi.bus_lock, 1); 4473 sema_init(&dsi->bus_lock, 1);
3670 4474
3671 dsi.workqueue = create_singlethread_workqueue("dsi"); 4475 INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
3672 if (dsi.workqueue == NULL)
3673 return -ENOMEM;
3674
3675 INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
3676 dsi_framedone_timeout_work_callback); 4476 dsi_framedone_timeout_work_callback);
3677 4477
3678#ifdef DSI_CATCH_MISSING_TE 4478#ifdef DSI_CATCH_MISSING_TE
3679 init_timer(&dsi.te_timer); 4479 init_timer(&dsi->te_timer);
3680 dsi.te_timer.function = dsi_te_timeout; 4480 dsi->te_timer.function = dsi_te_timeout;
3681 dsi.te_timer.data = 0; 4481 dsi->te_timer.data = 0;
3682#endif 4482#endif
3683 dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0); 4483 dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
3684 if (!dsi_mem) { 4484 if (!dsi_mem) {
3685 DSSERR("can't get IORESOURCE_MEM DSI\n"); 4485 DSSERR("can't get IORESOURCE_MEM DSI\n");
3686 r = -EINVAL; 4486 r = -EINVAL;
3687 goto err1; 4487 goto err1;
3688 } 4488 }
3689 dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem)); 4489 dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
3690 if (!dsi.base) { 4490 if (!dsi->base) {
3691 DSSERR("can't ioremap DSI\n"); 4491 DSSERR("can't ioremap DSI\n");
3692 r = -ENOMEM; 4492 r = -ENOMEM;
3693 goto err1; 4493 goto err1;
3694 } 4494 }
3695 dsi.irq = platform_get_irq(dsi.pdev, 0); 4495 dsi->irq = platform_get_irq(dsi->pdev, 0);
3696 if (dsi.irq < 0) { 4496 if (dsi->irq < 0) {
3697 DSSERR("platform_get_irq failed\n"); 4497 DSSERR("platform_get_irq failed\n");
3698 r = -ENODEV; 4498 r = -ENODEV;
3699 goto err2; 4499 goto err2;
3700 } 4500 }
3701 4501
3702 r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED, 4502 r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
3703 "OMAP DSI1", dsi.pdev); 4503 dev_name(&dsidev->dev), dsi->pdev);
3704 if (r < 0) { 4504 if (r < 0) {
3705 DSSERR("request_irq failed\n"); 4505 DSSERR("request_irq failed\n");
3706 goto err2; 4506 goto err2;
3707 } 4507 }
3708 4508
3709 /* DSI VCs initialization */ 4509 /* DSI VCs initialization */
3710 for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { 4510 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
3711 dsi.vc[i].mode = DSI_VC_MODE_L4; 4511 dsi->vc[i].mode = DSI_VC_MODE_L4;
3712 dsi.vc[i].dssdev = NULL; 4512 dsi->vc[i].dssdev = NULL;
3713 dsi.vc[i].vc_id = 0; 4513 dsi->vc[i].vc_id = 0;
3714 } 4514 }
3715 4515
3716 dsi_calc_clock_param_ranges(); 4516 dsi_calc_clock_param_ranges(dsidev);
3717 4517
3718 enable_clocks(1); 4518 enable_clocks(1);
3719 4519
3720 rev = dsi_read_reg(DSI_REVISION); 4520 rev = dsi_read_reg(dsidev, DSI_REVISION);
3721 dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n", 4521 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
3722 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 4522 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
3723 4523
4524 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
4525
3724 enable_clocks(0); 4526 enable_clocks(0);
3725 4527
3726 return 0; 4528 return 0;
3727err2: 4529err2:
3728 iounmap(dsi.base); 4530 iounmap(dsi->base);
3729err1: 4531err1:
3730 destroy_workqueue(dsi.workqueue); 4532 kfree(dsi);
4533err0:
3731 return r; 4534 return r;
3732} 4535}
3733 4536
3734static void dsi_exit(void) 4537static void dsi_exit(struct platform_device *dsidev)
3735{ 4538{
3736 if (dsi.vdds_dsi_reg != NULL) { 4539 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3737 regulator_put(dsi.vdds_dsi_reg); 4540
3738 dsi.vdds_dsi_reg = NULL; 4541 if (dsi->vdds_dsi_reg != NULL) {
4542 if (dsi->vdds_dsi_enabled) {
4543 regulator_disable(dsi->vdds_dsi_reg);
4544 dsi->vdds_dsi_enabled = false;
4545 }
4546
4547 regulator_put(dsi->vdds_dsi_reg);
4548 dsi->vdds_dsi_reg = NULL;
3739 } 4549 }
3740 4550
3741 free_irq(dsi.irq, dsi.pdev); 4551 free_irq(dsi->irq, dsi->pdev);
3742 iounmap(dsi.base); 4552 iounmap(dsi->base);
3743 4553
3744 destroy_workqueue(dsi.workqueue); 4554 kfree(dsi);
3745 4555
3746 DSSDBG("omap_dsi_exit\n"); 4556 DSSDBG("omap_dsi_exit\n");
3747} 4557}
3748 4558
3749/* DSI1 HW IP initialisation */ 4559/* DSI1 HW IP initialisation */
3750static int omap_dsi1hw_probe(struct platform_device *pdev) 4560static int omap_dsi1hw_probe(struct platform_device *dsidev)
3751{ 4561{
3752 int r; 4562 int r;
3753 dsi.pdev = pdev; 4563
3754 r = dsi_init(pdev); 4564 r = dsi_init(dsidev);
3755 if (r) { 4565 if (r) {
3756 DSSERR("Failed to initialize DSI\n"); 4566 DSSERR("Failed to initialize DSI\n");
3757 goto err_dsi; 4567 goto err_dsi;
@@ -3760,9 +4570,12 @@ err_dsi:
3760 return r; 4570 return r;
3761} 4571}
3762 4572
3763static int omap_dsi1hw_remove(struct platform_device *pdev) 4573static int omap_dsi1hw_remove(struct platform_device *dsidev)
3764{ 4574{
3765 dsi_exit(); 4575 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4576
4577 dsi_exit(dsidev);
4578 WARN_ON(dsi->scp_clk_refcount > 0);
3766 return 0; 4579 return 0;
3767} 4580}
3768 4581
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 3f1fee63c678..d9489d5c4f08 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -29,7 +29,7 @@
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31 31
32#include <plat/display.h> 32#include <video/omapdss.h>
33#include <plat/clock.h> 33#include <plat/clock.h>
34#include "dss.h" 34#include "dss.h"
35#include "dss_features.h" 35#include "dss_features.h"
@@ -45,7 +45,6 @@ struct dss_reg {
45#define DSS_REVISION DSS_REG(0x0000) 45#define DSS_REVISION DSS_REG(0x0000)
46#define DSS_SYSCONFIG DSS_REG(0x0010) 46#define DSS_SYSCONFIG DSS_REG(0x0010)
47#define DSS_SYSSTATUS DSS_REG(0x0014) 47#define DSS_SYSSTATUS DSS_REG(0x0014)
48#define DSS_IRQSTATUS DSS_REG(0x0018)
49#define DSS_CONTROL DSS_REG(0x0040) 48#define DSS_CONTROL DSS_REG(0x0040)
50#define DSS_SDI_CONTROL DSS_REG(0x0044) 49#define DSS_SDI_CONTROL DSS_REG(0x0044)
51#define DSS_PLL_CONTROL DSS_REG(0x0048) 50#define DSS_PLL_CONTROL DSS_REG(0x0048)
@@ -75,17 +74,17 @@ static struct {
75 struct dss_clock_info cache_dss_cinfo; 74 struct dss_clock_info cache_dss_cinfo;
76 struct dispc_clock_info cache_dispc_cinfo; 75 struct dispc_clock_info cache_dispc_cinfo;
77 76
78 enum dss_clk_source dsi_clk_source; 77 enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
79 enum dss_clk_source dispc_clk_source; 78 enum omap_dss_clk_source dispc_clk_source;
80 enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; 79 enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
81 80
82 u32 ctx[DSS_SZ_REGS / sizeof(u32)]; 81 u32 ctx[DSS_SZ_REGS / sizeof(u32)];
83} dss; 82} dss;
84 83
85static const char * const dss_generic_clk_source_names[] = { 84static const char * const dss_generic_clk_source_names[] = {
86 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", 85 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC",
87 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", 86 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI",
88 [DSS_CLK_SRC_FCK] = "DSS_FCK", 87 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK",
89}; 88};
90 89
91static void dss_clk_enable_all_no_ctx(void); 90static void dss_clk_enable_all_no_ctx(void);
@@ -230,7 +229,7 @@ void dss_sdi_disable(void)
230 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ 229 REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
231} 230}
232 231
233const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src) 232const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
234{ 233{
235 return dss_generic_clk_source_names[clk_src]; 234 return dss_generic_clk_source_names[clk_src];
236} 235}
@@ -246,8 +245,8 @@ void dss_dump_clocks(struct seq_file *s)
246 245
247 seq_printf(s, "- DSS -\n"); 246 seq_printf(s, "- DSS -\n");
248 247
249 fclk_name = dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK); 248 fclk_name = dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
250 fclk_real_name = dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK); 249 fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
251 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK); 250 fclk_rate = dss_clk_get_rate(DSS_CLK_FCK);
252 251
253 if (dss.dpll4_m4_ck) { 252 if (dss.dpll4_m4_ck) {
@@ -286,7 +285,6 @@ void dss_dump_regs(struct seq_file *s)
286 DUMPREG(DSS_REVISION); 285 DUMPREG(DSS_REVISION);
287 DUMPREG(DSS_SYSCONFIG); 286 DUMPREG(DSS_SYSCONFIG);
288 DUMPREG(DSS_SYSSTATUS); 287 DUMPREG(DSS_SYSSTATUS);
289 DUMPREG(DSS_IRQSTATUS);
290 DUMPREG(DSS_CONTROL); 288 DUMPREG(DSS_CONTROL);
291 289
292 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & 290 if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
@@ -300,18 +298,25 @@ void dss_dump_regs(struct seq_file *s)
300#undef DUMPREG 298#undef DUMPREG
301} 299}
302 300
303void dss_select_dispc_clk_source(enum dss_clk_source clk_src) 301void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
304{ 302{
303 struct platform_device *dsidev;
305 int b; 304 int b;
306 u8 start, end; 305 u8 start, end;
307 306
308 switch (clk_src) { 307 switch (clk_src) {
309 case DSS_CLK_SRC_FCK: 308 case OMAP_DSS_CLK_SRC_FCK:
310 b = 0; 309 b = 0;
311 break; 310 break;
312 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 311 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
313 b = 1; 312 b = 1;
314 dsi_wait_pll_hsdiv_dispc_active(); 313 dsidev = dsi_get_dsidev_from_id(0);
314 dsi_wait_pll_hsdiv_dispc_active(dsidev);
315 break;
316 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
317 b = 2;
318 dsidev = dsi_get_dsidev_from_id(1);
319 dsi_wait_pll_hsdiv_dispc_active(dsidev);
315 break; 320 break;
316 default: 321 default:
317 BUG(); 322 BUG();
@@ -324,17 +329,27 @@ void dss_select_dispc_clk_source(enum dss_clk_source clk_src)
324 dss.dispc_clk_source = clk_src; 329 dss.dispc_clk_source = clk_src;
325} 330}
326 331
327void dss_select_dsi_clk_source(enum dss_clk_source clk_src) 332void dss_select_dsi_clk_source(int dsi_module,
333 enum omap_dss_clk_source clk_src)
328{ 334{
335 struct platform_device *dsidev;
329 int b; 336 int b;
330 337
331 switch (clk_src) { 338 switch (clk_src) {
332 case DSS_CLK_SRC_FCK: 339 case OMAP_DSS_CLK_SRC_FCK:
333 b = 0; 340 b = 0;
334 break; 341 break;
335 case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: 342 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
343 BUG_ON(dsi_module != 0);
344 b = 1;
345 dsidev = dsi_get_dsidev_from_id(0);
346 dsi_wait_pll_hsdiv_dsi_active(dsidev);
347 break;
348 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
349 BUG_ON(dsi_module != 1);
336 b = 1; 350 b = 1;
337 dsi_wait_pll_hsdiv_dsi_active(); 351 dsidev = dsi_get_dsidev_from_id(1);
352 dsi_wait_pll_hsdiv_dsi_active(dsidev);
338 break; 353 break;
339 default: 354 default:
340 BUG(); 355 BUG();
@@ -342,25 +357,33 @@ void dss_select_dsi_clk_source(enum dss_clk_source clk_src)
342 357
343 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ 358 REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */
344 359
345 dss.dsi_clk_source = clk_src; 360 dss.dsi_clk_source[dsi_module] = clk_src;
346} 361}
347 362
348void dss_select_lcd_clk_source(enum omap_channel channel, 363void dss_select_lcd_clk_source(enum omap_channel channel,
349 enum dss_clk_source clk_src) 364 enum omap_dss_clk_source clk_src)
350{ 365{
366 struct platform_device *dsidev;
351 int b, ix, pos; 367 int b, ix, pos;
352 368
353 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) 369 if (!dss_has_feature(FEAT_LCD_CLK_SRC))
354 return; 370 return;
355 371
356 switch (clk_src) { 372 switch (clk_src) {
357 case DSS_CLK_SRC_FCK: 373 case OMAP_DSS_CLK_SRC_FCK:
358 b = 0; 374 b = 0;
359 break; 375 break;
360 case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 376 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
361 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD); 377 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
362 b = 1; 378 b = 1;
363 dsi_wait_pll_hsdiv_dispc_active(); 379 dsidev = dsi_get_dsidev_from_id(0);
380 dsi_wait_pll_hsdiv_dispc_active(dsidev);
381 break;
382 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
383 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2);
384 b = 1;
385 dsidev = dsi_get_dsidev_from_id(1);
386 dsi_wait_pll_hsdiv_dispc_active(dsidev);
364 break; 387 break;
365 default: 388 default:
366 BUG(); 389 BUG();
@@ -373,20 +396,26 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
373 dss.lcd_clk_source[ix] = clk_src; 396 dss.lcd_clk_source[ix] = clk_src;
374} 397}
375 398
376enum dss_clk_source dss_get_dispc_clk_source(void) 399enum omap_dss_clk_source dss_get_dispc_clk_source(void)
377{ 400{
378 return dss.dispc_clk_source; 401 return dss.dispc_clk_source;
379} 402}
380 403
381enum dss_clk_source dss_get_dsi_clk_source(void) 404enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
382{ 405{
383 return dss.dsi_clk_source; 406 return dss.dsi_clk_source[dsi_module];
384} 407}
385 408
386enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 409enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
387{ 410{
388 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 411 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
389 return dss.lcd_clk_source[ix]; 412 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1;
413 return dss.lcd_clk_source[ix];
414 } else {
415 /* LCD_CLK source is the same as DISPC_FCLK source for
416 * OMAP2 and OMAP3 */
417 return dss.dispc_clk_source;
418 }
390} 419}
391 420
392/* calculate clock rates using dividers in cinfo */ 421/* calculate clock rates using dividers in cinfo */
@@ -659,13 +688,18 @@ static int dss_init(void)
659 * the kernel resets it */ 688 * the kernel resets it */
660 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); 689 omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
661 690
691#ifdef CONFIG_OMAP2_DSS_SLEEP_BEFORE_RESET
662 /* We need to wait here a bit, otherwise we sometimes start to 692 /* We need to wait here a bit, otherwise we sometimes start to
663 * get synclost errors, and after that only power cycle will 693 * get synclost errors, and after that only power cycle will
664 * restore DSS functionality. I have no idea why this happens. 694 * restore DSS functionality. I have no idea why this happens.
665 * And we have to wait _before_ resetting the DSS, but after 695 * And we have to wait _before_ resetting the DSS, but after
666 * enabling clocks. 696 * enabling clocks.
697 *
698 * This bug was at least present on OMAP3430. It's unknown
699 * if it happens on OMAP2 or OMAP3630.
667 */ 700 */
668 msleep(50); 701 msleep(50);
702#endif
669 703
670 _omap_dss_reset(); 704 _omap_dss_reset();
671 705
@@ -700,10 +734,11 @@ static int dss_init(void)
700 734
701 dss.dpll4_m4_ck = dpll4_m4_ck; 735 dss.dpll4_m4_ck = dpll4_m4_ck;
702 736
703 dss.dsi_clk_source = DSS_CLK_SRC_FCK; 737 dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
704 dss.dispc_clk_source = DSS_CLK_SRC_FCK; 738 dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
705 dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; 739 dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
706 dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; 740 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
741 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
707 742
708 dss_save_context(); 743 dss_save_context();
709 744
@@ -1015,6 +1050,14 @@ static void core_dump_clocks(struct seq_file *s)
1015 dss.dss_video_fck 1050 dss.dss_video_fck
1016 }; 1051 };
1017 1052
1053 const char *names[5] = {
1054 "ick",
1055 "fck",
1056 "sys_clk",
1057 "tv_fck",
1058 "video_fck"
1059 };
1060
1018 seq_printf(s, "- CORE -\n"); 1061 seq_printf(s, "- CORE -\n");
1019 1062
1020 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled); 1063 seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
@@ -1022,8 +1065,11 @@ static void core_dump_clocks(struct seq_file *s)
1022 for (i = 0; i < 5; i++) { 1065 for (i = 0; i < 5; i++) {
1023 if (!clocks[i]) 1066 if (!clocks[i])
1024 continue; 1067 continue;
1025 seq_printf(s, "%-15s\t%lu\t%d\n", 1068 seq_printf(s, "%s (%s)%*s\t%lu\t%d\n",
1069 names[i],
1026 clocks[i]->name, 1070 clocks[i]->name,
1071 24 - strlen(names[i]) - strlen(clocks[i]->name),
1072 "",
1027 clk_get_rate(clocks[i]), 1073 clk_get_rate(clocks[i]),
1028 clocks[i]->usecount); 1074 clocks[i]->usecount);
1029 } 1075 }
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index c2f582bb19c0..8ab6d43329bb 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -117,15 +117,6 @@ enum dss_clock {
117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/ 117 DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
118}; 118};
119 119
120enum dss_clk_source {
121 DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK
122 * OMAP4: PLL1_CLK1 */
123 DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK
124 * OMAP4: PLL1_CLK2 */
125 DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK
126 * OMAP4: DSS_FCLK */
127};
128
129enum dss_hdmi_venc_clk_source_select { 120enum dss_hdmi_venc_clk_source_select {
130 DSS_VENC_TV_CLK = 0, 121 DSS_VENC_TV_CLK = 0,
131 DSS_HDMI_M_PCLK = 1, 122 DSS_HDMI_M_PCLK = 1,
@@ -236,7 +227,7 @@ void dss_clk_enable(enum dss_clock clks);
236void dss_clk_disable(enum dss_clock clks); 227void dss_clk_disable(enum dss_clock clks);
237unsigned long dss_clk_get_rate(enum dss_clock clk); 228unsigned long dss_clk_get_rate(enum dss_clock clk);
238int dss_need_ctx_restore(void); 229int dss_need_ctx_restore(void);
239const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src); 230const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
240void dss_dump_clocks(struct seq_file *s); 231void dss_dump_clocks(struct seq_file *s);
241 232
242void dss_dump_regs(struct seq_file *s); 233void dss_dump_regs(struct seq_file *s);
@@ -248,13 +239,14 @@ void dss_sdi_init(u8 datapairs);
248int dss_sdi_enable(void); 239int dss_sdi_enable(void);
249void dss_sdi_disable(void); 240void dss_sdi_disable(void);
250 241
251void dss_select_dispc_clk_source(enum dss_clk_source clk_src); 242void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
252void dss_select_dsi_clk_source(enum dss_clk_source clk_src); 243void dss_select_dsi_clk_source(int dsi_module,
244 enum omap_dss_clk_source clk_src);
253void dss_select_lcd_clk_source(enum omap_channel channel, 245void dss_select_lcd_clk_source(enum omap_channel channel,
254 enum dss_clk_source clk_src); 246 enum omap_dss_clk_source clk_src);
255enum dss_clk_source dss_get_dispc_clk_source(void); 247enum omap_dss_clk_source dss_get_dispc_clk_source(void);
256enum dss_clk_source dss_get_dsi_clk_source(void); 248enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
257enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); 249enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
258 250
259void dss_set_venc_output(enum omap_dss_venc_type type); 251void dss_set_venc_output(enum omap_dss_venc_type type);
260void dss_set_dac_pwrdn_bgz(bool enable); 252void dss_set_dac_pwrdn_bgz(bool enable);
@@ -284,31 +276,39 @@ static inline void sdi_exit(void)
284 276
285/* DSI */ 277/* DSI */
286#ifdef CONFIG_OMAP2_DSS_DSI 278#ifdef CONFIG_OMAP2_DSS_DSI
279
280struct dentry;
281struct file_operations;
282
287int dsi_init_platform_driver(void); 283int dsi_init_platform_driver(void);
288void dsi_uninit_platform_driver(void); 284void dsi_uninit_platform_driver(void);
289 285
290void dsi_dump_clocks(struct seq_file *s); 286void dsi_dump_clocks(struct seq_file *s);
291void dsi_dump_irqs(struct seq_file *s); 287void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir,
292void dsi_dump_regs(struct seq_file *s); 288 const struct file_operations *debug_fops);
289void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
290 const struct file_operations *debug_fops);
293 291
294void dsi_save_context(void); 292void dsi_save_context(void);
295void dsi_restore_context(void); 293void dsi_restore_context(void);
296 294
297int dsi_init_display(struct omap_dss_device *display); 295int dsi_init_display(struct omap_dss_device *display);
298void dsi_irq_handler(void); 296void dsi_irq_handler(void);
299unsigned long dsi_get_pll_hsdiv_dispc_rate(void); 297unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
300int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); 298int dsi_pll_set_clock_div(struct platform_device *dsidev,
301int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, 299 struct dsi_clock_info *cinfo);
302 struct dsi_clock_info *cinfo, 300int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
301 unsigned long req_pck, struct dsi_clock_info *cinfo,
303 struct dispc_clock_info *dispc_cinfo); 302 struct dispc_clock_info *dispc_cinfo);
304int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, 303int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
305 bool enable_hsdiv); 304 bool enable_hsdiv);
306void dsi_pll_uninit(void); 305void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
307void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, 306void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
308 u32 fifo_size, enum omap_burst_size *burst_size, 307 u32 fifo_size, enum omap_burst_size *burst_size,
309 u32 *fifo_low, u32 *fifo_high); 308 u32 *fifo_low, u32 *fifo_high);
310void dsi_wait_pll_hsdiv_dispc_active(void); 309void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
311void dsi_wait_pll_hsdiv_dsi_active(void); 310void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
311struct platform_device *dsi_get_dsidev_from_id(int module);
312#else 312#else
313static inline int dsi_init_platform_driver(void) 313static inline int dsi_init_platform_driver(void)
314{ 314{
@@ -317,17 +317,47 @@ static inline int dsi_init_platform_driver(void)
317static inline void dsi_uninit_platform_driver(void) 317static inline void dsi_uninit_platform_driver(void)
318{ 318{
319} 319}
320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void) 320static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
321{ 321{
322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__); 322 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
323 return 0; 323 return 0;
324} 324}
325static inline void dsi_wait_pll_hsdiv_dispc_active(void) 325static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
326 struct dsi_clock_info *cinfo)
327{
328 WARN("%s: DSI not compiled in\n", __func__);
329 return -ENODEV;
330}
331static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
332 bool is_tft, unsigned long req_pck,
333 struct dsi_clock_info *dsi_cinfo,
334 struct dispc_clock_info *dispc_cinfo)
335{
336 WARN("%s: DSI not compiled in\n", __func__);
337 return -ENODEV;
338}
339static inline int dsi_pll_init(struct platform_device *dsidev,
340 bool enable_hsclk, bool enable_hsdiv)
326{ 341{
342 WARN("%s: DSI not compiled in\n", __func__);
343 return -ENODEV;
327} 344}
328static inline void dsi_wait_pll_hsdiv_dsi_active(void) 345static inline void dsi_pll_uninit(struct platform_device *dsidev,
346 bool disconnect_lanes)
329{ 347{
330} 348}
349static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
350{
351}
352static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
353{
354}
355static inline struct platform_device *dsi_get_dsidev_from_id(int module)
356{
357 WARN("%s: DSI not compiled in, returning platform device as NULL\n",
358 __func__);
359 return NULL;
360}
331#endif 361#endif
332 362
333/* DPI */ 363/* DPI */
@@ -391,7 +421,8 @@ int dispc_setup_plane(enum omap_plane plane,
391 enum omap_dss_rotation_type rotation_type, 421 enum omap_dss_rotation_type rotation_type,
392 u8 rotation, bool mirror, 422 u8 rotation, bool mirror,
393 u8 global_alpha, u8 pre_mult_alpha, 423 u8 global_alpha, u8 pre_mult_alpha,
394 enum omap_channel channel); 424 enum omap_channel channel,
425 u32 puv_addr);
395 426
396bool dispc_go_busy(enum omap_channel channel); 427bool dispc_go_busy(enum omap_channel channel);
397void dispc_go(enum omap_channel channel); 428void dispc_go(enum omap_channel channel);
@@ -485,13 +516,6 @@ void hdmi_panel_exit(void);
485int rfbi_init_platform_driver(void); 516int rfbi_init_platform_driver(void);
486void rfbi_uninit_platform_driver(void); 517void rfbi_uninit_platform_driver(void);
487void rfbi_dump_regs(struct seq_file *s); 518void rfbi_dump_regs(struct seq_file *s);
488
489int rfbi_configure(int rfbi_module, int bpp, int lines);
490void rfbi_enable_rfbi(bool enable);
491void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
492 u16 height, void (callback)(void *data), void *data);
493void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
494unsigned long rfbi_get_max_tx_rate(void);
495int rfbi_init_display(struct omap_dss_device *display); 519int rfbi_init_display(struct omap_dss_device *display);
496#else 520#else
497static inline int rfbi_init_platform_driver(void) 521static inline int rfbi_init_platform_driver(void)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index aa1622241d0d..1c18888e5df3 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -22,7 +22,7 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25#include <plat/display.h> 25#include <video/omapdss.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27 27
28#include "dss.h" 28#include "dss.h"
@@ -52,7 +52,7 @@ struct omap_dss_features {
52}; 52};
53 53
54/* This struct is assigned to one of the below during initialization */ 54/* This struct is assigned to one of the below during initialization */
55static struct omap_dss_features *omap_current_dss_features; 55static const struct omap_dss_features *omap_current_dss_features;
56 56
57static const struct dss_reg_field omap2_dss_reg_fields[] = { 57static const struct dss_reg_field omap2_dss_reg_fields[] = {
58 [FEAT_REG_FIRHINC] = { 11, 0 }, 58 [FEAT_REG_FIRHINC] = { 11, 0 },
@@ -177,22 +177,55 @@ static const enum omap_color_mode omap3_dss_supported_color_modes[] = {
177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, 177 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
178}; 178};
179 179
180static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
181 /* OMAP_DSS_GFX */
182 OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
183 OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
184 OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
185 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
186 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
187 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 |
188 OMAP_DSS_COLOR_ARGB16_1555,
189
190 /* OMAP_DSS_VIDEO1 */
191 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
192 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
193 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
194 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
195 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
196 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
197 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
198 OMAP_DSS_COLOR_RGBX32,
199
200 /* OMAP_DSS_VIDEO2 */
201 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
202 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
203 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
204 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
205 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
206 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
207 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
208 OMAP_DSS_COLOR_RGBX32,
209};
210
180static const char * const omap2_dss_clk_source_names[] = { 211static const char * const omap2_dss_clk_source_names[] = {
181 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A", 212 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "N/A",
182 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A", 213 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "N/A",
183 [DSS_CLK_SRC_FCK] = "DSS_FCLK1", 214 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK1",
184}; 215};
185 216
186static const char * const omap3_dss_clk_source_names[] = { 217static const char * const omap3_dss_clk_source_names[] = {
187 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK", 218 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI1_PLL_FCLK",
188 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK", 219 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI2_PLL_FCLK",
189 [DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK", 220 [OMAP_DSS_CLK_SRC_FCK] = "DSS1_ALWON_FCLK",
190}; 221};
191 222
192static const char * const omap4_dss_clk_source_names[] = { 223static const char * const omap4_dss_clk_source_names[] = {
193 [DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1", 224 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "PLL1_CLK1",
194 [DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2", 225 [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "PLL1_CLK2",
195 [DSS_CLK_SRC_FCK] = "DSS_FCLK", 226 [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCLK",
227 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "PLL2_CLK1",
228 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2",
196}; 229};
197 230
198static const struct dss_param_range omap2_dss_param_range[] = { 231static const struct dss_param_range omap2_dss_param_range[] = {
@@ -226,7 +259,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
226}; 259};
227 260
228/* OMAP2 DSS Features */ 261/* OMAP2 DSS Features */
229static struct omap_dss_features omap2_dss_features = { 262static const struct omap_dss_features omap2_dss_features = {
230 .reg_fields = omap2_dss_reg_fields, 263 .reg_fields = omap2_dss_reg_fields,
231 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields), 264 .num_reg_fields = ARRAY_SIZE(omap2_dss_reg_fields),
232 265
@@ -244,7 +277,7 @@ static struct omap_dss_features omap2_dss_features = {
244}; 277};
245 278
246/* OMAP3 DSS Features */ 279/* OMAP3 DSS Features */
247static struct omap_dss_features omap3430_dss_features = { 280static const struct omap_dss_features omap3430_dss_features = {
248 .reg_fields = omap3_dss_reg_fields, 281 .reg_fields = omap3_dss_reg_fields,
249 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 282 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
250 283
@@ -252,7 +285,8 @@ static struct omap_dss_features omap3430_dss_features = {
252 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 285 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
253 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 286 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
254 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | 287 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
255 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF, 288 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
289 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC,
256 290
257 .num_mgrs = 2, 291 .num_mgrs = 2,
258 .num_ovls = 3, 292 .num_ovls = 3,
@@ -262,7 +296,7 @@ static struct omap_dss_features omap3430_dss_features = {
262 .dss_params = omap3_dss_param_range, 296 .dss_params = omap3_dss_param_range,
263}; 297};
264 298
265static struct omap_dss_features omap3630_dss_features = { 299static const struct omap_dss_features omap3630_dss_features = {
266 .reg_fields = omap3_dss_reg_fields, 300 .reg_fields = omap3_dss_reg_fields,
267 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 301 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
268 302
@@ -271,7 +305,8 @@ static struct omap_dss_features omap3630_dss_features = {
271 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 305 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
272 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | 306 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
273 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | 307 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
274 FEAT_RESIZECONF, 308 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
309 FEAT_DSI_PLL_FREQSEL,
275 310
276 .num_mgrs = 2, 311 .num_mgrs = 2,
277 .num_ovls = 3, 312 .num_ovls = 3,
@@ -282,19 +317,43 @@ static struct omap_dss_features omap3630_dss_features = {
282}; 317};
283 318
284/* OMAP4 DSS Features */ 319/* OMAP4 DSS Features */
285static struct omap_dss_features omap4_dss_features = { 320/* For OMAP4430 ES 1.0 revision */
321static const struct omap_dss_features omap4430_es1_0_dss_features = {
286 .reg_fields = omap4_dss_reg_fields, 322 .reg_fields = omap4_dss_reg_fields,
287 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 323 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
288 324
289 .has_feature = 325 .has_feature =
290 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 326 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
291 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | 327 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
292 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC, 328 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
329 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
330 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
293 331
294 .num_mgrs = 3, 332 .num_mgrs = 3,
295 .num_ovls = 3, 333 .num_ovls = 3,
296 .supported_displays = omap4_dss_supported_displays, 334 .supported_displays = omap4_dss_supported_displays,
297 .supported_color_modes = omap3_dss_supported_color_modes, 335 .supported_color_modes = omap4_dss_supported_color_modes,
336 .clksrc_names = omap4_dss_clk_source_names,
337 .dss_params = omap4_dss_param_range,
338};
339
340/* For all the other OMAP4 versions */
341static const struct omap_dss_features omap4_dss_features = {
342 .reg_fields = omap4_dss_reg_fields,
343 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
344
345 .has_feature =
346 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
347 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
348 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
349 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
350 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
351 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2,
352
353 .num_mgrs = 3,
354 .num_ovls = 3,
355 .supported_displays = omap4_dss_supported_displays,
356 .supported_color_modes = omap4_dss_supported_color_modes,
298 .clksrc_names = omap4_dss_clk_source_names, 357 .clksrc_names = omap4_dss_clk_source_names,
299 .dss_params = omap4_dss_param_range, 358 .dss_params = omap4_dss_param_range,
300}; 359};
@@ -337,7 +396,7 @@ bool dss_feat_color_mode_supported(enum omap_plane plane,
337 color_mode; 396 color_mode;
338} 397}
339 398
340const char *dss_feat_get_clk_source_name(enum dss_clk_source id) 399const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id)
341{ 400{
342 return omap_current_dss_features->clksrc_names[id]; 401 return omap_current_dss_features->clksrc_names[id];
343} 402}
@@ -365,6 +424,10 @@ void dss_features_init(void)
365 omap_current_dss_features = &omap3630_dss_features; 424 omap_current_dss_features = &omap3630_dss_features;
366 else if (cpu_is_omap34xx()) 425 else if (cpu_is_omap34xx())
367 omap_current_dss_features = &omap3430_dss_features; 426 omap_current_dss_features = &omap3430_dss_features;
368 else 427 else if (omap_rev() == OMAP4430_REV_ES1_0)
428 omap_current_dss_features = &omap4430_es1_0_dss_features;
429 else if (cpu_is_omap44xx())
369 omap_current_dss_features = &omap4_dss_features; 430 omap_current_dss_features = &omap4_dss_features;
431 else
432 DSSWARN("Unsupported OMAP version");
370} 433}
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 12e9c4ef0dec..07b346f7d916 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -23,23 +23,34 @@
23#define MAX_DSS_MANAGERS 3 23#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 24#define MAX_DSS_OVERLAYS 3
25#define MAX_DSS_LCD_MANAGERS 2 25#define MAX_DSS_LCD_MANAGERS 2
26#define MAX_NUM_DSI 2
26 27
27/* DSS has feature id */ 28/* DSS has feature id */
28enum dss_feat_id { 29enum dss_feat_id {
29 FEAT_GLOBAL_ALPHA = 1 << 0, 30 FEAT_GLOBAL_ALPHA = 1 << 0,
30 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1, 31 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
31 FEAT_PRE_MULT_ALPHA = 1 << 2, 32 FEAT_PRE_MULT_ALPHA = 1 << 2,
32 FEAT_LCDENABLEPOL = 1 << 3, 33 FEAT_LCDENABLEPOL = 1 << 3,
33 FEAT_LCDENABLESIGNAL = 1 << 4, 34 FEAT_LCDENABLESIGNAL = 1 << 4,
34 FEAT_PCKFREEENABLE = 1 << 5, 35 FEAT_PCKFREEENABLE = 1 << 5,
35 FEAT_FUNCGATED = 1 << 6, 36 FEAT_FUNCGATED = 1 << 6,
36 FEAT_MGR_LCD2 = 1 << 7, 37 FEAT_MGR_LCD2 = 1 << 7,
37 FEAT_LINEBUFFERSPLIT = 1 << 8, 38 FEAT_LINEBUFFERSPLIT = 1 << 8,
38 FEAT_ROWREPEATENABLE = 1 << 9, 39 FEAT_ROWREPEATENABLE = 1 << 9,
39 FEAT_RESIZECONF = 1 << 10, 40 FEAT_RESIZECONF = 1 << 10,
40 /* Independent core clk divider */ 41 /* Independent core clk divider */
41 FEAT_CORE_CLK_DIV = 1 << 11, 42 FEAT_CORE_CLK_DIV = 1 << 11,
42 FEAT_LCD_CLK_SRC = 1 << 12, 43 FEAT_LCD_CLK_SRC = 1 << 12,
44 /* DSI-PLL power command 0x3 is not working */
45 FEAT_DSI_PLL_PWR_BUG = 1 << 13,
46 FEAT_DSI_PLL_FREQSEL = 1 << 14,
47 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15,
48 FEAT_DSI_VC_OCP_WIDTH = 1 << 16,
49 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17,
50 FEAT_DSI_GNQ = 1 << 18,
51 FEAT_HDMI_CTS_SWMODE = 1 << 19,
52 FEAT_HANDLE_UV_SEPARATE = 1 << 20,
53 FEAT_ATTR2 = 1 << 21,
43}; 54};
44 55
45/* DSS register field id */ 56/* DSS register field id */
@@ -77,7 +88,7 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
77enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 88enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
78bool dss_feat_color_mode_supported(enum omap_plane plane, 89bool dss_feat_color_mode_supported(enum omap_plane plane,
79 enum omap_color_mode color_mode); 90 enum omap_color_mode color_mode);
80const char *dss_feat_get_clk_source_name(enum dss_clk_source id); 91const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
81 92
82bool dss_has_feature(enum dss_feat_id id); 93bool dss_has_feature(enum dss_feat_id id);
83void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 94void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a981def8099a..b0555f4f0a78 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -29,10 +29,16 @@
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <plat/display.h> 32#include <video/omapdss.h>
33#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
34 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
35#include <sound/soc.h>
36#include <sound/pcm_params.h>
37#endif
33 38
34#include "dss.h" 39#include "dss.h"
35#include "hdmi.h" 40#include "hdmi.h"
41#include "dss_features.h"
36 42
37static struct { 43static struct {
38 struct mutex lock; 44 struct mutex lock;
@@ -1052,25 +1058,26 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
1052 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; 1058 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1053} 1059}
1054 1060
1055static void hdmi_compute_pll(unsigned long clkin, int phy, 1061static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1056 int n, struct hdmi_pll_info *pi) 1062 struct hdmi_pll_info *pi)
1057{ 1063{
1058 unsigned long refclk; 1064 unsigned long clkin, refclk;
1059 u32 mf; 1065 u32 mf;
1060 1066
1067 clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000;
1061 /* 1068 /*
1062 * Input clock is predivided by N + 1 1069 * Input clock is predivided by N + 1
1063 * out put of which is reference clk 1070 * out put of which is reference clk
1064 */ 1071 */
1065 refclk = clkin / (n + 1); 1072 pi->regn = dssdev->clocks.hdmi.regn;
1066 pi->regn = n; 1073 refclk = clkin / (pi->regn + 1);
1067 1074
1068 /* 1075 /*
1069 * multiplier is pixel_clk/ref_clk 1076 * multiplier is pixel_clk/ref_clk
1070 * Multiplying by 100 to avoid fractional part removal 1077 * Multiplying by 100 to avoid fractional part removal
1071 */ 1078 */
1072 pi->regm = (phy * 100/(refclk))/100; 1079 pi->regm = (phy * 100 / (refclk)) / 100;
1073 pi->regm2 = 1; 1080 pi->regm2 = dssdev->clocks.hdmi.regm2;
1074 1081
1075 /* 1082 /*
1076 * fractional multiplier is remainder of the difference between 1083 * fractional multiplier is remainder of the difference between
@@ -1078,14 +1085,14 @@ static void hdmi_compute_pll(unsigned long clkin, int phy,
1078 * multiplied by 2^18(262144) divided by the reference clock 1085 * multiplied by 2^18(262144) divided by the reference clock
1079 */ 1086 */
1080 mf = (phy - pi->regm * refclk) * 262144; 1087 mf = (phy - pi->regm * refclk) * 262144;
1081 pi->regmf = mf/(refclk); 1088 pi->regmf = mf / (refclk);
1082 1089
1083 /* 1090 /*
1084 * Dcofreq should be set to 1 if required pixel clock 1091 * Dcofreq should be set to 1 if required pixel clock
1085 * is greater than 1000MHz 1092 * is greater than 1000MHz
1086 */ 1093 */
1087 pi->dcofreq = phy > 1000 * 100; 1094 pi->dcofreq = phy > 1000 * 100;
1088 pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10; 1095 pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10;
1089 1096
1090 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); 1097 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1091 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 1098 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
@@ -1106,7 +1113,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1106 int r, code = 0; 1113 int r, code = 0;
1107 struct hdmi_pll_info pll_data; 1114 struct hdmi_pll_info pll_data;
1108 struct omap_video_timings *p; 1115 struct omap_video_timings *p;
1109 int clkin, n, phy; 1116 unsigned long phy;
1110 1117
1111 hdmi_enable_clocks(1); 1118 hdmi_enable_clocks(1);
1112 1119
@@ -1126,11 +1133,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1126 dssdev->panel.timings = cea_vesa_timings[code].timings; 1133 dssdev->panel.timings = cea_vesa_timings[code].timings;
1127 update_hdmi_timings(&hdmi.cfg, p, code); 1134 update_hdmi_timings(&hdmi.cfg, p, code);
1128 1135
1129 clkin = 3840; /* 38.4 MHz */
1130 n = 15; /* this is a constant for our math */
1131 phy = p->pixel_clock; 1136 phy = p->pixel_clock;
1132 1137
1133 hdmi_compute_pll(clkin, phy, n, &pll_data); 1138 hdmi_compute_pll(dssdev, phy, &pll_data);
1134 1139
1135 hdmi_wp_video_start(0); 1140 hdmi_wp_video_start(0);
1136 1141
@@ -1160,7 +1165,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1160 * dynamically by user. This can be moved to single location , say 1165 * dynamically by user. This can be moved to single location , say
1161 * Boardfile. 1166 * Boardfile.
1162 */ 1167 */
1163 dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); 1168 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
1164 1169
1165 /* bypass TV gamma table */ 1170 /* bypass TV gamma table */
1166 dispc_enable_gamma_table(0); 1171 dispc_enable_gamma_table(0);
@@ -1275,10 +1280,420 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1275 mutex_unlock(&hdmi.lock); 1280 mutex_unlock(&hdmi.lock);
1276} 1281}
1277 1282
1283#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1284 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1285static void hdmi_wp_audio_config_format(
1286 struct hdmi_audio_format *aud_fmt)
1287{
1288 u32 r;
1289
1290 DSSDBG("Enter hdmi_wp_audio_config_format\n");
1291
1292 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG);
1293 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
1294 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
1295 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
1296 r = FLD_MOD(r, aud_fmt->type, 4, 4);
1297 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
1298 r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
1299 r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
1300 r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
1301 hdmi_write_reg(HDMI_WP_AUDIO_CFG, r);
1302}
1303
1304static void hdmi_wp_audio_config_dma(struct hdmi_audio_dma *aud_dma)
1305{
1306 u32 r;
1307
1308 DSSDBG("Enter hdmi_wp_audio_config_dma\n");
1309
1310 r = hdmi_read_reg(HDMI_WP_AUDIO_CFG2);
1311 r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
1312 r = FLD_MOD(r, aud_dma->block_size, 7, 0);
1313 hdmi_write_reg(HDMI_WP_AUDIO_CFG2, r);
1314
1315 r = hdmi_read_reg(HDMI_WP_AUDIO_CTRL);
1316 r = FLD_MOD(r, aud_dma->mode, 9, 9);
1317 r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
1318 hdmi_write_reg(HDMI_WP_AUDIO_CTRL, r);
1319}
1320
1321static void hdmi_core_audio_config(struct hdmi_core_audio_config *cfg)
1322{
1323 u32 r;
1324
1325 /* audio clock recovery parameters */
1326 r = hdmi_read_reg(HDMI_CORE_AV_ACR_CTRL);
1327 r = FLD_MOD(r, cfg->use_mclk, 2, 2);
1328 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1329 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1330 hdmi_write_reg(HDMI_CORE_AV_ACR_CTRL, r);
1331
1332 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1333 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1334 REG_FLD_MOD(HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
1335
1336 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
1337 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
1338 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
1339 REG_FLD_MOD(HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1340 } else {
1341 /*
1342 * HDMI IP uses this configuration to divide the MCLK to
1343 * update CTS value.
1344 */
1345 REG_FLD_MOD(HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1346
1347 /* Configure clock for audio packets */
1348 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1349 cfg->aud_par_busclk, 7, 0);
1350 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
1351 (cfg->aud_par_busclk >> 8), 7, 0);
1352 REG_FLD_MOD(HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
1353 (cfg->aud_par_busclk >> 16), 7, 0);
1354 }
1355
1356 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1357 REG_FLD_MOD(HDMI_CORE_AV_SPDIF_CTRL, cfg->fs_override, 1, 1);
1358
1359 /* I2S parameters */
1360 REG_FLD_MOD(HDMI_CORE_AV_I2S_CHST4, cfg->freq_sample, 3, 0);
1361
1362 r = hdmi_read_reg(HDMI_CORE_AV_I2S_IN_CTRL);
1363 r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
1364 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
1365 r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
1366 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
1367 r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
1368 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
1369 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
1370 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
1371 hdmi_write_reg(HDMI_CORE_AV_I2S_IN_CTRL, r);
1372
1373 r = hdmi_read_reg(HDMI_CORE_AV_I2S_CHST5);
1374 r = FLD_MOD(r, cfg->freq_sample, 7, 4);
1375 r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
1376 r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
1377 hdmi_write_reg(HDMI_CORE_AV_I2S_CHST5, r);
1378
1379 REG_FLD_MOD(HDMI_CORE_AV_I2S_IN_LEN, cfg->i2s_cfg.in_length_bits, 3, 0);
1380
1381 /* Audio channels and mode parameters */
1382 REG_FLD_MOD(HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
1383 r = hdmi_read_reg(HDMI_CORE_AV_AUD_MODE);
1384 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
1385 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
1386 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
1387 r = FLD_MOD(r, cfg->en_spdif, 1, 1);
1388 hdmi_write_reg(HDMI_CORE_AV_AUD_MODE, r);
1389}
1390
1391static void hdmi_core_audio_infoframe_config(
1392 struct hdmi_core_infoframe_audio *info_aud)
1393{
1394 u8 val;
1395 u8 sum = 0, checksum = 0;
1396
1397 /*
1398 * Set audio info frame type, version and length as
1399 * described in HDMI 1.4a Section 8.2.2 specification.
1400 * Checksum calculation is defined in Section 5.3.5.
1401 */
1402 hdmi_write_reg(HDMI_CORE_AV_AUDIO_TYPE, 0x84);
1403 hdmi_write_reg(HDMI_CORE_AV_AUDIO_VERS, 0x01);
1404 hdmi_write_reg(HDMI_CORE_AV_AUDIO_LEN, 0x0a);
1405 sum += 0x84 + 0x001 + 0x00a;
1406
1407 val = (info_aud->db1_coding_type << 4)
1408 | (info_aud->db1_channel_count - 1);
1409 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(0), val);
1410 sum += val;
1411
1412 val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
1413 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(1), val);
1414 sum += val;
1415
1416 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
1417
1418 val = info_aud->db4_channel_alloc;
1419 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(3), val);
1420 sum += val;
1421
1422 val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
1423 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(4), val);
1424 sum += val;
1425
1426 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
1427 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
1428 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
1429 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
1430 hdmi_write_reg(HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
1431
1432 checksum = 0x100 - sum;
1433 hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum);
1434
1435 /*
1436 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
1437 * is available.
1438 */
1439}
1440
1441static int hdmi_config_audio_acr(u32 sample_freq, u32 *n, u32 *cts)
1442{
1443 u32 r;
1444 u32 deep_color = 0;
1445 u32 pclk = hdmi.cfg.timings.timings.pixel_clock;
1446
1447 if (n == NULL || cts == NULL)
1448 return -EINVAL;
1449 /*
1450 * Obtain current deep color configuration. This needed
1451 * to calculate the TMDS clock based on the pixel clock.
1452 */
1453 r = REG_GET(HDMI_WP_VIDEO_CFG, 1, 0);
1454 switch (r) {
1455 case 1: /* No deep color selected */
1456 deep_color = 100;
1457 break;
1458 case 2: /* 10-bit deep color selected */
1459 deep_color = 125;
1460 break;
1461 case 3: /* 12-bit deep color selected */
1462 deep_color = 150;
1463 break;
1464 default:
1465 return -EINVAL;
1466 }
1467
1468 switch (sample_freq) {
1469 case 32000:
1470 if ((deep_color == 125) && ((pclk == 54054)
1471 || (pclk == 74250)))
1472 *n = 8192;
1473 else
1474 *n = 4096;
1475 break;
1476 case 44100:
1477 *n = 6272;
1478 break;
1479 case 48000:
1480 if ((deep_color == 125) && ((pclk == 54054)
1481 || (pclk == 74250)))
1482 *n = 8192;
1483 else
1484 *n = 6144;
1485 break;
1486 default:
1487 *n = 0;
1488 return -EINVAL;
1489 }
1490
1491 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
1492 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
1493
1494 return 0;
1495}
1496
1497static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1498 struct snd_pcm_hw_params *params,
1499 struct snd_soc_dai *dai)
1500{
1501 struct hdmi_audio_format audio_format;
1502 struct hdmi_audio_dma audio_dma;
1503 struct hdmi_core_audio_config core_cfg;
1504 struct hdmi_core_infoframe_audio aud_if_cfg;
1505 int err, n, cts;
1506 enum hdmi_core_audio_sample_freq sample_freq;
1507
1508 switch (params_format(params)) {
1509 case SNDRV_PCM_FORMAT_S16_LE:
1510 core_cfg.i2s_cfg.word_max_length =
1511 HDMI_AUDIO_I2S_MAX_WORD_20BITS;
1512 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS;
1513 core_cfg.i2s_cfg.in_length_bits =
1514 HDMI_AUDIO_I2S_INPUT_LENGTH_16;
1515 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;
1516 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
1517 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
1518 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
1519 audio_dma.transfer_size = 0x10;
1520 break;
1521 case SNDRV_PCM_FORMAT_S24_LE:
1522 core_cfg.i2s_cfg.word_max_length =
1523 HDMI_AUDIO_I2S_MAX_WORD_24BITS;
1524 core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS;
1525 core_cfg.i2s_cfg.in_length_bits =
1526 HDMI_AUDIO_I2S_INPUT_LENGTH_24;
1527 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE;
1528 audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS;
1529 audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
1530 core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;
1531 audio_dma.transfer_size = 0x20;
1532 break;
1533 default:
1534 return -EINVAL;
1535 }
1536
1537 switch (params_rate(params)) {
1538 case 32000:
1539 sample_freq = HDMI_AUDIO_FS_32000;
1540 break;
1541 case 44100:
1542 sample_freq = HDMI_AUDIO_FS_44100;
1543 break;
1544 case 48000:
1545 sample_freq = HDMI_AUDIO_FS_48000;
1546 break;
1547 default:
1548 return -EINVAL;
1549 }
1550
1551 err = hdmi_config_audio_acr(params_rate(params), &n, &cts);
1552 if (err < 0)
1553 return err;
1554
1555 /* Audio wrapper config */
1556 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
1557 audio_format.active_chnnls_msk = 0x03;
1558 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
1559 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
1560 /* Disable start/stop signals of IEC 60958 blocks */
1561 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF;
1562
1563 audio_dma.block_size = 0xC0;
1564 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
1565 audio_dma.fifo_threshold = 0x20; /* in number of samples */
1566
1567 hdmi_wp_audio_config_dma(&audio_dma);
1568 hdmi_wp_audio_config_format(&audio_format);
1569
1570 /*
1571 * I2S config
1572 */
1573 core_cfg.i2s_cfg.en_high_bitrate_aud = false;
1574 /* Only used with high bitrate audio */
1575 core_cfg.i2s_cfg.cbit_order = false;
1576 /* Serial data and word select should change on sck rising edge */
1577 core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING;
1578 core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM;
1579 /* Set I2S word select polarity */
1580 core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT;
1581 core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST;
1582 /* Set serial data to word select shift. See Phillips spec. */
1583 core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;
1584 /* Enable one of the four available serial data channels */
1585 core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN;
1586
1587 /* Core audio config */
1588 core_cfg.freq_sample = sample_freq;
1589 core_cfg.n = n;
1590 core_cfg.cts = cts;
1591 if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) {
1592 core_cfg.aud_par_busclk = 0;
1593 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW;
1594 core_cfg.use_mclk = false;
1595 } else {
1596 core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8);
1597 core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW;
1598 core_cfg.use_mclk = true;
1599 core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS;
1600 }
1601 core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH;
1602 core_cfg.en_spdif = false;
1603 /* Use sample frequency from channel status word */
1604 core_cfg.fs_override = true;
1605 /* Enable ACR packets */
1606 core_cfg.en_acr_pkt = true;
1607 /* Disable direct streaming digital audio */
1608 core_cfg.en_dsd_audio = false;
1609 /* Use parallel audio interface */
1610 core_cfg.en_parallel_aud_input = true;
1611
1612 hdmi_core_audio_config(&core_cfg);
1613
1614 /*
1615 * Configure packet
1616 * info frame audio see doc CEA861-D page 74
1617 */
1618 aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM;
1619 aud_if_cfg.db1_channel_count = 2;
1620 aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM;
1621 aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM;
1622 aud_if_cfg.db4_channel_alloc = 0x00;
1623 aud_if_cfg.db5_downmix_inh = false;
1624 aud_if_cfg.db5_lsv = 0;
1625
1626 hdmi_core_audio_infoframe_config(&aud_if_cfg);
1627 return 0;
1628}
1629
1630static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
1631 struct snd_soc_dai *dai)
1632{
1633 int err = 0;
1634 switch (cmd) {
1635 case SNDRV_PCM_TRIGGER_START:
1636 case SNDRV_PCM_TRIGGER_RESUME:
1637 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1638 REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
1639 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 31, 31);
1640 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 1, 30, 30);
1641 break;
1642
1643 case SNDRV_PCM_TRIGGER_STOP:
1644 case SNDRV_PCM_TRIGGER_SUSPEND:
1645 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1646 REG_FLD_MOD(HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
1647 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 30, 30);
1648 REG_FLD_MOD(HDMI_WP_AUDIO_CTRL, 0, 31, 31);
1649 break;
1650 default:
1651 err = -EINVAL;
1652 }
1653 return err;
1654}
1655
1656static int hdmi_audio_startup(struct snd_pcm_substream *substream,
1657 struct snd_soc_dai *dai)
1658{
1659 if (!hdmi.mode) {
1660 pr_err("Current video settings do not support audio.\n");
1661 return -EIO;
1662 }
1663 return 0;
1664}
1665
1666static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
1667};
1668
1669static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
1670 .hw_params = hdmi_audio_hw_params,
1671 .trigger = hdmi_audio_trigger,
1672 .startup = hdmi_audio_startup,
1673};
1674
1675static struct snd_soc_dai_driver hdmi_codec_dai_drv = {
1676 .name = "hdmi-audio-codec",
1677 .playback = {
1678 .channels_min = 2,
1679 .channels_max = 2,
1680 .rates = SNDRV_PCM_RATE_32000 |
1681 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
1682 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1683 SNDRV_PCM_FMTBIT_S24_LE,
1684 },
1685 .ops = &hdmi_audio_codec_ops,
1686};
1687#endif
1688
1278/* HDMI HW IP initialisation */ 1689/* HDMI HW IP initialisation */
1279static int omapdss_hdmihw_probe(struct platform_device *pdev) 1690static int omapdss_hdmihw_probe(struct platform_device *pdev)
1280{ 1691{
1281 struct resource *hdmi_mem; 1692 struct resource *hdmi_mem;
1693#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1694 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1695 int ret;
1696#endif
1282 1697
1283 hdmi.pdata = pdev->dev.platform_data; 1698 hdmi.pdata = pdev->dev.platform_data;
1284 hdmi.pdev = pdev; 1699 hdmi.pdev = pdev;
@@ -1300,6 +1715,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1300 1715
1301 hdmi_panel_init(); 1716 hdmi_panel_init();
1302 1717
1718#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1719 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1720
1721 /* Register ASoC codec DAI */
1722 ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv,
1723 &hdmi_codec_dai_drv, 1);
1724 if (ret) {
1725 DSSERR("can't register ASoC HDMI audio codec\n");
1726 return ret;
1727 }
1728#endif
1303 return 0; 1729 return 0;
1304} 1730}
1305 1731
@@ -1307,6 +1733,11 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
1307{ 1733{
1308 hdmi_panel_exit(); 1734 hdmi_panel_exit();
1309 1735
1736#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1737 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
1738 snd_soc_unregister_codec(&pdev->dev);
1739#endif
1740
1310 iounmap(hdmi.base_wp); 1741 iounmap(hdmi.base_wp);
1311 1742
1312 return 0; 1743 return 0;
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index 9887ab96da3c..c885f9cb0659 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -22,7 +22,7 @@
22#define _OMAP4_DSS_HDMI_H_ 22#define _OMAP4_DSS_HDMI_H_
23 23
24#include <linux/string.h> 24#include <linux/string.h>
25#include <plat/display.h> 25#include <video/omapdss.h>
26 26
27#define HDMI_WP 0x0 27#define HDMI_WP 0x0
28#define HDMI_CORE_SYS 0x400 28#define HDMI_CORE_SYS 0x400
@@ -48,6 +48,10 @@ struct hdmi_reg { u16 idx; };
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68) 48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68)
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C) 49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C)
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70) 50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70)
51#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80)
52#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84)
53#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88)
54#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
51 55
52/* HDMI IP Core System */ 56/* HDMI IP Core System */
53#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx) 57#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx)
@@ -105,6 +109,8 @@ struct hdmi_reg { u16 idx; };
105#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15) 109#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15)
106#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190) 110#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190)
107#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27) 111#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
112#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210)
113#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10)
108#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290) 114#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290)
109#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27) 115#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27)
110#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300) 116#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300)
@@ -153,6 +159,10 @@ struct hdmi_reg { u16 idx; };
153#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184) 159#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184)
154#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188) 160#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188)
155#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C) 161#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C)
162#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200)
163#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204)
164#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208)
165#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C)
156#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280) 166#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280)
157#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284) 167#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284)
158#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288) 168#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288)
@@ -272,7 +282,7 @@ enum hdmi_core_packet_ctrl {
272 HDMI_PACKETREPEATOFF = 0 282 HDMI_PACKETREPEATOFF = 0
273}; 283};
274 284
275/* INFOFRAME_AVI_ definitions */ 285/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
276enum hdmi_core_infoframe { 286enum hdmi_core_infoframe {
277 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, 287 HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
278 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, 288 HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
@@ -317,7 +327,36 @@ enum hdmi_core_infoframe {
317 HDMI_INFOFRAME_AVI_DB5PR_7 = 6, 327 HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
318 HDMI_INFOFRAME_AVI_DB5PR_8 = 7, 328 HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
319 HDMI_INFOFRAME_AVI_DB5PR_9 = 8, 329 HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
320 HDMI_INFOFRAME_AVI_DB5PR_10 = 9 330 HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
331 HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM = 0,
332 HDMI_INFOFRAME_AUDIO_DB1CT_IEC60958 = 1,
333 HDMI_INFOFRAME_AUDIO_DB1CT_AC3 = 2,
334 HDMI_INFOFRAME_AUDIO_DB1CT_MPEG1 = 3,
335 HDMI_INFOFRAME_AUDIO_DB1CT_MP3 = 4,
336 HDMI_INFOFRAME_AUDIO_DB1CT_MPEG2_MULTICH = 5,
337 HDMI_INFOFRAME_AUDIO_DB1CT_AAC = 6,
338 HDMI_INFOFRAME_AUDIO_DB1CT_DTS = 7,
339 HDMI_INFOFRAME_AUDIO_DB1CT_ATRAC = 8,
340 HDMI_INFOFRAME_AUDIO_DB1CT_ONEBIT = 9,
341 HDMI_INFOFRAME_AUDIO_DB1CT_DOLBY_DIGITAL_PLUS = 10,
342 HDMI_INFOFRAME_AUDIO_DB1CT_DTS_HD = 11,
343 HDMI_INFOFRAME_AUDIO_DB1CT_MAT = 12,
344 HDMI_INFOFRAME_AUDIO_DB1CT_DST = 13,
345 HDMI_INFOFRAME_AUDIO_DB1CT_WMA_PRO = 14,
346 HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM = 0,
347 HDMI_INFOFRAME_AUDIO_DB2SF_32000 = 1,
348 HDMI_INFOFRAME_AUDIO_DB2SF_44100 = 2,
349 HDMI_INFOFRAME_AUDIO_DB2SF_48000 = 3,
350 HDMI_INFOFRAME_AUDIO_DB2SF_88200 = 4,
351 HDMI_INFOFRAME_AUDIO_DB2SF_96000 = 5,
352 HDMI_INFOFRAME_AUDIO_DB2SF_176400 = 6,
353 HDMI_INFOFRAME_AUDIO_DB2SF_192000 = 7,
354 HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM = 0,
355 HDMI_INFOFRAME_AUDIO_DB2SS_16BIT = 1,
356 HDMI_INFOFRAME_AUDIO_DB2SS_20BIT = 2,
357 HDMI_INFOFRAME_AUDIO_DB2SS_24BIT = 3,
358 HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PERMITTED = 0,
359 HDMI_INFOFRAME_AUDIO_DB5_DM_INH_PROHIBITED = 1
321}; 360};
322 361
323enum hdmi_packing_mode { 362enum hdmi_packing_mode {
@@ -327,6 +366,121 @@ enum hdmi_packing_mode {
327 HDMI_PACK_ALREADYPACKED = 7 366 HDMI_PACK_ALREADYPACKED = 7
328}; 367};
329 368
369enum hdmi_core_audio_sample_freq {
370 HDMI_AUDIO_FS_32000 = 0x3,
371 HDMI_AUDIO_FS_44100 = 0x0,
372 HDMI_AUDIO_FS_48000 = 0x2,
373 HDMI_AUDIO_FS_88200 = 0x8,
374 HDMI_AUDIO_FS_96000 = 0xA,
375 HDMI_AUDIO_FS_176400 = 0xC,
376 HDMI_AUDIO_FS_192000 = 0xE,
377 HDMI_AUDIO_FS_NOT_INDICATED = 0x1
378};
379
380enum hdmi_core_audio_layout {
381 HDMI_AUDIO_LAYOUT_2CH = 0,
382 HDMI_AUDIO_LAYOUT_8CH = 1
383};
384
385enum hdmi_core_cts_mode {
386 HDMI_AUDIO_CTS_MODE_HW = 0,
387 HDMI_AUDIO_CTS_MODE_SW = 1
388};
389
390enum hdmi_stereo_channels {
391 HDMI_AUDIO_STEREO_NOCHANNELS = 0,
392 HDMI_AUDIO_STEREO_ONECHANNEL = 1,
393 HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
394 HDMI_AUDIO_STEREO_THREECHANNELS = 3,
395 HDMI_AUDIO_STEREO_FOURCHANNELS = 4
396};
397
398enum hdmi_audio_type {
399 HDMI_AUDIO_TYPE_LPCM = 0,
400 HDMI_AUDIO_TYPE_IEC = 1
401};
402
403enum hdmi_audio_justify {
404 HDMI_AUDIO_JUSTIFY_LEFT = 0,
405 HDMI_AUDIO_JUSTIFY_RIGHT = 1
406};
407
408enum hdmi_audio_sample_order {
409 HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
410 HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
411};
412
413enum hdmi_audio_samples_perword {
414 HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
415 HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
416};
417
418enum hdmi_audio_sample_size {
419 HDMI_AUDIO_SAMPLE_16BITS = 0,
420 HDMI_AUDIO_SAMPLE_24BITS = 1
421};
422
423enum hdmi_audio_transf_mode {
424 HDMI_AUDIO_TRANSF_DMA = 0,
425 HDMI_AUDIO_TRANSF_IRQ = 1
426};
427
428enum hdmi_audio_blk_strt_end_sig {
429 HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
430 HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
431};
432
433enum hdmi_audio_i2s_config {
434 HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT = 0,
435 HDMI_AUDIO_I2S_WS_POLARIT_YLOW_IS_RIGHT = 1,
436 HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0,
437 HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1,
438 HDMI_AUDIO_I2S_MAX_WORD_20BITS = 0,
439 HDMI_AUDIO_I2S_MAX_WORD_24BITS = 1,
440 HDMI_AUDIO_I2S_CHST_WORD_NOT_SPECIFIED = 0,
441 HDMI_AUDIO_I2S_CHST_WORD_16_BITS = 1,
442 HDMI_AUDIO_I2S_CHST_WORD_17_BITS = 6,
443 HDMI_AUDIO_I2S_CHST_WORD_18_BITS = 2,
444 HDMI_AUDIO_I2S_CHST_WORD_19_BITS = 4,
445 HDMI_AUDIO_I2S_CHST_WORD_20_BITS_20MAX = 5,
446 HDMI_AUDIO_I2S_CHST_WORD_20_BITS_24MAX = 1,
447 HDMI_AUDIO_I2S_CHST_WORD_21_BITS = 6,
448 HDMI_AUDIO_I2S_CHST_WORD_22_BITS = 2,
449 HDMI_AUDIO_I2S_CHST_WORD_23_BITS = 4,
450 HDMI_AUDIO_I2S_CHST_WORD_24_BITS = 5,
451 HDMI_AUDIO_I2S_SCK_EDGE_FALLING = 0,
452 HDMI_AUDIO_I2S_SCK_EDGE_RISING = 1,
453 HDMI_AUDIO_I2S_VBIT_FOR_PCM = 0,
454 HDMI_AUDIO_I2S_VBIT_FOR_COMPRESSED = 1,
455 HDMI_AUDIO_I2S_INPUT_LENGTH_NA = 0,
456 HDMI_AUDIO_I2S_INPUT_LENGTH_16 = 2,
457 HDMI_AUDIO_I2S_INPUT_LENGTH_17 = 12,
458 HDMI_AUDIO_I2S_INPUT_LENGTH_18 = 4,
459 HDMI_AUDIO_I2S_INPUT_LENGTH_19 = 8,
460 HDMI_AUDIO_I2S_INPUT_LENGTH_20 = 10,
461 HDMI_AUDIO_I2S_INPUT_LENGTH_21 = 13,
462 HDMI_AUDIO_I2S_INPUT_LENGTH_22 = 5,
463 HDMI_AUDIO_I2S_INPUT_LENGTH_23 = 9,
464 HDMI_AUDIO_I2S_INPUT_LENGTH_24 = 11,
465 HDMI_AUDIO_I2S_FIRST_BIT_SHIFT = 0,
466 HDMI_AUDIO_I2S_FIRST_BIT_NO_SHIFT = 1,
467 HDMI_AUDIO_I2S_SD0_EN = 1,
468 HDMI_AUDIO_I2S_SD1_EN = 1 << 1,
469 HDMI_AUDIO_I2S_SD2_EN = 1 << 2,
470 HDMI_AUDIO_I2S_SD3_EN = 1 << 3,
471};
472
473enum hdmi_audio_mclk_mode {
474 HDMI_AUDIO_MCLK_128FS = 0,
475 HDMI_AUDIO_MCLK_256FS = 1,
476 HDMI_AUDIO_MCLK_384FS = 2,
477 HDMI_AUDIO_MCLK_512FS = 3,
478 HDMI_AUDIO_MCLK_768FS = 4,
479 HDMI_AUDIO_MCLK_1024FS = 5,
480 HDMI_AUDIO_MCLK_1152FS = 6,
481 HDMI_AUDIO_MCLK_192FS = 7
482};
483
330struct hdmi_core_video_config { 484struct hdmi_core_video_config {
331 enum hdmi_core_inputbus_width ip_bus_width; 485 enum hdmi_core_inputbus_width ip_bus_width;
332 enum hdmi_core_dither_trunc op_dither_truc; 486 enum hdmi_core_dither_trunc op_dither_truc;
@@ -376,6 +530,19 @@ struct hdmi_core_infoframe_avi {
376 u16 db12_13_pixel_sofright; 530 u16 db12_13_pixel_sofright;
377 /* Pixel number start of right bar */ 531 /* Pixel number start of right bar */
378}; 532};
533/*
534 * Refer to section 8.2 in HDMI 1.3 specification for
535 * details about infoframe databytes
536 */
537struct hdmi_core_infoframe_audio {
538 u8 db1_coding_type;
539 u8 db1_channel_count;
540 u8 db2_sample_freq;
541 u8 db2_sample_size;
542 u8 db4_channel_alloc;
543 bool db5_downmix_inh;
544 u8 db5_lsv; /* Level shift values for downmix */
545};
379 546
380struct hdmi_core_packet_enable_repeat { 547struct hdmi_core_packet_enable_repeat {
381 u32 audio_pkt; 548 u32 audio_pkt;
@@ -412,4 +579,53 @@ struct hdmi_config {
412 struct hdmi_cm cm; 579 struct hdmi_cm cm;
413}; 580};
414 581
582struct hdmi_audio_format {
583 enum hdmi_stereo_channels stereo_channels;
584 u8 active_chnnls_msk;
585 enum hdmi_audio_type type;
586 enum hdmi_audio_justify justification;
587 enum hdmi_audio_sample_order sample_order;
588 enum hdmi_audio_samples_perword samples_per_word;
589 enum hdmi_audio_sample_size sample_size;
590 enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
591};
592
593struct hdmi_audio_dma {
594 u8 transfer_size;
595 u8 block_size;
596 enum hdmi_audio_transf_mode mode;
597 u16 fifo_threshold;
598};
599
600struct hdmi_core_audio_i2s_config {
601 u8 word_max_length;
602 u8 word_length;
603 u8 in_length_bits;
604 u8 justification;
605 u8 en_high_bitrate_aud;
606 u8 sck_edge_mode;
607 u8 cbit_order;
608 u8 vbit;
609 u8 ws_polarity;
610 u8 direction;
611 u8 shift;
612 u8 active_sds;
613};
614
615struct hdmi_core_audio_config {
616 struct hdmi_core_audio_i2s_config i2s_cfg;
617 enum hdmi_core_audio_sample_freq freq_sample;
618 bool fs_override;
619 u32 n;
620 u32 cts;
621 u32 aud_par_busclk;
622 enum hdmi_core_audio_layout layout;
623 enum hdmi_core_cts_mode cts_mode;
624 bool use_mclk;
625 enum hdmi_audio_mclk_mode mclk_mode;
626 bool en_acr_pkt;
627 bool en_dsd_audio;
628 bool en_parallel_aud_input;
629 bool en_spdif;
630};
415#endif 631#endif
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
index ffb5de94131f..7d4f2bd7c506 100644
--- a/drivers/video/omap2/dss/hdmi_omap4_panel.c
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -24,7 +24,7 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <plat/display.h> 27#include <video/omapdss.h>
28 28
29#include "dss.h" 29#include "dss.h"
30 30
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index bcd37ec86952..9aeea50e33ff 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -29,7 +29,7 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/jiffies.h> 30#include <linux/jiffies.h>
31 31
32#include <plat/display.h> 32#include <video/omapdss.h>
33#include <plat/cpu.h> 33#include <plat/cpu.h>
34 34
35#include "dss.h" 35#include "dss.h"
@@ -393,6 +393,7 @@ struct overlay_cache_data {
393 393
394 u32 paddr; 394 u32 paddr;
395 void __iomem *vaddr; 395 void __iomem *vaddr;
396 u32 p_uv_addr; /* relevant for NV12 format only */
396 u16 screen_width; 397 u16 screen_width;
397 u16 width; 398 u16 width;
398 u16 height; 399 u16 height;
@@ -775,10 +776,17 @@ static int configure_overlay(enum omap_plane plane)
775 } 776 }
776 777
777 switch (c->color_mode) { 778 switch (c->color_mode) {
779 case OMAP_DSS_COLOR_NV12:
780 bpp = 8;
781 break;
778 case OMAP_DSS_COLOR_RGB16: 782 case OMAP_DSS_COLOR_RGB16:
779 case OMAP_DSS_COLOR_ARGB16: 783 case OMAP_DSS_COLOR_ARGB16:
780 case OMAP_DSS_COLOR_YUV2: 784 case OMAP_DSS_COLOR_YUV2:
781 case OMAP_DSS_COLOR_UYVY: 785 case OMAP_DSS_COLOR_UYVY:
786 case OMAP_DSS_COLOR_RGBA16:
787 case OMAP_DSS_COLOR_RGBX16:
788 case OMAP_DSS_COLOR_ARGB16_1555:
789 case OMAP_DSS_COLOR_XRGB16_1555:
782 bpp = 16; 790 bpp = 16;
783 break; 791 break;
784 792
@@ -854,7 +862,8 @@ static int configure_overlay(enum omap_plane plane)
854 c->mirror, 862 c->mirror,
855 c->global_alpha, 863 c->global_alpha,
856 c->pre_mult_alpha, 864 c->pre_mult_alpha,
857 c->channel); 865 c->channel,
866 c->p_uv_addr);
858 867
859 if (r) { 868 if (r) {
860 /* this shouldn't happen */ 869 /* this shouldn't happen */
@@ -1269,6 +1278,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1269 1278
1270 oc->paddr = ovl->info.paddr; 1279 oc->paddr = ovl->info.paddr;
1271 oc->vaddr = ovl->info.vaddr; 1280 oc->vaddr = ovl->info.vaddr;
1281 oc->p_uv_addr = ovl->info.p_uv_addr;
1272 oc->screen_width = ovl->info.screen_width; 1282 oc->screen_width = ovl->info.screen_width;
1273 oc->width = ovl->info.width; 1283 oc->width = ovl->info.width;
1274 oc->height = ovl->info.height; 1284 oc->height = ovl->info.height;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index f1aca6d04011..0f08025b1f0e 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -31,7 +31,7 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <plat/display.h> 34#include <video/omapdss.h>
35#include <plat/cpu.h> 35#include <plat/cpu.h>
36 36
37#include "dss.h" 37#include "dss.h"
@@ -201,12 +201,16 @@ static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
201static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, 201static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
202 size_t size) 202 size_t size)
203{ 203{
204 int r; 204 int r, enable;
205 struct omap_overlay_info info; 205 struct omap_overlay_info info;
206 206
207 ovl->get_overlay_info(ovl, &info); 207 ovl->get_overlay_info(ovl, &info);
208 208
209 info.enabled = simple_strtoul(buf, NULL, 10); 209 r = kstrtoint(buf, 0, &enable);
210 if (r)
211 return r;
212
213 info.enabled = !!enable;
210 214
211 r = ovl->set_overlay_info(ovl, &info); 215 r = ovl->set_overlay_info(ovl, &info);
212 if (r) 216 if (r)
@@ -231,8 +235,13 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
231 const char *buf, size_t size) 235 const char *buf, size_t size)
232{ 236{
233 int r; 237 int r;
238 u8 alpha;
234 struct omap_overlay_info info; 239 struct omap_overlay_info info;
235 240
241 r = kstrtou8(buf, 0, &alpha);
242 if (r)
243 return r;
244
236 ovl->get_overlay_info(ovl, &info); 245 ovl->get_overlay_info(ovl, &info);
237 246
238 /* Video1 plane does not support global alpha 247 /* Video1 plane does not support global alpha
@@ -242,7 +251,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
242 ovl->id == OMAP_DSS_VIDEO1) 251 ovl->id == OMAP_DSS_VIDEO1)
243 info.global_alpha = 255; 252 info.global_alpha = 255;
244 else 253 else
245 info.global_alpha = simple_strtoul(buf, NULL, 10); 254 info.global_alpha = alpha;
246 255
247 r = ovl->set_overlay_info(ovl, &info); 256 r = ovl->set_overlay_info(ovl, &info);
248 if (r) 257 if (r)
@@ -268,8 +277,13 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
268 const char *buf, size_t size) 277 const char *buf, size_t size)
269{ 278{
270 int r; 279 int r;
280 u8 alpha;
271 struct omap_overlay_info info; 281 struct omap_overlay_info info;
272 282
283 r = kstrtou8(buf, 0, &alpha);
284 if (r)
285 return r;
286
273 ovl->get_overlay_info(ovl, &info); 287 ovl->get_overlay_info(ovl, &info);
274 288
275 /* only GFX and Video2 plane support pre alpha multiplied 289 /* only GFX and Video2 plane support pre alpha multiplied
@@ -279,7 +293,7 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
279 ovl->id == OMAP_DSS_VIDEO1) 293 ovl->id == OMAP_DSS_VIDEO1)
280 info.pre_mult_alpha = 0; 294 info.pre_mult_alpha = 0;
281 else 295 else
282 info.pre_mult_alpha = simple_strtoul(buf, NULL, 10); 296 info.pre_mult_alpha = alpha;
283 297
284 r = ovl->set_overlay_info(ovl, &info); 298 r = ovl->set_overlay_info(ovl, &info);
285 if (r) 299 if (r)
@@ -491,13 +505,18 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
491 ovl->manager = mgr; 505 ovl->manager = mgr;
492 506
493 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); 507 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
494 /* XXX: on manual update display, in auto update mode, a bug happens 508 /* XXX: When there is an overlay on a DSI manual update display, and
495 * here. When an overlay is first enabled on LCD, then it's disabled, 509 * the overlay is first disabled, then moved to tv, and enabled, we
496 * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT 510 * seem to get SYNC_LOST_DIGIT error.
497 * errors. Waiting before changing the channel_out fixes it. I'm 511 *
498 * guessing that the overlay is still somehow being used for the LCD, 512 * Waiting doesn't seem to help, but updating the manual update display
499 * but I don't understand how or why. */ 513 * after disabling the overlay seems to fix this. This hints that the
500 msleep(40); 514 * overlay is perhaps somehow tied to the LCD output until the output
515 * is updated.
516 *
517 * Userspace workaround for this is to update the LCD after disabling
518 * the overlay, but before moving the overlay to TV.
519 */
501 dispc_set_channel_out(ovl->id, mgr->id); 520 dispc_set_channel_out(ovl->id, mgr->id);
502 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 521 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
503 522
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5ea17f49c611..c06fbe0bc678 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -32,8 +32,9 @@
32#include <linux/ktime.h> 32#include <linux/ktime.h>
33#include <linux/hrtimer.h> 33#include <linux/hrtimer.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/semaphore.h>
35 36
36#include <plat/display.h> 37#include <video/omapdss.h>
37#include "dss.h" 38#include "dss.h"
38 39
39struct rfbi_reg { u16 idx; }; 40struct rfbi_reg { u16 idx; };
@@ -65,9 +66,6 @@ struct rfbi_reg { u16 idx; };
65#define REG_FLD_MOD(idx, val, start, end) \ 66#define REG_FLD_MOD(idx, val, start, end) \
66 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) 67 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
67 68
68/* To work around an RFBI transfer rate limitation */
69#define OMAP_RFBI_RATE_LIMIT 1
70
71enum omap_rfbi_cycleformat { 69enum omap_rfbi_cycleformat {
72 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0, 70 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
73 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1, 71 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
@@ -89,11 +87,6 @@ enum omap_rfbi_parallelmode {
89 OMAP_DSS_RFBI_PARALLELMODE_16 = 3, 87 OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
90}; 88};
91 89
92enum update_cmd {
93 RFBI_CMD_UPDATE = 0,
94 RFBI_CMD_SYNC = 1,
95};
96
97static int rfbi_convert_timings(struct rfbi_timings *t); 90static int rfbi_convert_timings(struct rfbi_timings *t);
98static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); 91static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
99 92
@@ -114,20 +107,9 @@ static struct {
114 107
115 struct omap_dss_device *dssdev[2]; 108 struct omap_dss_device *dssdev[2];
116 109
117 struct kfifo cmd_fifo; 110 struct semaphore bus_lock;
118 spinlock_t cmd_lock;
119 struct completion cmd_done;
120 atomic_t cmd_fifo_full;
121 atomic_t cmd_pending;
122} rfbi; 111} rfbi;
123 112
124struct update_region {
125 u16 x;
126 u16 y;
127 u16 w;
128 u16 h;
129};
130
131static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) 113static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
132{ 114{
133 __raw_writel(val, rfbi.base + idx.idx); 115 __raw_writel(val, rfbi.base + idx.idx);
@@ -146,9 +128,20 @@ static void rfbi_enable_clocks(bool enable)
146 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); 128 dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
147} 129}
148 130
131void rfbi_bus_lock(void)
132{
133 down(&rfbi.bus_lock);
134}
135EXPORT_SYMBOL(rfbi_bus_lock);
136
137void rfbi_bus_unlock(void)
138{
139 up(&rfbi.bus_lock);
140}
141EXPORT_SYMBOL(rfbi_bus_unlock);
142
149void omap_rfbi_write_command(const void *buf, u32 len) 143void omap_rfbi_write_command(const void *buf, u32 len)
150{ 144{
151 rfbi_enable_clocks(1);
152 switch (rfbi.parallelmode) { 145 switch (rfbi.parallelmode) {
153 case OMAP_DSS_RFBI_PARALLELMODE_8: 146 case OMAP_DSS_RFBI_PARALLELMODE_8:
154 { 147 {
@@ -172,13 +165,11 @@ void omap_rfbi_write_command(const void *buf, u32 len)
172 default: 165 default:
173 BUG(); 166 BUG();
174 } 167 }
175 rfbi_enable_clocks(0);
176} 168}
177EXPORT_SYMBOL(omap_rfbi_write_command); 169EXPORT_SYMBOL(omap_rfbi_write_command);
178 170
179void omap_rfbi_read_data(void *buf, u32 len) 171void omap_rfbi_read_data(void *buf, u32 len)
180{ 172{
181 rfbi_enable_clocks(1);
182 switch (rfbi.parallelmode) { 173 switch (rfbi.parallelmode) {
183 case OMAP_DSS_RFBI_PARALLELMODE_8: 174 case OMAP_DSS_RFBI_PARALLELMODE_8:
184 { 175 {
@@ -206,13 +197,11 @@ void omap_rfbi_read_data(void *buf, u32 len)
206 default: 197 default:
207 BUG(); 198 BUG();
208 } 199 }
209 rfbi_enable_clocks(0);
210} 200}
211EXPORT_SYMBOL(omap_rfbi_read_data); 201EXPORT_SYMBOL(omap_rfbi_read_data);
212 202
213void omap_rfbi_write_data(const void *buf, u32 len) 203void omap_rfbi_write_data(const void *buf, u32 len)
214{ 204{
215 rfbi_enable_clocks(1);
216 switch (rfbi.parallelmode) { 205 switch (rfbi.parallelmode) {
217 case OMAP_DSS_RFBI_PARALLELMODE_8: 206 case OMAP_DSS_RFBI_PARALLELMODE_8:
218 { 207 {
@@ -237,7 +226,6 @@ void omap_rfbi_write_data(const void *buf, u32 len)
237 BUG(); 226 BUG();
238 227
239 } 228 }
240 rfbi_enable_clocks(0);
241} 229}
242EXPORT_SYMBOL(omap_rfbi_write_data); 230EXPORT_SYMBOL(omap_rfbi_write_data);
243 231
@@ -249,8 +237,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
249 int horiz_offset = scr_width - w; 237 int horiz_offset = scr_width - w;
250 int i; 238 int i;
251 239
252 rfbi_enable_clocks(1);
253
254 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && 240 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
255 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { 241 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
256 const u16 __iomem *pd = buf; 242 const u16 __iomem *pd = buf;
@@ -295,12 +281,10 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
295 } else { 281 } else {
296 BUG(); 282 BUG();
297 } 283 }
298
299 rfbi_enable_clocks(0);
300} 284}
301EXPORT_SYMBOL(omap_rfbi_write_pixels); 285EXPORT_SYMBOL(omap_rfbi_write_pixels);
302 286
303void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, 287static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
304 u16 height, void (*callback)(void *data), void *data) 288 u16 height, void (*callback)(void *data), void *data)
305{ 289{
306 u32 l; 290 u32 l;
@@ -317,8 +301,6 @@ void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
317 rfbi.framedone_callback = callback; 301 rfbi.framedone_callback = callback;
318 rfbi.framedone_callback_data = data; 302 rfbi.framedone_callback_data = data;
319 303
320 rfbi_enable_clocks(1);
321
322 rfbi_write_reg(RFBI_PIXEL_CNT, width * height); 304 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
323 305
324 l = rfbi_read_reg(RFBI_CONTROL); 306 l = rfbi_read_reg(RFBI_CONTROL);
@@ -337,15 +319,11 @@ static void framedone_callback(void *data, u32 mask)
337 319
338 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); 320 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
339 321
340 rfbi_enable_clocks(0);
341
342 callback = rfbi.framedone_callback; 322 callback = rfbi.framedone_callback;
343 rfbi.framedone_callback = NULL; 323 rfbi.framedone_callback = NULL;
344 324
345 if (callback != NULL) 325 if (callback != NULL)
346 callback(rfbi.framedone_callback_data); 326 callback(rfbi.framedone_callback_data);
347
348 atomic_set(&rfbi.cmd_pending, 0);
349} 327}
350 328
351#if 1 /* VERBOSE */ 329#if 1 /* VERBOSE */
@@ -435,7 +413,7 @@ static int calc_extif_timings(struct rfbi_timings *t)
435} 413}
436 414
437 415
438void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t) 416static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
439{ 417{
440 int r; 418 int r;
441 419
@@ -447,7 +425,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
447 425
448 BUG_ON(!t->converted); 426 BUG_ON(!t->converted);
449 427
450 rfbi_enable_clocks(1);
451 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]); 428 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
452 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]); 429 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
453 430
@@ -456,7 +433,6 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
456 (t->tim[2] ? 1 : 0), 4, 4); 433 (t->tim[2] ? 1 : 0), 4, 4);
457 434
458 rfbi_print_timings(); 435 rfbi_print_timings();
459 rfbi_enable_clocks(0);
460} 436}
461 437
462static int ps_to_rfbi_ticks(int time, int div) 438static int ps_to_rfbi_ticks(int time, int div)
@@ -472,59 +448,6 @@ static int ps_to_rfbi_ticks(int time, int div)
472 return ret; 448 return ret;
473} 449}
474 450
475#ifdef OMAP_RFBI_RATE_LIMIT
476unsigned long rfbi_get_max_tx_rate(void)
477{
478 unsigned long l4_rate, dss1_rate;
479 int min_l4_ticks = 0;
480 int i;
481
482 /* According to TI this can't be calculated so make the
483 * adjustments for a couple of known frequencies and warn for
484 * others.
485 */
486 static const struct {
487 unsigned long l4_clk; /* HZ */
488 unsigned long dss1_clk; /* HZ */
489 unsigned long min_l4_ticks;
490 } ftab[] = {
491 { 55, 132, 7, }, /* 7.86 MPix/s */
492 { 110, 110, 12, }, /* 9.16 MPix/s */
493 { 110, 132, 10, }, /* 11 Mpix/s */
494 { 120, 120, 10, }, /* 12 Mpix/s */
495 { 133, 133, 10, }, /* 13.3 Mpix/s */
496 };
497
498 l4_rate = rfbi.l4_khz / 1000;
499 dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
500
501 for (i = 0; i < ARRAY_SIZE(ftab); i++) {
502 /* Use a window instead of an exact match, to account
503 * for different DPLL multiplier / divider pairs.
504 */
505 if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
506 abs(ftab[i].dss1_clk - dss1_rate) < 3) {
507 min_l4_ticks = ftab[i].min_l4_ticks;
508 break;
509 }
510 }
511 if (i == ARRAY_SIZE(ftab)) {
512 /* Can't be sure, return anyway the maximum not
513 * rate-limited. This might cause a problem only for the
514 * tearing synchronisation.
515 */
516 DSSERR("can't determine maximum RFBI transfer rate\n");
517 return rfbi.l4_khz * 1000;
518 }
519 return rfbi.l4_khz * 1000 / min_l4_ticks;
520}
521#else
522int rfbi_get_max_tx_rate(void)
523{
524 return rfbi.l4_khz * 1000;
525}
526#endif
527
528static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) 451static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
529{ 452{
530 *clk_period = 1000000000 / rfbi.l4_khz; 453 *clk_period = 1000000000 / rfbi.l4_khz;
@@ -644,7 +567,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
644 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n", 567 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
645 mode, hs, vs, hs_pol_inv, vs_pol_inv); 568 mode, hs, vs, hs_pol_inv, vs_pol_inv);
646 569
647 rfbi_enable_clocks(1);
648 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); 570 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
649 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); 571 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
650 572
@@ -657,7 +579,6 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
657 l &= ~(1 << 20); 579 l &= ~(1 << 20);
658 else 580 else
659 l |= 1 << 20; 581 l |= 1 << 20;
660 rfbi_enable_clocks(0);
661 582
662 return 0; 583 return 0;
663} 584}
@@ -672,7 +593,6 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
672 if (line > (1 << 11) - 1) 593 if (line > (1 << 11) - 1)
673 return -EINVAL; 594 return -EINVAL;
674 595
675 rfbi_enable_clocks(1);
676 l = rfbi_read_reg(RFBI_CONFIG(0)); 596 l = rfbi_read_reg(RFBI_CONFIG(0));
677 l &= ~(0x3 << 2); 597 l &= ~(0x3 << 2);
678 if (enable) { 598 if (enable) {
@@ -682,50 +602,12 @@ int omap_rfbi_enable_te(bool enable, unsigned line)
682 rfbi.te_enabled = 0; 602 rfbi.te_enabled = 0;
683 rfbi_write_reg(RFBI_CONFIG(0), l); 603 rfbi_write_reg(RFBI_CONFIG(0), l);
684 rfbi_write_reg(RFBI_LINE_NUMBER, line); 604 rfbi_write_reg(RFBI_LINE_NUMBER, line);
685 rfbi_enable_clocks(0);
686 605
687 return 0; 606 return 0;
688} 607}
689EXPORT_SYMBOL(omap_rfbi_enable_te); 608EXPORT_SYMBOL(omap_rfbi_enable_te);
690 609
691#if 0 610static int rfbi_configure(int rfbi_module, int bpp, int lines)
692static void rfbi_enable_config(int enable1, int enable2)
693{
694 u32 l;
695 int cs = 0;
696
697 if (enable1)
698 cs |= 1<<0;
699 if (enable2)
700 cs |= 1<<1;
701
702 rfbi_enable_clocks(1);
703
704 l = rfbi_read_reg(RFBI_CONTROL);
705
706 l = FLD_MOD(l, cs, 3, 2);
707 l = FLD_MOD(l, 0, 1, 1);
708
709 rfbi_write_reg(RFBI_CONTROL, l);
710
711
712 l = rfbi_read_reg(RFBI_CONFIG(0));
713 l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
714 /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
715 /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
716
717 l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
718 l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
719 l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
720
721 l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
722 rfbi_write_reg(RFBI_CONFIG(0), l);
723
724 rfbi_enable_clocks(0);
725}
726#endif
727
728int rfbi_configure(int rfbi_module, int bpp, int lines)
729{ 611{
730 u32 l; 612 u32 l;
731 int cycle1 = 0, cycle2 = 0, cycle3 = 0; 613 int cycle1 = 0, cycle2 = 0, cycle3 = 0;
@@ -821,8 +703,6 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
821 break; 703 break;
822 } 704 }
823 705
824 rfbi_enable_clocks(1);
825
826 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */ 706 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
827 707
828 l = 0; 708 l = 0;
@@ -856,11 +736,15 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
856 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n", 736 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
857 bpp, lines, cycle1, cycle2, cycle3); 737 bpp, lines, cycle1, cycle2, cycle3);
858 738
859 rfbi_enable_clocks(0);
860
861 return 0; 739 return 0;
862} 740}
863EXPORT_SYMBOL(rfbi_configure); 741
742int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
743 int data_lines)
744{
745 return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
746}
747EXPORT_SYMBOL(omap_rfbi_configure);
864 748
865int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, 749int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
866 u16 *x, u16 *y, u16 *w, u16 *h) 750 u16 *x, u16 *y, u16 *w, u16 *h)
@@ -960,6 +844,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
960{ 844{
961 int r; 845 int r;
962 846
847 rfbi_enable_clocks(1);
848
963 r = omap_dss_start_device(dssdev); 849 r = omap_dss_start_device(dssdev);
964 if (r) { 850 if (r) {
965 DSSERR("failed to start device\n"); 851 DSSERR("failed to start device\n");
@@ -1002,6 +888,8 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
1002 omap_dispc_unregister_isr(framedone_callback, NULL, 888 omap_dispc_unregister_isr(framedone_callback, NULL,
1003 DISPC_IRQ_FRAMEDONE); 889 DISPC_IRQ_FRAMEDONE);
1004 omap_dss_stop_device(dssdev); 890 omap_dss_stop_device(dssdev);
891
892 rfbi_enable_clocks(0);
1005} 893}
1006EXPORT_SYMBOL(omapdss_rfbi_display_disable); 894EXPORT_SYMBOL(omapdss_rfbi_display_disable);
1007 895
@@ -1021,11 +909,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
1021 909
1022 rfbi.pdev = pdev; 910 rfbi.pdev = pdev;
1023 911
1024 spin_lock_init(&rfbi.cmd_lock); 912 sema_init(&rfbi.bus_lock, 1);
1025
1026 init_completion(&rfbi.cmd_done);
1027 atomic_set(&rfbi.cmd_fifo_full, 0);
1028 atomic_set(&rfbi.cmd_pending, 0);
1029 913
1030 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); 914 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
1031 if (!rfbi_mem) { 915 if (!rfbi_mem) {
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 54a53e648180..0bd4b0350f80 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -25,7 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/regulator/consumer.h> 26#include <linux/regulator/consumer.h>
27 27
28#include <plat/display.h> 28#include <video/omapdss.h>
29#include <plat/cpu.h> 29#include <plat/cpu.h>
30#include "dss.h" 30#include "dss.h"
31 31
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 8e35a5bae429..980f919ed987 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -34,7 +34,7 @@
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/regulator/consumer.h> 35#include <linux/regulator/consumer.h>
36 36
37#include <plat/display.h> 37#include <video/omapdss.h>
38#include <plat/cpu.h> 38#include <plat/cpu.h>
39 39
40#include "dss.h" 40#include "dss.h"
@@ -373,8 +373,11 @@ static void venc_reset(void)
373 } 373 }
374 } 374 }
375 375
376#ifdef CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET
376 /* the magical sleep that makes things work */ 377 /* the magical sleep that makes things work */
378 /* XXX more info? What bug this circumvents? */
377 msleep(20); 379 msleep(20);
380#endif
378} 381}
379 382
380static void venc_enable_clocks(int enable) 383static void venc_enable_clocks(int enable)
@@ -473,6 +476,12 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
473 476
474 mutex_lock(&venc.venc_lock); 477 mutex_lock(&venc.venc_lock);
475 478
479 r = omap_dss_start_device(dssdev);
480 if (r) {
481 DSSERR("failed to start device\n");
482 goto err0;
483 }
484
476 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { 485 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
477 r = -EINVAL; 486 r = -EINVAL;
478 goto err1; 487 goto err1;
@@ -484,10 +493,11 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
484 493
485 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 494 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
486 495
487 /* wait couple of vsyncs until enabling the LCD */ 496 mutex_unlock(&venc.venc_lock);
488 msleep(50); 497 return 0;
489
490err1: 498err1:
499 omap_dss_stop_device(dssdev);
500err0:
491 mutex_unlock(&venc.venc_lock); 501 mutex_unlock(&venc.venc_lock);
492 502
493 return r; 503 return r;
@@ -510,10 +520,9 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
510 520
511 venc_power_off(dssdev); 521 venc_power_off(dssdev);
512 522
513 /* wait at least 5 vsyncs after disabling the LCD */
514 msleep(100);
515
516 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 523 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
524
525 omap_dss_stop_device(dssdev);
517end: 526end:
518 mutex_unlock(&venc.venc_lock); 527 mutex_unlock(&venc.venc_lock);
519} 528}
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 6f435450987e..cff450392b79 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -28,7 +28,7 @@
28#include <linux/omapfb.h> 28#include <linux/omapfb.h>
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30 30
31#include <plat/display.h> 31#include <video/omapdss.h>
32#include <plat/vrfb.h> 32#include <plat/vrfb.h>
33#include <plat/vram.h> 33#include <plat/vram.h>
34 34
@@ -895,8 +895,16 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
895 895
896 p.display_info.xres = xres; 896 p.display_info.xres = xres;
897 p.display_info.yres = yres; 897 p.display_info.yres = yres;
898 p.display_info.width = 0; 898
899 p.display_info.height = 0; 899 if (display->driver->get_dimensions) {
900 u32 w, h;
901 display->driver->get_dimensions(display, &w, &h);
902 p.display_info.width = w;
903 p.display_info.height = h;
904 } else {
905 p.display_info.width = 0;
906 p.display_info.height = 0;
907 }
900 908
901 if (copy_to_user((void __user *)arg, &p.display_info, 909 if (copy_to_user((void __user *)arg, &p.display_info,
902 sizeof(p.display_info))) 910 sizeof(p.display_info)))
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 505ec6672049..505bc12a3031 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -30,7 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/omapfb.h> 31#include <linux/omapfb.h>
32 32
33#include <plat/display.h> 33#include <video/omapdss.h>
34#include <plat/vram.h> 34#include <plat/vram.h>
35#include <plat/vrfb.h> 35#include <plat/vrfb.h>
36 36
@@ -702,8 +702,16 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
702 var->xres, var->yres, 702 var->xres, var->yres,
703 var->xres_virtual, var->yres_virtual); 703 var->xres_virtual, var->yres_virtual);
704 704
705 var->height = -1; 705 if (display && display->driver->get_dimensions) {
706 var->width = -1; 706 u32 w, h;
707 display->driver->get_dimensions(display, &w, &h);
708 var->width = DIV_ROUND_CLOSEST(w, 1000);
709 var->height = DIV_ROUND_CLOSEST(h, 1000);
710 } else {
711 var->height = -1;
712 var->width = -1;
713 }
714
707 var->grayscale = 0; 715 var->grayscale = 0;
708 716
709 if (display && display->driver->get_timings) { 717 if (display && display->driver->get_timings) {
@@ -749,35 +757,6 @@ static int omapfb_open(struct fb_info *fbi, int user)
749 757
750static int omapfb_release(struct fb_info *fbi, int user) 758static int omapfb_release(struct fb_info *fbi, int user)
751{ 759{
752#if 0
753 struct omapfb_info *ofbi = FB2OFB(fbi);
754 struct omapfb2_device *fbdev = ofbi->fbdev;
755 struct omap_dss_device *display = fb2display(fbi);
756
757 DBG("Closing fb with plane index %d\n", ofbi->id);
758
759 omapfb_lock(fbdev);
760
761 if (display && display->get_update_mode && display->update) {
762 /* XXX this update should be removed, I think. But it's
763 * good for debugging */
764 if (display->get_update_mode(display) ==
765 OMAP_DSS_UPDATE_MANUAL) {
766 u16 w, h;
767
768 if (display->sync)
769 display->sync(display);
770
771 display->get_resolution(display, &w, &h);
772 display->update(display, 0, 0, w, h);
773 }
774 }
775
776 if (display && display->sync)
777 display->sync(display);
778
779 omapfb_unlock(fbdev);
780#endif
781 return 0; 760 return 0;
782} 761}
783 762
@@ -1263,7 +1242,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1263 struct omapfb_info *ofbi = FB2OFB(fbi); 1242 struct omapfb_info *ofbi = FB2OFB(fbi);
1264 struct omapfb2_device *fbdev = ofbi->fbdev; 1243 struct omapfb2_device *fbdev = ofbi->fbdev;
1265 struct omap_dss_device *display = fb2display(fbi); 1244 struct omap_dss_device *display = fb2display(fbi);
1266 int do_update = 0;
1267 int r = 0; 1245 int r = 0;
1268 1246
1269 if (!display) 1247 if (!display)
@@ -1279,11 +1257,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1279 if (display->driver->resume) 1257 if (display->driver->resume)
1280 r = display->driver->resume(display); 1258 r = display->driver->resume(display);
1281 1259
1282 if (r == 0 && display->driver->get_update_mode &&
1283 display->driver->get_update_mode(display) ==
1284 OMAP_DSS_UPDATE_MANUAL)
1285 do_update = 1;
1286
1287 break; 1260 break;
1288 1261
1289 case FB_BLANK_NORMAL: 1262 case FB_BLANK_NORMAL:
@@ -1307,13 +1280,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
1307exit: 1280exit:
1308 omapfb_unlock(fbdev); 1281 omapfb_unlock(fbdev);
1309 1282
1310 if (r == 0 && do_update && display->driver->update) {
1311 u16 w, h;
1312 display->driver->get_resolution(display, &w, &h);
1313
1314 r = display->driver->update(display, 0, 0, w, h);
1315 }
1316
1317 return r; 1283 return r;
1318} 1284}
1319 1285
@@ -2030,9 +1996,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
2030static int omapfb_mode_to_timings(const char *mode_str, 1996static int omapfb_mode_to_timings(const char *mode_str,
2031 struct omap_video_timings *timings, u8 *bpp) 1997 struct omap_video_timings *timings, u8 *bpp)
2032{ 1998{
2033 struct fb_info fbi; 1999 struct fb_info *fbi;
2034 struct fb_var_screeninfo var; 2000 struct fb_var_screeninfo *var;
2035 struct fb_ops fbops; 2001 struct fb_ops *fbops;
2036 int r; 2002 int r;
2037 2003
2038#ifdef CONFIG_OMAP2_DSS_VENC 2004#ifdef CONFIG_OMAP2_DSS_VENC
@@ -2050,39 +2016,66 @@ static int omapfb_mode_to_timings(const char *mode_str,
2050 /* this is quite a hack, but I wanted to use the modedb and for 2016 /* this is quite a hack, but I wanted to use the modedb and for
2051 * that we need fb_info and var, so we create dummy ones */ 2017 * that we need fb_info and var, so we create dummy ones */
2052 2018
2053 memset(&fbi, 0, sizeof(fbi)); 2019 *bpp = 0;
2054 memset(&var, 0, sizeof(var)); 2020 fbi = NULL;
2055 memset(&fbops, 0, sizeof(fbops)); 2021 var = NULL;
2056 fbi.fbops = &fbops; 2022 fbops = NULL;
2057
2058 r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24);
2059
2060 if (r != 0) {
2061 timings->pixel_clock = PICOS2KHZ(var.pixclock);
2062 timings->hbp = var.left_margin;
2063 timings->hfp = var.right_margin;
2064 timings->vbp = var.upper_margin;
2065 timings->vfp = var.lower_margin;
2066 timings->hsw = var.hsync_len;
2067 timings->vsw = var.vsync_len;
2068 timings->x_res = var.xres;
2069 timings->y_res = var.yres;
2070
2071 switch (var.bits_per_pixel) {
2072 case 16:
2073 *bpp = 16;
2074 break;
2075 case 24:
2076 case 32:
2077 default:
2078 *bpp = 24;
2079 break;
2080 }
2081 2023
2082 return 0; 2024 fbi = kzalloc(sizeof(*fbi), GFP_KERNEL);
2083 } else { 2025 if (fbi == NULL) {
2084 return -EINVAL; 2026 r = -ENOMEM;
2027 goto err;
2028 }
2029
2030 var = kzalloc(sizeof(*var), GFP_KERNEL);
2031 if (var == NULL) {
2032 r = -ENOMEM;
2033 goto err;
2034 }
2035
2036 fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
2037 if (fbops == NULL) {
2038 r = -ENOMEM;
2039 goto err;
2040 }
2041
2042 fbi->fbops = fbops;
2043
2044 r = fb_find_mode(var, fbi, mode_str, NULL, 0, NULL, 24);
2045 if (r == 0) {
2046 r = -EINVAL;
2047 goto err;
2048 }
2049
2050 timings->pixel_clock = PICOS2KHZ(var->pixclock);
2051 timings->hbp = var->left_margin;
2052 timings->hfp = var->right_margin;
2053 timings->vbp = var->upper_margin;
2054 timings->vfp = var->lower_margin;
2055 timings->hsw = var->hsync_len;
2056 timings->vsw = var->vsync_len;
2057 timings->x_res = var->xres;
2058 timings->y_res = var->yres;
2059
2060 switch (var->bits_per_pixel) {
2061 case 16:
2062 *bpp = 16;
2063 break;
2064 case 24:
2065 case 32:
2066 default:
2067 *bpp = 24;
2068 break;
2085 } 2069 }
2070
2071 r = 0;
2072
2073err:
2074 kfree(fbi);
2075 kfree(var);
2076 kfree(fbops);
2077
2078 return r;
2086} 2079}
2087 2080
2088static int omapfb_set_def_mode(struct omapfb2_device *fbdev, 2081static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
@@ -2185,6 +2178,61 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2185 return r; 2178 return r;
2186} 2179}
2187 2180
2181static int omapfb_init_display(struct omapfb2_device *fbdev,
2182 struct omap_dss_device *dssdev)
2183{
2184 struct omap_dss_driver *dssdrv = dssdev->driver;
2185 int r;
2186
2187 r = dssdrv->enable(dssdev);
2188 if (r) {
2189 dev_warn(fbdev->dev, "Failed to enable display '%s'\n",
2190 dssdev->name);
2191 return r;
2192 }
2193
2194 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2195 u16 w, h;
2196 if (dssdrv->enable_te) {
2197 r = dssdrv->enable_te(dssdev, 1);
2198 if (r) {
2199 dev_err(fbdev->dev, "Failed to set TE\n");
2200 return r;
2201 }
2202 }
2203
2204 if (dssdrv->set_update_mode) {
2205 r = dssdrv->set_update_mode(dssdev,
2206 OMAP_DSS_UPDATE_MANUAL);
2207 if (r) {
2208 dev_err(fbdev->dev,
2209 "Failed to set update mode\n");
2210 return r;
2211 }
2212 }
2213
2214 dssdrv->get_resolution(dssdev, &w, &h);
2215 r = dssdrv->update(dssdev, 0, 0, w, h);
2216 if (r) {
2217 dev_err(fbdev->dev,
2218 "Failed to update display\n");
2219 return r;
2220 }
2221 } else {
2222 if (dssdrv->set_update_mode) {
2223 r = dssdrv->set_update_mode(dssdev,
2224 OMAP_DSS_UPDATE_AUTO);
2225 if (r) {
2226 dev_err(fbdev->dev,
2227 "Failed to set update mode\n");
2228 return r;
2229 }
2230 }
2231 }
2232
2233 return 0;
2234}
2235
2188static int omapfb_probe(struct platform_device *pdev) 2236static int omapfb_probe(struct platform_device *pdev)
2189{ 2237{
2190 struct omapfb2_device *fbdev = NULL; 2238 struct omapfb2_device *fbdev = NULL;
@@ -2284,30 +2332,13 @@ static int omapfb_probe(struct platform_device *pdev)
2284 } 2332 }
2285 2333
2286 if (def_display) { 2334 if (def_display) {
2287 struct omap_dss_driver *dssdrv = def_display->driver; 2335 r = omapfb_init_display(fbdev, def_display);
2288
2289 r = def_display->driver->enable(def_display);
2290 if (r) { 2336 if (r) {
2291 dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 2337 dev_err(fbdev->dev,
2292 def_display->name); 2338 "failed to initialize default "
2339 "display\n");
2293 goto cleanup; 2340 goto cleanup;
2294 } 2341 }
2295
2296 if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
2297 u16 w, h;
2298 if (dssdrv->enable_te)
2299 dssdrv->enable_te(def_display, 1);
2300 if (dssdrv->set_update_mode)
2301 dssdrv->set_update_mode(def_display,
2302 OMAP_DSS_UPDATE_MANUAL);
2303
2304 dssdrv->get_resolution(def_display, &w, &h);
2305 def_display->driver->update(def_display, 0, 0, w, h);
2306 } else {
2307 if (dssdrv->set_update_mode)
2308 dssdrv->set_update_mode(def_display,
2309 OMAP_DSS_UPDATE_AUTO);
2310 }
2311 } 2342 }
2312 2343
2313 DBG("create sysfs for fbs\n"); 2344 DBG("create sysfs for fbs\n");
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 6f9c72cd6bb0..2f5e817b2a9a 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -29,7 +29,7 @@
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/omapfb.h> 30#include <linux/omapfb.h>
31 31
32#include <plat/display.h> 32#include <video/omapdss.h>
33#include <plat/vrfb.h> 33#include <plat/vrfb.h>
34 34
35#include "omapfb.h" 35#include "omapfb.h"
@@ -50,10 +50,12 @@ static ssize_t store_rotate_type(struct device *dev,
50 struct fb_info *fbi = dev_get_drvdata(dev); 50 struct fb_info *fbi = dev_get_drvdata(dev);
51 struct omapfb_info *ofbi = FB2OFB(fbi); 51 struct omapfb_info *ofbi = FB2OFB(fbi);
52 struct omapfb2_mem_region *rg; 52 struct omapfb2_mem_region *rg;
53 enum omap_dss_rotation_type rot_type; 53 int rot_type;
54 int r; 54 int r;
55 55
56 rot_type = simple_strtoul(buf, NULL, 0); 56 r = kstrtoint(buf, 0, &rot_type);
57 if (r)
58 return r;
57 59
58 if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) 60 if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
59 return -EINVAL; 61 return -EINVAL;
@@ -102,14 +104,15 @@ static ssize_t store_mirror(struct device *dev,
102{ 104{
103 struct fb_info *fbi = dev_get_drvdata(dev); 105 struct fb_info *fbi = dev_get_drvdata(dev);
104 struct omapfb_info *ofbi = FB2OFB(fbi); 106 struct omapfb_info *ofbi = FB2OFB(fbi);
105 unsigned long mirror; 107 int mirror;
106 int r; 108 int r;
107 struct fb_var_screeninfo new_var; 109 struct fb_var_screeninfo new_var;
108 110
109 mirror = simple_strtoul(buf, NULL, 0); 111 r = kstrtoint(buf, 0, &mirror);
112 if (r)
113 return r;
110 114
111 if (mirror != 0 && mirror != 1) 115 mirror = !!mirror;
112 return -EINVAL;
113 116
114 if (!lock_fb_info(fbi)) 117 if (!lock_fb_info(fbi))
115 return -ENODEV; 118 return -ENODEV;
@@ -445,7 +448,11 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
445 int r; 448 int r;
446 int i; 449 int i;
447 450
448 size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0)); 451 r = kstrtoul(buf, 0, &size);
452 if (r)
453 return r;
454
455 size = PAGE_ALIGN(size);
449 456
450 if (!lock_fb_info(fbi)) 457 if (!lock_fb_info(fbi))
451 return -ENODEV; 458 return -ENODEV;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 1305fc9880ba..aa1b1d974276 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -29,13 +29,15 @@
29 29
30#include <linux/rwsem.h> 30#include <linux/rwsem.h>
31 31
32#include <plat/display.h> 32#include <video/omapdss.h>
33 33
34#ifdef DEBUG 34#ifdef DEBUG
35extern unsigned int omapfb_debug; 35extern unsigned int omapfb_debug;
36#define DBG(format, ...) \ 36#define DBG(format, ...) \
37 if (omapfb_debug) \ 37 do { \
38 printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__) 38 if (omapfb_debug) \
39 printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__); \
40 } while (0)
39#else 41#else
40#define DBG(format, ...) 42#define DBG(format, ...)
41#endif 43#endif
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 3b6cdcac8f1a..0352afa49a39 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -182,6 +182,7 @@ struct s3c_fb_vsync {
182 182
183/** 183/**
184 * struct s3c_fb - overall hardware state of the hardware 184 * struct s3c_fb - overall hardware state of the hardware
185 * @slock: The spinlock protection for this data sturcture.
185 * @dev: The device that we bound to, for printing, etc. 186 * @dev: The device that we bound to, for printing, etc.
186 * @regs_res: The resource we claimed for the IO registers. 187 * @regs_res: The resource we claimed for the IO registers.
187 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. 188 * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
@@ -195,6 +196,7 @@ struct s3c_fb_vsync {
195 * @vsync_info: VSYNC-related information (count, queues...) 196 * @vsync_info: VSYNC-related information (count, queues...)
196 */ 197 */
197struct s3c_fb { 198struct s3c_fb {
199 spinlock_t slock;
198 struct device *dev; 200 struct device *dev;
199 struct resource *regs_res; 201 struct resource *regs_res;
200 struct clk *bus_clk; 202 struct clk *bus_clk;
@@ -300,6 +302,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
300 var->blue.length = 5; 302 var->blue.length = 5;
301 break; 303 break;
302 304
305 case 32:
303 case 28: 306 case 28:
304 case 25: 307 case 25:
305 var->transp.length = var->bits_per_pixel - 24; 308 var->transp.length = var->bits_per_pixel - 24;
@@ -308,7 +311,6 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
308 case 24: 311 case 24:
309 /* our 24bpp is unpacked, so 32bpp */ 312 /* our 24bpp is unpacked, so 32bpp */
310 var->bits_per_pixel = 32; 313 var->bits_per_pixel = 32;
311 case 32:
312 var->red.offset = 16; 314 var->red.offset = 16;
313 var->red.length = 8; 315 var->red.length = 8;
314 var->green.offset = 8; 316 var->green.offset = 8;
@@ -947,6 +949,8 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
947 void __iomem *regs = sfb->regs; 949 void __iomem *regs = sfb->regs;
948 u32 irq_sts_reg; 950 u32 irq_sts_reg;
949 951
952 spin_lock(&sfb->slock);
953
950 irq_sts_reg = readl(regs + VIDINTCON1); 954 irq_sts_reg = readl(regs + VIDINTCON1);
951 955
952 if (irq_sts_reg & VIDINTCON1_INT_FRAME) { 956 if (irq_sts_reg & VIDINTCON1_INT_FRAME) {
@@ -963,6 +967,7 @@ static irqreturn_t s3c_fb_irq(int irq, void *dev_id)
963 */ 967 */
964 s3c_fb_disable_irq(sfb); 968 s3c_fb_disable_irq(sfb);
965 969
970 spin_unlock(&sfb->slock);
966 return IRQ_HANDLED; 971 return IRQ_HANDLED;
967} 972}
968 973
@@ -1339,6 +1344,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
1339 sfb->pdata = pd; 1344 sfb->pdata = pd;
1340 sfb->variant = fbdrv->variant; 1345 sfb->variant = fbdrv->variant;
1341 1346
1347 spin_lock_init(&sfb->slock);
1348
1342 sfb->bus_clk = clk_get(dev, "lcd"); 1349 sfb->bus_clk = clk_get(dev, "lcd");
1343 if (IS_ERR(sfb->bus_clk)) { 1350 if (IS_ERR(sfb->bus_clk)) {
1344 dev_err(dev, "failed to get bus clock\n"); 1351 dev_err(dev, "failed to get bus clock\n");
@@ -1442,8 +1449,7 @@ err_ioremap:
1442 iounmap(sfb->regs); 1449 iounmap(sfb->regs);
1443 1450
1444err_req_region: 1451err_req_region:
1445 release_resource(sfb->regs_res); 1452 release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
1446 kfree(sfb->regs_res);
1447 1453
1448err_clk: 1454err_clk:
1449 clk_disable(sfb->bus_clk); 1455 clk_disable(sfb->bus_clk);
@@ -1479,8 +1485,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
1479 clk_disable(sfb->bus_clk); 1485 clk_disable(sfb->bus_clk);
1480 clk_put(sfb->bus_clk); 1486 clk_put(sfb->bus_clk);
1481 1487
1482 release_resource(sfb->regs_res); 1488 release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
1483 kfree(sfb->regs_res);
1484 1489
1485 kfree(sfb); 1490 kfree(sfb);
1486 1491
@@ -1521,7 +1526,8 @@ static int s3c_fb_resume(struct device *dev)
1521 1526
1522 clk_enable(sfb->bus_clk); 1527 clk_enable(sfb->bus_clk);
1523 1528
1524 /* setup registers */ 1529 /* setup gpio and output polarity controls */
1530 pd->setup_gpio();
1525 writel(pd->vidcon1, sfb->regs + VIDCON1); 1531 writel(pd->vidcon1, sfb->regs + VIDCON1);
1526 1532
1527 /* zero all windows before we do anything */ 1533 /* zero all windows before we do anything */
@@ -1549,7 +1555,7 @@ static int s3c_fb_resume(struct device *dev)
1549 return 0; 1555 return 0;
1550} 1556}
1551 1557
1552int s3c_fb_runtime_suspend(struct device *dev) 1558static int s3c_fb_runtime_suspend(struct device *dev)
1553{ 1559{
1554 struct platform_device *pdev = to_platform_device(dev); 1560 struct platform_device *pdev = to_platform_device(dev);
1555 struct s3c_fb *sfb = platform_get_drvdata(pdev); 1561 struct s3c_fb *sfb = platform_get_drvdata(pdev);
@@ -1569,7 +1575,7 @@ int s3c_fb_runtime_suspend(struct device *dev)
1569 return 0; 1575 return 0;
1570} 1576}
1571 1577
1572int s3c_fb_runtime_resume(struct device *dev) 1578static int s3c_fb_runtime_resume(struct device *dev)
1573{ 1579{
1574 struct platform_device *pdev = to_platform_device(dev); 1580 struct platform_device *pdev = to_platform_device(dev);
1575 struct s3c_fb *sfb = platform_get_drvdata(pdev); 1581 struct s3c_fb *sfb = platform_get_drvdata(pdev);
@@ -1579,7 +1585,8 @@ int s3c_fb_runtime_resume(struct device *dev)
1579 1585
1580 clk_enable(sfb->bus_clk); 1586 clk_enable(sfb->bus_clk);
1581 1587
1582 /* setup registers */ 1588 /* setup gpio and output polarity controls */
1589 pd->setup_gpio();
1583 writel(pd->vidcon1, sfb->regs + VIDCON1); 1590 writel(pd->vidcon1, sfb->regs + VIDCON1);
1584 1591
1585 /* zero all windows before we do anything */ 1592 /* zero all windows before we do anything */
@@ -1623,28 +1630,31 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = {
1623 .has_osd_c = 1, 1630 .has_osd_c = 1,
1624 .osd_size_off = 0x8, 1631 .osd_size_off = 0x8,
1625 .palette_sz = 256, 1632 .palette_sz = 256,
1626 .valid_bpp = VALID_BPP1248 | VALID_BPP(16) | VALID_BPP(24), 1633 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1634 VALID_BPP(18) | VALID_BPP(24)),
1627 }, 1635 },
1628 [1] = { 1636 [1] = {
1629 .has_osd_c = 1, 1637 .has_osd_c = 1,
1630 .has_osd_d = 1, 1638 .has_osd_d = 1,
1631 .osd_size_off = 0x12, 1639 .osd_size_off = 0xc,
1632 .has_osd_alpha = 1, 1640 .has_osd_alpha = 1,
1633 .palette_sz = 256, 1641 .palette_sz = 256,
1634 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1642 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1635 VALID_BPP(18) | VALID_BPP(19) | 1643 VALID_BPP(18) | VALID_BPP(19) |
1636 VALID_BPP(24) | VALID_BPP(25)), 1644 VALID_BPP(24) | VALID_BPP(25) |
1645 VALID_BPP(28)),
1637 }, 1646 },
1638 [2] = { 1647 [2] = {
1639 .has_osd_c = 1, 1648 .has_osd_c = 1,
1640 .has_osd_d = 1, 1649 .has_osd_d = 1,
1641 .osd_size_off = 0x12, 1650 .osd_size_off = 0xc,
1642 .has_osd_alpha = 1, 1651 .has_osd_alpha = 1,
1643 .palette_sz = 16, 1652 .palette_sz = 16,
1644 .palette_16bpp = 1, 1653 .palette_16bpp = 1,
1645 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) | 1654 .valid_bpp = (VALID_BPP1248 | VALID_BPP(16) |
1646 VALID_BPP(18) | VALID_BPP(19) | 1655 VALID_BPP(18) | VALID_BPP(19) |
1647 VALID_BPP(24) | VALID_BPP(25)), 1656 VALID_BPP(24) | VALID_BPP(25) |
1657 VALID_BPP(28)),
1648 }, 1658 },
1649 [3] = { 1659 [3] = {
1650 .has_osd_c = 1, 1660 .has_osd_c = 1,
@@ -1653,7 +1663,8 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = {
1653 .palette_16bpp = 1, 1663 .palette_16bpp = 1,
1654 .valid_bpp = (VALID_BPP124 | VALID_BPP(16) | 1664 .valid_bpp = (VALID_BPP124 | VALID_BPP(16) |
1655 VALID_BPP(18) | VALID_BPP(19) | 1665 VALID_BPP(18) | VALID_BPP(19) |
1656 VALID_BPP(24) | VALID_BPP(25)), 1666 VALID_BPP(24) | VALID_BPP(25) |
1667 VALID_BPP(28)),
1657 }, 1668 },
1658 [4] = { 1669 [4] = {
1659 .has_osd_c = 1, 1670 .has_osd_c = 1,
@@ -1662,7 +1673,65 @@ static struct s3c_fb_win_variant s3c_fb_data_64xx_wins[] = {
1662 .palette_16bpp = 1, 1673 .palette_16bpp = 1,
1663 .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) | 1674 .valid_bpp = (VALID_BPP(1) | VALID_BPP(2) |
1664 VALID_BPP(16) | VALID_BPP(18) | 1675 VALID_BPP(16) | VALID_BPP(18) |
1665 VALID_BPP(24) | VALID_BPP(25)), 1676 VALID_BPP(19) | VALID_BPP(24) |
1677 VALID_BPP(25) | VALID_BPP(28)),
1678 },
1679};
1680
1681static struct s3c_fb_win_variant s3c_fb_data_s5p_wins[] = {
1682 [0] = {
1683 .has_osd_c = 1,
1684 .osd_size_off = 0x8,
1685 .palette_sz = 256,
1686 .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) |
1687 VALID_BPP(15) | VALID_BPP(16) |
1688 VALID_BPP(18) | VALID_BPP(19) |
1689 VALID_BPP(24) | VALID_BPP(25) |
1690 VALID_BPP(32)),
1691 },
1692 [1] = {
1693 .has_osd_c = 1,
1694 .has_osd_d = 1,
1695 .osd_size_off = 0xc,
1696 .has_osd_alpha = 1,
1697 .palette_sz = 256,
1698 .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) |
1699 VALID_BPP(15) | VALID_BPP(16) |
1700 VALID_BPP(18) | VALID_BPP(19) |
1701 VALID_BPP(24) | VALID_BPP(25) |
1702 VALID_BPP(32)),
1703 },
1704 [2] = {
1705 .has_osd_c = 1,
1706 .has_osd_d = 1,
1707 .osd_size_off = 0xc,
1708 .has_osd_alpha = 1,
1709 .palette_sz = 256,
1710 .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) |
1711 VALID_BPP(15) | VALID_BPP(16) |
1712 VALID_BPP(18) | VALID_BPP(19) |
1713 VALID_BPP(24) | VALID_BPP(25) |
1714 VALID_BPP(32)),
1715 },
1716 [3] = {
1717 .has_osd_c = 1,
1718 .has_osd_alpha = 1,
1719 .palette_sz = 256,
1720 .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) |
1721 VALID_BPP(15) | VALID_BPP(16) |
1722 VALID_BPP(18) | VALID_BPP(19) |
1723 VALID_BPP(24) | VALID_BPP(25) |
1724 VALID_BPP(32)),
1725 },
1726 [4] = {
1727 .has_osd_c = 1,
1728 .has_osd_alpha = 1,
1729 .palette_sz = 256,
1730 .valid_bpp = (VALID_BPP1248 | VALID_BPP(13) |
1731 VALID_BPP(15) | VALID_BPP(16) |
1732 VALID_BPP(18) | VALID_BPP(19) |
1733 VALID_BPP(24) | VALID_BPP(25) |
1734 VALID_BPP(32)),
1666 }, 1735 },
1667}; 1736};
1668 1737
@@ -1719,11 +1788,11 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
1719 1788
1720 .has_prtcon = 1, 1789 .has_prtcon = 1,
1721 }, 1790 },
1722 .win[0] = &s3c_fb_data_64xx_wins[0], 1791 .win[0] = &s3c_fb_data_s5p_wins[0],
1723 .win[1] = &s3c_fb_data_64xx_wins[1], 1792 .win[1] = &s3c_fb_data_s5p_wins[1],
1724 .win[2] = &s3c_fb_data_64xx_wins[2], 1793 .win[2] = &s3c_fb_data_s5p_wins[2],
1725 .win[3] = &s3c_fb_data_64xx_wins[3], 1794 .win[3] = &s3c_fb_data_s5p_wins[3],
1726 .win[4] = &s3c_fb_data_64xx_wins[4], 1795 .win[4] = &s3c_fb_data_s5p_wins[4],
1727}; 1796};
1728 1797
1729static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { 1798static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
@@ -1749,11 +1818,11 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
1749 1818
1750 .has_shadowcon = 1, 1819 .has_shadowcon = 1,
1751 }, 1820 },
1752 .win[0] = &s3c_fb_data_64xx_wins[0], 1821 .win[0] = &s3c_fb_data_s5p_wins[0],
1753 .win[1] = &s3c_fb_data_64xx_wins[1], 1822 .win[1] = &s3c_fb_data_s5p_wins[1],
1754 .win[2] = &s3c_fb_data_64xx_wins[2], 1823 .win[2] = &s3c_fb_data_s5p_wins[2],
1755 .win[3] = &s3c_fb_data_64xx_wins[3], 1824 .win[3] = &s3c_fb_data_s5p_wins[3],
1756 .win[4] = &s3c_fb_data_64xx_wins[4], 1825 .win[4] = &s3c_fb_data_s5p_wins[4],
1757}; 1826};
1758 1827
1759/* S3C2443/S3C2416 style hardware */ 1828/* S3C2443/S3C2416 style hardware */
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 61c819e35f7f..0aa13761de6e 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -867,7 +867,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
867 goto dealloc_fb; 867 goto dealloc_fb;
868 } 868 }
869 869
870 size = (res->end - res->start) + 1; 870 size = resource_size(res);
871 info->mem = request_mem_region(res->start, size, pdev->name); 871 info->mem = request_mem_region(res->start, size, pdev->name);
872 if (info->mem == NULL) { 872 if (info->mem == NULL) {
873 dev_err(&pdev->dev, "failed to get memory region\n"); 873 dev_err(&pdev->dev, "failed to get memory region\n");
@@ -997,8 +997,7 @@ release_irq:
997release_regs: 997release_regs:
998 iounmap(info->io); 998 iounmap(info->io);
999release_mem: 999release_mem:
1000 release_resource(info->mem); 1000 release_mem_region(res->start, size);
1001 kfree(info->mem);
1002dealloc_fb: 1001dealloc_fb:
1003 platform_set_drvdata(pdev, NULL); 1002 platform_set_drvdata(pdev, NULL);
1004 framebuffer_release(fbinfo); 1003 framebuffer_release(fbinfo);
@@ -1044,8 +1043,7 @@ static int __devexit s3c2410fb_remove(struct platform_device *pdev)
1044 1043
1045 iounmap(info->io); 1044 iounmap(info->io);
1046 1045
1047 release_resource(info->mem); 1046 release_mem_region(info->mem->start, resource_size(info->mem));
1048 kfree(info->mem);
1049 1047
1050 platform_set_drvdata(pdev, NULL); 1048 platform_set_drvdata(pdev, NULL);
1051 framebuffer_release(fbinfo); 1049 framebuffer_release(fbinfo);
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index c4482f2e5799..4ca5d0c8fe84 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -25,6 +25,9 @@
25#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */ 25#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
26#include <video/vga.h> 26#include <video/vga.h>
27 27
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30
28#ifdef CONFIG_MTRR 31#ifdef CONFIG_MTRR
29#include <asm/mtrr.h> 32#include <asm/mtrr.h>
30#endif 33#endif
@@ -36,6 +39,12 @@ struct s3fb_info {
36 struct mutex open_lock; 39 struct mutex open_lock;
37 unsigned int ref_count; 40 unsigned int ref_count;
38 u32 pseudo_palette[16]; 41 u32 pseudo_palette[16];
42#ifdef CONFIG_FB_S3_DDC
43 u8 __iomem *mmio;
44 bool ddc_registered;
45 struct i2c_adapter ddc_adapter;
46 struct i2c_algo_bit_data ddc_algo;
47#endif
39}; 48};
40 49
41 50
@@ -105,6 +114,9 @@ static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64",
105#define CHIP_UNDECIDED_FLAG 0x80 114#define CHIP_UNDECIDED_FLAG 0x80
106#define CHIP_MASK 0xFF 115#define CHIP_MASK 0xFF
107 116
117#define MMIO_OFFSET 0x1000000
118#define MMIO_SIZE 0x10000
119
108/* CRT timing register sets */ 120/* CRT timing register sets */
109 121
110static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END}; 122static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END};
@@ -140,7 +152,7 @@ static const struct svga_timing_regs s3_timing_regs = {
140/* Module parameters */ 152/* Module parameters */
141 153
142 154
143static char *mode_option __devinitdata = "640x480-8@60"; 155static char *mode_option __devinitdata;
144 156
145#ifdef CONFIG_MTRR 157#ifdef CONFIG_MTRR
146static int mtrr __devinitdata = 1; 158static int mtrr __devinitdata = 1;
@@ -169,6 +181,119 @@ MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, defau
169 181
170/* ------------------------------------------------------------------------- */ 182/* ------------------------------------------------------------------------- */
171 183
184#ifdef CONFIG_FB_S3_DDC
185
186#define DDC_REG 0xaa /* Trio 3D/1X/2X */
187#define DDC_MMIO_REG 0xff20 /* all other chips */
188#define DDC_SCL_OUT (1 << 0)
189#define DDC_SDA_OUT (1 << 1)
190#define DDC_SCL_IN (1 << 2)
191#define DDC_SDA_IN (1 << 3)
192#define DDC_DRIVE_EN (1 << 4)
193
194static bool s3fb_ddc_needs_mmio(int chip)
195{
196 return !(chip == CHIP_360_TRIO3D_1X ||
197 chip == CHIP_362_TRIO3D_2X ||
198 chip == CHIP_368_TRIO3D_2X);
199}
200
201static u8 s3fb_ddc_read(struct s3fb_info *par)
202{
203 if (s3fb_ddc_needs_mmio(par->chip))
204 return readb(par->mmio + DDC_MMIO_REG);
205 else
206 return vga_rcrt(par->state.vgabase, DDC_REG);
207}
208
209static void s3fb_ddc_write(struct s3fb_info *par, u8 val)
210{
211 if (s3fb_ddc_needs_mmio(par->chip))
212 writeb(val, par->mmio + DDC_MMIO_REG);
213 else
214 vga_wcrt(par->state.vgabase, DDC_REG, val);
215}
216
217static void s3fb_ddc_setscl(void *data, int val)
218{
219 struct s3fb_info *par = data;
220 unsigned char reg;
221
222 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
223 if (val)
224 reg |= DDC_SCL_OUT;
225 else
226 reg &= ~DDC_SCL_OUT;
227 s3fb_ddc_write(par, reg);
228}
229
230static void s3fb_ddc_setsda(void *data, int val)
231{
232 struct s3fb_info *par = data;
233 unsigned char reg;
234
235 reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
236 if (val)
237 reg |= DDC_SDA_OUT;
238 else
239 reg &= ~DDC_SDA_OUT;
240 s3fb_ddc_write(par, reg);
241}
242
243static int s3fb_ddc_getscl(void *data)
244{
245 struct s3fb_info *par = data;
246
247 return !!(s3fb_ddc_read(par) & DDC_SCL_IN);
248}
249
250static int s3fb_ddc_getsda(void *data)
251{
252 struct s3fb_info *par = data;
253
254 return !!(s3fb_ddc_read(par) & DDC_SDA_IN);
255}
256
257static int __devinit s3fb_setup_ddc_bus(struct fb_info *info)
258{
259 struct s3fb_info *par = info->par;
260
261 strlcpy(par->ddc_adapter.name, info->fix.id,
262 sizeof(par->ddc_adapter.name));
263 par->ddc_adapter.owner = THIS_MODULE;
264 par->ddc_adapter.class = I2C_CLASS_DDC;
265 par->ddc_adapter.algo_data = &par->ddc_algo;
266 par->ddc_adapter.dev.parent = info->device;
267 par->ddc_algo.setsda = s3fb_ddc_setsda;
268 par->ddc_algo.setscl = s3fb_ddc_setscl;
269 par->ddc_algo.getsda = s3fb_ddc_getsda;
270 par->ddc_algo.getscl = s3fb_ddc_getscl;
271 par->ddc_algo.udelay = 10;
272 par->ddc_algo.timeout = 20;
273 par->ddc_algo.data = par;
274
275 i2c_set_adapdata(&par->ddc_adapter, par);
276
277 /*
278 * some Virge cards have external MUX to switch chip I2C bus between
279 * DDC and extension pins - switch it do DDC
280 */
281/* vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */
282 if (par->chip == CHIP_357_VIRGE_GX2 ||
283 par->chip == CHIP_359_VIRGE_GX2P)
284 svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03);
285 else
286 svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03);
287 /* some Virge need this or the DDC is ignored */
288 svga_wcrt_mask(par->state.vgabase, 0x5c, 0x03, 0x03);
289
290 return i2c_bit_add_bus(&par->ddc_adapter);
291}
292#endif /* CONFIG_FB_S3_DDC */
293
294
295/* ------------------------------------------------------------------------- */
296
172/* Set font in S3 fast text mode */ 297/* Set font in S3 fast text mode */
173 298
174static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) 299static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
@@ -994,6 +1119,7 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
994 struct s3fb_info *par; 1119 struct s3fb_info *par;
995 int rc; 1120 int rc;
996 u8 regval, cr38, cr39; 1121 u8 regval, cr38, cr39;
1122 bool found = false;
997 1123
998 /* Ignore secondary VGA device because there is no VGA arbitration */ 1124 /* Ignore secondary VGA device because there is no VGA arbitration */
999 if (! svga_primary_device(dev)) { 1125 if (! svga_primary_device(dev)) {
@@ -1110,12 +1236,69 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
1110 info->fix.ypanstep = 0; 1236 info->fix.ypanstep = 0;
1111 info->fix.accel = FB_ACCEL_NONE; 1237 info->fix.accel = FB_ACCEL_NONE;
1112 info->pseudo_palette = (void*) (par->pseudo_palette); 1238 info->pseudo_palette = (void*) (par->pseudo_palette);
1239 info->var.bits_per_pixel = 8;
1240
1241#ifdef CONFIG_FB_S3_DDC
1242 /* Enable MMIO if needed */
1243 if (s3fb_ddc_needs_mmio(par->chip)) {
1244 par->mmio = ioremap(info->fix.smem_start + MMIO_OFFSET, MMIO_SIZE);
1245 if (par->mmio)
1246 svga_wcrt_mask(par->state.vgabase, 0x53, 0x08, 0x08); /* enable MMIO */
1247 else
1248 dev_err(info->device, "unable to map MMIO at 0x%lx, disabling DDC",
1249 info->fix.smem_start + MMIO_OFFSET);
1250 }
1251 if (!s3fb_ddc_needs_mmio(par->chip) || par->mmio)
1252 if (s3fb_setup_ddc_bus(info) == 0) {
1253 u8 *edid = fb_ddc_read(&par->ddc_adapter);
1254 par->ddc_registered = true;
1255 if (edid) {
1256 fb_edid_to_monspecs(edid, &info->monspecs);
1257 kfree(edid);
1258 if (!info->monspecs.modedb)
1259 dev_err(info->device, "error getting mode database\n");
1260 else {
1261 const struct fb_videomode *m;
1262
1263 fb_videomode_to_modelist(info->monspecs.modedb,
1264 info->monspecs.modedb_len,
1265 &info->modelist);
1266 m = fb_find_best_display(&info->monspecs, &info->modelist);
1267 if (m) {
1268 fb_videomode_to_var(&info->var, m);
1269 /* fill all other info->var's fields */
1270 if (s3fb_check_var(&info->var, info) == 0)
1271 found = true;
1272 }
1273 }
1274 }
1275 }
1276#endif
1277 if (!mode_option && !found)
1278 mode_option = "640x480-8@60";
1113 1279
1114 /* Prepare startup mode */ 1280 /* Prepare startup mode */
1115 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); 1281 if (mode_option) {
1116 if (! ((rc == 1) || (rc == 2))) { 1282 rc = fb_find_mode(&info->var, info, mode_option,
1117 rc = -EINVAL; 1283 info->monspecs.modedb, info->monspecs.modedb_len,
1118 dev_err(info->device, "mode %s not found\n", mode_option); 1284 NULL, info->var.bits_per_pixel);
1285 if (!rc || rc == 4) {
1286 rc = -EINVAL;
1287 dev_err(info->device, "mode %s not found\n", mode_option);
1288 fb_destroy_modedb(info->monspecs.modedb);
1289 info->monspecs.modedb = NULL;
1290 goto err_find_mode;
1291 }
1292 }
1293
1294 fb_destroy_modedb(info->monspecs.modedb);
1295 info->monspecs.modedb = NULL;
1296
1297 /* maximize virtual vertical size for fast scrolling */
1298 info->var.yres_virtual = info->fix.smem_len * 8 /
1299 (info->var.bits_per_pixel * info->var.xres_virtual);
1300 if (info->var.yres_virtual < info->var.yres) {
1301 dev_err(info->device, "virtual vertical size smaller than real\n");
1119 goto err_find_mode; 1302 goto err_find_mode;
1120 } 1303 }
1121 1304
@@ -1164,6 +1347,12 @@ err_reg_fb:
1164 fb_dealloc_cmap(&info->cmap); 1347 fb_dealloc_cmap(&info->cmap);
1165err_alloc_cmap: 1348err_alloc_cmap:
1166err_find_mode: 1349err_find_mode:
1350#ifdef CONFIG_FB_S3_DDC
1351 if (par->ddc_registered)
1352 i2c_del_adapter(&par->ddc_adapter);
1353 if (par->mmio)
1354 iounmap(par->mmio);
1355#endif
1167 pci_iounmap(dev, info->screen_base); 1356 pci_iounmap(dev, info->screen_base);
1168err_iomap: 1357err_iomap:
1169 pci_release_regions(dev); 1358 pci_release_regions(dev);
@@ -1180,12 +1369,11 @@ err_enable_device:
1180static void __devexit s3_pci_remove(struct pci_dev *dev) 1369static void __devexit s3_pci_remove(struct pci_dev *dev)
1181{ 1370{
1182 struct fb_info *info = pci_get_drvdata(dev); 1371 struct fb_info *info = pci_get_drvdata(dev);
1372 struct s3fb_info __maybe_unused *par = info->par;
1183 1373
1184 if (info) { 1374 if (info) {
1185 1375
1186#ifdef CONFIG_MTRR 1376#ifdef CONFIG_MTRR
1187 struct s3fb_info *par = info->par;
1188
1189 if (par->mtrr_reg >= 0) { 1377 if (par->mtrr_reg >= 0) {
1190 mtrr_del(par->mtrr_reg, 0, 0); 1378 mtrr_del(par->mtrr_reg, 0, 0);
1191 par->mtrr_reg = -1; 1379 par->mtrr_reg = -1;
@@ -1195,6 +1383,13 @@ static void __devexit s3_pci_remove(struct pci_dev *dev)
1195 unregister_framebuffer(info); 1383 unregister_framebuffer(info);
1196 fb_dealloc_cmap(&info->cmap); 1384 fb_dealloc_cmap(&info->cmap);
1197 1385
1386#ifdef CONFIG_FB_S3_DDC
1387 if (par->ddc_registered)
1388 i2c_del_adapter(&par->ddc_adapter);
1389 if (par->mmio)
1390 iounmap(par->mmio);
1391#endif
1392
1198 pci_iounmap(dev, info->screen_base); 1393 pci_iounmap(dev, info->screen_base);
1199 pci_release_regions(dev); 1394 pci_release_regions(dev);
1200/* pci_disable_device(dev); */ 1395/* pci_disable_device(dev); */
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index bb71fea07284..80fa87e2ae2f 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -171,6 +171,8 @@ void savagefb_create_i2c_busses(struct fb_info *info)
171 171
172 switch (par->chip) { 172 switch (par->chip) {
173 case S3_PROSAVAGE: 173 case S3_PROSAVAGE:
174 case S3_PROSAVAGEDDR:
175 case S3_TWISTER:
174 par->chan.reg = CR_SERIAL2; 176 par->chan.reg = CR_SERIAL2;
175 par->chan.ioaddr = par->mmio.vbase; 177 par->chan.ioaddr = par->mmio.vbase;
176 par->chan.algo.setsda = prosavage_gpio_setsda; 178 par->chan.algo.setsda = prosavage_gpio_setsda;
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index 4e9490c19d7d..32549d177b19 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -36,7 +36,6 @@
36#define PCI_CHIP_SAVAGE_IX 0x8c13 36#define PCI_CHIP_SAVAGE_IX 0x8c13
37#define PCI_CHIP_PROSAVAGE_PM 0x8a25 37#define PCI_CHIP_PROSAVAGE_PM 0x8a25
38#define PCI_CHIP_PROSAVAGE_KM 0x8a26 38#define PCI_CHIP_PROSAVAGE_KM 0x8a26
39 /* Twister is a code name; hope I get the real name soon. */
40#define PCI_CHIP_S3TWISTER_P 0x8d01 39#define PCI_CHIP_S3TWISTER_P 0x8d01
41#define PCI_CHIP_S3TWISTER_K 0x8d02 40#define PCI_CHIP_S3TWISTER_K 0x8d02
42#define PCI_CHIP_PROSAVAGE_DDR 0x8d03 41#define PCI_CHIP_PROSAVAGE_DDR 0x8d03
@@ -52,14 +51,15 @@
52#define PCI_CHIP_SUPSAV_IXCDDR 0x8c2f 51#define PCI_CHIP_SUPSAV_IXCDDR 0x8c2f
53 52
54 53
54#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
55 55
56#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) 56#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
57 57
58#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) || (chip==S3_PROSAVAGE)) 58#define S3_SAVAGE4_SERIES(chip) ((chip>=S3_SAVAGE4) || (chip<=S3_PROSAVAGEDDR))
59 59
60#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) 60#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
61 61
62#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) 62#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) || (chip==S3_PROSAVAGEDDR))
63 63
64/* Chip tags. These are used to group the adapters into 64/* Chip tags. These are used to group the adapters into
65 * related families. 65 * related families.
@@ -71,6 +71,8 @@ typedef enum {
71 S3_SAVAGE_MX, 71 S3_SAVAGE_MX,
72 S3_SAVAGE4, 72 S3_SAVAGE4,
73 S3_PROSAVAGE, 73 S3_PROSAVAGE,
74 S3_TWISTER,
75 S3_PROSAVAGEDDR,
74 S3_SUPERSAVAGE, 76 S3_SUPERSAVAGE,
75 S3_SAVAGE2000, 77 S3_SAVAGE2000,
76 S3_LAST 78 S3_LAST
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index a2dc1a7ec758..3b7f2f5bae71 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -328,7 +328,9 @@ SavageSetup2DEngine(struct savagefb_par *par)
328 savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par); 328 savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
329 break; 329 break;
330 case S3_SAVAGE4: 330 case S3_SAVAGE4:
331 case S3_TWISTER:
331 case S3_PROSAVAGE: 332 case S3_PROSAVAGE:
333 case S3_PROSAVAGEDDR:
332 case S3_SUPERSAVAGE: 334 case S3_SUPERSAVAGE:
333 /* Disable BCI */ 335 /* Disable BCI */
334 savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par); 336 savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
@@ -1886,6 +1888,8 @@ static int savage_init_hw(struct savagefb_par *par)
1886 break; 1888 break;
1887 1889
1888 case S3_PROSAVAGE: 1890 case S3_PROSAVAGE:
1891 case S3_PROSAVAGEDDR:
1892 case S3_TWISTER:
1889 videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024; 1893 videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024;
1890 break; 1894 break;
1891 1895
@@ -1963,7 +1967,8 @@ static int savage_init_hw(struct savagefb_par *par)
1963 } 1967 }
1964 } 1968 }
1965 1969
1966 if (S3_SAVAGE_MOBILE_SERIES(par->chip) && !par->crtonly) 1970 if ((S3_SAVAGE_MOBILE_SERIES(par->chip) ||
1971 S3_MOBILE_TWISTER_SERIES(par->chip)) && !par->crtonly)
1967 par->display_type = DISP_LCD; 1972 par->display_type = DISP_LCD;
1968 else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi)) 1973 else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi))
1969 par->display_type = DISP_DFP; 1974 par->display_type = DISP_DFP;
@@ -2111,19 +2116,19 @@ static int __devinit savage_init_fb_info(struct fb_info *info,
2111 snprintf(info->fix.id, 16, "ProSavageKM"); 2116 snprintf(info->fix.id, 16, "ProSavageKM");
2112 break; 2117 break;
2113 case FB_ACCEL_S3TWISTER_P: 2118 case FB_ACCEL_S3TWISTER_P:
2114 par->chip = S3_PROSAVAGE; 2119 par->chip = S3_TWISTER;
2115 snprintf(info->fix.id, 16, "TwisterP"); 2120 snprintf(info->fix.id, 16, "TwisterP");
2116 break; 2121 break;
2117 case FB_ACCEL_S3TWISTER_K: 2122 case FB_ACCEL_S3TWISTER_K:
2118 par->chip = S3_PROSAVAGE; 2123 par->chip = S3_TWISTER;
2119 snprintf(info->fix.id, 16, "TwisterK"); 2124 snprintf(info->fix.id, 16, "TwisterK");
2120 break; 2125 break;
2121 case FB_ACCEL_PROSAVAGE_DDR: 2126 case FB_ACCEL_PROSAVAGE_DDR:
2122 par->chip = S3_PROSAVAGE; 2127 par->chip = S3_PROSAVAGEDDR;
2123 snprintf(info->fix.id, 16, "ProSavageDDR"); 2128 snprintf(info->fix.id, 16, "ProSavageDDR");
2124 break; 2129 break;
2125 case FB_ACCEL_PROSAVAGE_DDRK: 2130 case FB_ACCEL_PROSAVAGE_DDRK:
2126 par->chip = S3_PROSAVAGE; 2131 par->chip = S3_PROSAVAGEDDR;
2127 snprintf(info->fix.id, 16, "ProSavage8"); 2132 snprintf(info->fix.id, 16, "ProSavage8");
2128 break; 2133 break;
2129 } 2134 }
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 8fe19582c460..45e47d847163 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -551,8 +551,7 @@ out_unmap:
551 free_irq(par->irq, &par->vsync); 551 free_irq(par->irq, &par->vsync);
552 iounmap(par->base); 552 iounmap(par->base);
553out_res: 553out_res:
554 release_resource(par->ioarea); 554 release_mem_region(res->start, resource_size(res));
555 kfree(par->ioarea);
556out_fb: 555out_fb:
557 framebuffer_release(info); 556 framebuffer_release(info);
558 return ret; 557 return ret;
@@ -570,8 +569,7 @@ static int __devexit sh7760fb_remove(struct platform_device *dev)
570 if (par->irq >= 0) 569 if (par->irq >= 0)
571 free_irq(par->irq, par); 570 free_irq(par->irq, par);
572 iounmap(par->base); 571 iounmap(par->base);
573 release_resource(par->ioarea); 572 release_mem_region(par->ioarea->start, resource_size(par->ioarea));
574 kfree(par->ioarea);
575 framebuffer_release(info); 573 framebuffer_release(info);
576 platform_set_drvdata(dev, NULL); 574 platform_set_drvdata(dev, NULL);
577 575
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 2b9e56a6bde4..6ae40b630dc9 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1131,15 +1131,19 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
1131 pm_runtime_get_sync(hdmi->dev); 1131 pm_runtime_get_sync(hdmi->dev);
1132 1132
1133 ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate); 1133 ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
1134 if (ret < 0) 1134 if (ret < 0) {
1135 pm_runtime_put(hdmi->dev);
1135 goto out; 1136 goto out;
1137 }
1136 1138
1137 hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE; 1139 hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
1138 1140
1139 /* Reconfigure the clock */ 1141 /* Reconfigure the clock */
1140 ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate); 1142 ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
1141 if (ret < 0) 1143 if (ret < 0) {
1144 pm_runtime_put(hdmi->dev);
1142 goto out; 1145 goto out;
1146 }
1143 1147
1144 msleep(10); 1148 msleep(10);
1145 sh_hdmi_configure(hdmi); 1149 sh_hdmi_configure(hdmi);
@@ -1336,6 +1340,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
1336ecodec: 1340ecodec:
1337 free_irq(irq, hdmi); 1341 free_irq(irq, hdmi);
1338ereqirq: 1342ereqirq:
1343 pm_runtime_suspend(&pdev->dev);
1339 pm_runtime_disable(&pdev->dev); 1344 pm_runtime_disable(&pdev->dev);
1340 iounmap(hdmi->base); 1345 iounmap(hdmi->base);
1341emap: 1346emap:
@@ -1372,6 +1377,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
1372 free_irq(irq, hdmi); 1377 free_irq(irq, hdmi);
1373 /* Wait for already scheduled work */ 1378 /* Wait for already scheduled work */
1374 cancel_delayed_work_sync(&hdmi->edid_work); 1379 cancel_delayed_work_sync(&hdmi->edid_work);
1380 pm_runtime_suspend(&pdev->dev);
1375 pm_runtime_disable(&pdev->dev); 1381 pm_runtime_disable(&pdev->dev);
1376 clk_disable(hdmi->hdmi_clk); 1382 clk_disable(hdmi->hdmi_clk);
1377 clk_put(hdmi->hdmi_clk); 1383 clk_put(hdmi->hdmi_clk);
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 9bcc61b4ef14..404c03b4b7c7 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -27,6 +27,7 @@
27#include <asm/atomic.h> 27#include <asm/atomic.h>
28 28
29#include "sh_mobile_lcdcfb.h" 29#include "sh_mobile_lcdcfb.h"
30#include "sh_mobile_meram.h"
30 31
31#define SIDE_B_OFFSET 0x1000 32#define SIDE_B_OFFSET 0x1000
32#define MIRROR_OFFSET 0x2000 33#define MIRROR_OFFSET 0x2000
@@ -143,6 +144,7 @@ struct sh_mobile_lcdc_priv {
143 unsigned long saved_shared_regs[NR_SHARED_REGS]; 144 unsigned long saved_shared_regs[NR_SHARED_REGS];
144 int started; 145 int started;
145 int forced_bpp; /* 2 channel LCDC must share bpp setting */ 146 int forced_bpp; /* 2 channel LCDC must share bpp setting */
147 struct sh_mobile_meram_info *meram_dev;
146}; 148};
147 149
148static bool banked(int reg_nr) 150static bool banked(int reg_nr)
@@ -469,7 +471,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
469 int bpp = 0; 471 int bpp = 0;
470 unsigned long ldddsr; 472 unsigned long ldddsr;
471 int k, m; 473 int k, m;
472 int ret = 0;
473 474
474 /* enable clocks before accessing the hardware */ 475 /* enable clocks before accessing the hardware */
475 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 476 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -538,11 +539,12 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
538 lcdc_write_chan(ch, LDPMR, 0); 539 lcdc_write_chan(ch, LDPMR, 0);
539 540
540 board_cfg = &ch->cfg.board_cfg; 541 board_cfg = &ch->cfg.board_cfg;
541 if (board_cfg->setup_sys) 542 if (board_cfg->setup_sys) {
542 ret = board_cfg->setup_sys(board_cfg->board_data, ch, 543 int ret = board_cfg->setup_sys(board_cfg->board_data,
543 &sh_mobile_lcdc_sys_bus_ops); 544 ch, &sh_mobile_lcdc_sys_bus_ops);
544 if (ret) 545 if (ret)
545 return ret; 546 return ret;
547 }
546 } 548 }
547 549
548 /* word and long word swap */ 550 /* word and long word swap */
@@ -564,6 +566,9 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
564 } 566 }
565 567
566 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 568 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
569 unsigned long base_addr_y;
570 unsigned long base_addr_c = 0;
571 int pitch;
567 ch = &priv->ch[k]; 572 ch = &priv->ch[k];
568 573
569 if (!priv->ch[k].enabled) 574 if (!priv->ch[k].enabled)
@@ -598,16 +603,68 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
598 } 603 }
599 lcdc_write_chan(ch, LDDFR, tmp); 604 lcdc_write_chan(ch, LDDFR, tmp);
600 605
606 base_addr_y = ch->info->fix.smem_start;
607 base_addr_c = base_addr_y +
608 ch->info->var.xres *
609 ch->info->var.yres_virtual;
610 pitch = ch->info->fix.line_length;
611
612 /* test if we can enable meram */
613 if (ch->cfg.meram_cfg && priv->meram_dev &&
614 priv->meram_dev->ops) {
615 struct sh_mobile_meram_cfg *cfg;
616 struct sh_mobile_meram_info *mdev;
617 unsigned long icb_addr_y, icb_addr_c;
618 int icb_pitch;
619 int pf;
620
621 cfg = ch->cfg.meram_cfg;
622 mdev = priv->meram_dev;
623 /* we need to de-init configured ICBs before we
624 * we can re-initialize them.
625 */
626 if (ch->meram_enabled)
627 mdev->ops->meram_unregister(mdev, cfg);
628
629 ch->meram_enabled = 0;
630
631 if (ch->info->var.nonstd) {
632 if (ch->info->var.bits_per_pixel == 24)
633 pf = SH_MOBILE_MERAM_PF_NV24;
634 else
635 pf = SH_MOBILE_MERAM_PF_NV;
636 } else {
637 pf = SH_MOBILE_MERAM_PF_RGB;
638 }
639
640 ret = mdev->ops->meram_register(mdev, cfg, pitch,
641 ch->info->var.yres,
642 pf,
643 base_addr_y,
644 base_addr_c,
645 &icb_addr_y,
646 &icb_addr_c,
647 &icb_pitch);
648 if (!ret) {
649 /* set LDSA1R value */
650 base_addr_y = icb_addr_y;
651 pitch = icb_pitch;
652
653 /* set LDSA2R value if required */
654 if (base_addr_c)
655 base_addr_c = icb_addr_c;
656
657 ch->meram_enabled = 1;
658 }
659 }
660
601 /* point out our frame buffer */ 661 /* point out our frame buffer */
602 lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start); 662 lcdc_write_chan(ch, LDSA1R, base_addr_y);
603 if (ch->info->var.nonstd) 663 if (ch->info->var.nonstd)
604 lcdc_write_chan(ch, LDSA2R, 664 lcdc_write_chan(ch, LDSA2R, base_addr_c);
605 ch->info->fix.smem_start +
606 ch->info->var.xres *
607 ch->info->var.yres_virtual);
608 665
609 /* set line size */ 666 /* set line size */
610 lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length); 667 lcdc_write_chan(ch, LDMLSR, pitch);
611 668
612 /* setup deferred io if SYS bus */ 669 /* setup deferred io if SYS bus */
613 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; 670 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
@@ -692,6 +749,17 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
692 board_cfg->display_off(board_cfg->board_data); 749 board_cfg->display_off(board_cfg->board_data);
693 module_put(board_cfg->owner); 750 module_put(board_cfg->owner);
694 } 751 }
752
753 /* disable the meram */
754 if (ch->meram_enabled) {
755 struct sh_mobile_meram_cfg *cfg;
756 struct sh_mobile_meram_info *mdev;
757 cfg = ch->cfg.meram_cfg;
758 mdev = priv->meram_dev;
759 mdev->ops->meram_unregister(mdev, cfg);
760 ch->meram_enabled = 0;
761 }
762
695 } 763 }
696 764
697 /* stop the lcdc */ 765 /* stop the lcdc */
@@ -875,9 +943,29 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
875 } else 943 } else
876 base_addr_c = 0; 944 base_addr_c = 0;
877 945
878 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y); 946 if (!ch->meram_enabled) {
879 if (base_addr_c) 947 lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
880 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c); 948 if (base_addr_c)
949 lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
950 } else {
951 struct sh_mobile_meram_cfg *cfg;
952 struct sh_mobile_meram_info *mdev;
953 unsigned long icb_addr_y, icb_addr_c;
954 int ret;
955
956 cfg = ch->cfg.meram_cfg;
957 mdev = priv->meram_dev;
958 ret = mdev->ops->meram_update(mdev, cfg,
959 base_addr_y, base_addr_c,
960 &icb_addr_y, &icb_addr_c);
961 if (ret)
962 return ret;
963
964 lcdc_write_chan_mirror(ch, LDSA1R, icb_addr_y);
965 if (icb_addr_c)
966 lcdc_write_chan_mirror(ch, LDSA2R, icb_addr_c);
967
968 }
881 969
882 if (lcdc_chan_is_sublcd(ch)) 970 if (lcdc_chan_is_sublcd(ch))
883 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS); 971 lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
@@ -1288,7 +1376,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1288 struct fb_info *info = event->info; 1376 struct fb_info *info = event->info;
1289 struct sh_mobile_lcdc_chan *ch = info->par; 1377 struct sh_mobile_lcdc_chan *ch = info->par;
1290 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 1378 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
1291 int ret;
1292 1379
1293 if (&ch->lcdc->notifier != nb) 1380 if (&ch->lcdc->notifier != nb)
1294 return NOTIFY_DONE; 1381 return NOTIFY_DONE;
@@ -1302,7 +1389,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1302 board_cfg->display_off(board_cfg->board_data); 1389 board_cfg->display_off(board_cfg->board_data);
1303 module_put(board_cfg->owner); 1390 module_put(board_cfg->owner);
1304 } 1391 }
1305 pm_runtime_put(info->device);
1306 sh_mobile_lcdc_stop(ch->lcdc); 1392 sh_mobile_lcdc_stop(ch->lcdc);
1307 break; 1393 break;
1308 case FB_EVENT_RESUME: 1394 case FB_EVENT_RESUME:
@@ -1316,9 +1402,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1316 module_put(board_cfg->owner); 1402 module_put(board_cfg->owner);
1317 } 1403 }
1318 1404
1319 ret = sh_mobile_lcdc_start(ch->lcdc); 1405 sh_mobile_lcdc_start(ch->lcdc);
1320 if (!ret)
1321 pm_runtime_get_sync(info->device);
1322 } 1406 }
1323 1407
1324 return NOTIFY_OK; 1408 return NOTIFY_OK;
@@ -1420,6 +1504,8 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1420 goto err1; 1504 goto err1;
1421 } 1505 }
1422 1506
1507 priv->meram_dev = pdata->meram_dev;
1508
1423 for (i = 0; i < j; i++) { 1509 for (i = 0; i < j; i++) {
1424 struct fb_var_screeninfo *var; 1510 struct fb_var_screeninfo *var;
1425 const struct fb_videomode *lcd_cfg, *max_cfg = NULL; 1511 const struct fb_videomode *lcd_cfg, *max_cfg = NULL;
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index f16cb5645a13..aeed6687e6a7 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -39,6 +39,7 @@ struct sh_mobile_lcdc_chan {
39 int use_count; 39 int use_count;
40 int blank_status; 40 int blank_status;
41 struct mutex open_lock; /* protects the use counter */ 41 struct mutex open_lock; /* protects the use counter */
42 int meram_enabled;
42}; 43};
43 44
44#endif 45#endif
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
new file mode 100644
index 000000000000..9170c82b495c
--- /dev/null
+++ b/drivers/video/sh_mobile_meram.c
@@ -0,0 +1,567 @@
1/*
2 * SuperH Mobile MERAM Driver for SuperH Mobile LCDC Driver
3 *
4 * Copyright (c) 2011 Damian Hobson-Garcia <dhobsong@igel.co.jp>
5 * Takanari Hayama <taki@igel.co.jp>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/device.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/platform_device.h>
18
19#include "sh_mobile_meram.h"
20
21/* meram registers */
22#define MExxCTL 0x0
23#define MExxBSIZE 0x4
24#define MExxMNCF 0x8
25#define MExxSARA 0x10
26#define MExxSARB 0x14
27#define MExxSBSIZE 0x18
28
29#define MERAM_MExxCTL_VAL(ctl, next_icb, addr) \
30 ((ctl) | (((next_icb) & 0x1f) << 11) | (((addr) & 0x7ff) << 16))
31#define MERAM_MExxBSIZE_VAL(a, b, c) \
32 (((a) << 28) | ((b) << 16) | (c))
33
34#define MEVCR1 0x4
35#define MEACTS 0x10
36#define MEQSEL1 0x40
37#define MEQSEL2 0x44
38
39/* settings */
40#define MERAM_SEC_LINE 15
41#define MERAM_LINE_WIDTH 2048
42
43/*
44 * MERAM/ICB access functions
45 */
46
47#define MERAM_ICB_OFFSET(base, idx, off) \
48 ((base) + (0x400 + ((idx) * 0x20) + (off)))
49
50static inline void meram_write_icb(void __iomem *base, int idx, int off,
51 unsigned long val)
52{
53 iowrite32(val, MERAM_ICB_OFFSET(base, idx, off));
54}
55
56static inline unsigned long meram_read_icb(void __iomem *base, int idx, int off)
57{
58 return ioread32(MERAM_ICB_OFFSET(base, idx, off));
59}
60
61static inline void meram_write_reg(void __iomem *base, int off,
62 unsigned long val)
63{
64 iowrite32(val, base + off);
65}
66
67static inline unsigned long meram_read_reg(void __iomem *base, int off)
68{
69 return ioread32(base + off);
70}
71
72/*
73 * register ICB
74 */
75
76#define MERAM_CACHE_START(p) ((p) >> 16)
77#define MERAM_CACHE_END(p) ((p) & 0xffff)
78#define MERAM_CACHE_SET(o, s) ((((o) & 0xffff) << 16) | \
79 (((o) + (s) - 1) & 0xffff))
80
81/*
82 * check if there's no overlaps in MERAM allocation.
83 */
84
85static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv,
86 struct sh_mobile_meram_icb *new)
87{
88 int i;
89 int used_start, used_end, meram_start, meram_end;
90
91 /* valid ICB? */
92 if (new->marker_icb & ~0x1f || new->cache_icb & ~0x1f)
93 return 1;
94
95 if (test_bit(new->marker_icb, &priv->used_icb) ||
96 test_bit(new->cache_icb, &priv->used_icb))
97 return 1;
98
99 for (i = 0; i < priv->used_meram_cache_regions; i++) {
100 used_start = MERAM_CACHE_START(priv->used_meram_cache[i]);
101 used_end = MERAM_CACHE_END(priv->used_meram_cache[i]);
102 meram_start = new->meram_offset;
103 meram_end = new->meram_offset + new->meram_size;
104
105 if ((meram_start >= used_start && meram_start < used_end) ||
106 (meram_end > used_start && meram_end < used_end))
107 return 1;
108 }
109
110 return 0;
111}
112
113/*
114 * mark the specified ICB as used
115 */
116
117static inline void meram_mark(struct sh_mobile_meram_priv *priv,
118 struct sh_mobile_meram_icb *new)
119{
120 int n;
121
122 if (new->marker_icb < 0 || new->cache_icb < 0)
123 return;
124
125 __set_bit(new->marker_icb, &priv->used_icb);
126 __set_bit(new->cache_icb, &priv->used_icb);
127
128 n = priv->used_meram_cache_regions;
129
130 priv->used_meram_cache[n] = MERAM_CACHE_SET(new->meram_offset,
131 new->meram_size);
132
133 priv->used_meram_cache_regions++;
134}
135
136/*
137 * unmark the specified ICB as used
138 */
139
140static inline void meram_unmark(struct sh_mobile_meram_priv *priv,
141 struct sh_mobile_meram_icb *icb)
142{
143 int i;
144 unsigned long pattern;
145
146 if (icb->marker_icb < 0 || icb->cache_icb < 0)
147 return;
148
149 __clear_bit(icb->marker_icb, &priv->used_icb);
150 __clear_bit(icb->cache_icb, &priv->used_icb);
151
152 pattern = MERAM_CACHE_SET(icb->meram_offset, icb->meram_size);
153 for (i = 0; i < priv->used_meram_cache_regions; i++) {
154 if (priv->used_meram_cache[i] == pattern) {
155 while (i < priv->used_meram_cache_regions - 1) {
156 priv->used_meram_cache[i] =
157 priv->used_meram_cache[i + 1] ;
158 i++;
159 }
160 priv->used_meram_cache[i] = 0;
161 priv->used_meram_cache_regions--;
162 break;
163 }
164 }
165}
166
167/*
168 * is this a YCbCr(NV12, NV16 or NV24) colorspace
169 */
170static inline int is_nvcolor(int cspace)
171{
172 if (cspace == SH_MOBILE_MERAM_PF_NV ||
173 cspace == SH_MOBILE_MERAM_PF_NV24)
174 return 1;
175 return 0;
176}
177
178/*
179 * set the next address to fetch
180 */
181static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
182 struct sh_mobile_meram_cfg *cfg,
183 unsigned long base_addr_y,
184 unsigned long base_addr_c)
185{
186 unsigned long target;
187
188 target = (cfg->current_reg) ? MExxSARA : MExxSARB;
189 cfg->current_reg ^= 1;
190
191 /* set the next address to fetch */
192 meram_write_icb(priv->base, cfg->icb[0].cache_icb, target,
193 base_addr_y);
194 meram_write_icb(priv->base, cfg->icb[0].marker_icb, target,
195 base_addr_y + cfg->icb[0].cache_unit);
196
197 if (is_nvcolor(cfg->pixelformat)) {
198 meram_write_icb(priv->base, cfg->icb[1].cache_icb, target,
199 base_addr_c);
200 meram_write_icb(priv->base, cfg->icb[1].marker_icb, target,
201 base_addr_c + cfg->icb[1].cache_unit);
202 }
203}
204
205/*
206 * get the next ICB address
207 */
208static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
209 struct sh_mobile_meram_cfg *cfg,
210 unsigned long *icb_addr_y,
211 unsigned long *icb_addr_c)
212{
213 unsigned long icb_offset;
214
215 if (pdata->addr_mode == SH_MOBILE_MERAM_MODE0)
216 icb_offset = 0x80000000 | (cfg->current_reg << 29);
217 else
218 icb_offset = 0xc0000000 | (cfg->current_reg << 23);
219
220 *icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
221 if ((*icb_addr_c) && is_nvcolor(cfg->pixelformat))
222 *icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
223}
224
225#define MERAM_CALC_BYTECOUNT(x, y) \
226 (((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
227
228/*
229 * initialize MERAM
230 */
231
232static int meram_init(struct sh_mobile_meram_priv *priv,
233 struct sh_mobile_meram_icb *icb,
234 int xres, int yres, int *out_pitch)
235{
236 unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
237 unsigned long bnm;
238 int lcdc_pitch, xpitch, line_cnt;
239 int save_lines;
240
241 /* adjust pitch to 1024, 2048, 4096 or 8192 */
242 lcdc_pitch = (xres - 1) | 1023;
243 lcdc_pitch = lcdc_pitch | (lcdc_pitch >> 1);
244 lcdc_pitch = lcdc_pitch | (lcdc_pitch >> 2);
245 lcdc_pitch += 1;
246
247 /* derive settings */
248 if (lcdc_pitch == 8192 && yres >= 1024) {
249 lcdc_pitch = xpitch = MERAM_LINE_WIDTH;
250 line_cnt = total_byte_count >> 11;
251 *out_pitch = xres;
252 save_lines = (icb->meram_size / 16 / MERAM_SEC_LINE);
253 save_lines *= MERAM_SEC_LINE;
254 } else {
255 xpitch = xres;
256 line_cnt = yres;
257 *out_pitch = lcdc_pitch;
258 save_lines = icb->meram_size / (lcdc_pitch >> 10) / 2;
259 save_lines &= 0xff;
260 }
261 bnm = (save_lines - 1) << 16;
262
263 /* TODO: we better to check if we have enough MERAM buffer size */
264
265 /* set up ICB */
266 meram_write_icb(priv->base, icb->cache_icb, MExxBSIZE,
267 MERAM_MExxBSIZE_VAL(0x0, line_cnt - 1, xpitch - 1));
268 meram_write_icb(priv->base, icb->marker_icb, MExxBSIZE,
269 MERAM_MExxBSIZE_VAL(0xf, line_cnt - 1, xpitch - 1));
270
271 meram_write_icb(priv->base, icb->cache_icb, MExxMNCF, bnm);
272 meram_write_icb(priv->base, icb->marker_icb, MExxMNCF, bnm);
273
274 meram_write_icb(priv->base, icb->cache_icb, MExxSBSIZE, xpitch);
275 meram_write_icb(priv->base, icb->marker_icb, MExxSBSIZE, xpitch);
276
277 /* save a cache unit size */
278 icb->cache_unit = xres * save_lines;
279
280 /*
281 * Set MERAM for framebuffer
282 *
283 * 0x70f: WD = 0x3, WS=0x1, CM=0x1, MD=FB mode
284 * we also chain the cache_icb and the marker_icb.
285 * we also split the allocated MERAM buffer between two ICBs.
286 */
287 meram_write_icb(priv->base, icb->cache_icb, MExxCTL,
288 MERAM_MExxCTL_VAL(0x70f, icb->marker_icb,
289 icb->meram_offset));
290 meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
291 MERAM_MExxCTL_VAL(0x70f, icb->cache_icb,
292 icb->meram_offset +
293 icb->meram_size / 2));
294
295 return 0;
296}
297
298static void meram_deinit(struct sh_mobile_meram_priv *priv,
299 struct sh_mobile_meram_icb *icb)
300{
301 /* disable ICB */
302 meram_write_icb(priv->base, icb->cache_icb, MExxCTL, 0);
303 meram_write_icb(priv->base, icb->marker_icb, MExxCTL, 0);
304 icb->cache_unit = 0;
305}
306
307/*
308 * register the ICB
309 */
310
311static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
312 struct sh_mobile_meram_cfg *cfg,
313 int xres, int yres, int pixelformat,
314 unsigned long base_addr_y,
315 unsigned long base_addr_c,
316 unsigned long *icb_addr_y,
317 unsigned long *icb_addr_c,
318 int *pitch)
319{
320 struct platform_device *pdev;
321 struct sh_mobile_meram_priv *priv;
322 int n, out_pitch;
323 int error = 0;
324
325 if (!pdata || !pdata->priv || !pdata->pdev || !cfg)
326 return -EINVAL;
327
328 if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
329 pixelformat != SH_MOBILE_MERAM_PF_NV24 &&
330 pixelformat != SH_MOBILE_MERAM_PF_RGB)
331 return -EINVAL;
332
333 priv = pdata->priv;
334 pdev = pdata->pdev;
335
336 dev_dbg(&pdev->dev, "registering %dx%d (%s) (y=%08lx, c=%08lx)",
337 xres, yres, (!pixelformat) ? "yuv" : "rgb",
338 base_addr_y, base_addr_c);
339
340 mutex_lock(&priv->lock);
341
342 /* we can't handle wider than 8192px */
343 if (xres > 8192) {
344 dev_err(&pdev->dev, "width exceeding the limit (> 8192).");
345 error = -EINVAL;
346 goto err;
347 }
348
349 if (priv->used_meram_cache_regions + 2 > SH_MOBILE_MERAM_ICB_NUM) {
350 dev_err(&pdev->dev, "no more ICB available.");
351 error = -EINVAL;
352 goto err;
353 }
354
355 /* do we have at least one ICB config? */
356 if (cfg->icb[0].marker_icb < 0 || cfg->icb[0].cache_icb < 0) {
357 dev_err(&pdev->dev, "at least one ICB is required.");
358 error = -EINVAL;
359 goto err;
360 }
361
362 /* make sure that there's no overlaps */
363 if (meram_check_overlap(priv, &cfg->icb[0])) {
364 dev_err(&pdev->dev, "conflicting config detected.");
365 error = -EINVAL;
366 goto err;
367 }
368 n = 1;
369
370 /* do the same if we have the second ICB set */
371 if (cfg->icb[1].marker_icb >= 0 && cfg->icb[1].cache_icb >= 0) {
372 if (meram_check_overlap(priv, &cfg->icb[1])) {
373 dev_err(&pdev->dev, "conflicting config detected.");
374 error = -EINVAL;
375 goto err;
376 }
377 n = 2;
378 }
379
380 if (is_nvcolor(pixelformat) && n != 2) {
381 dev_err(&pdev->dev, "requires two ICB sets for planar Y/C.");
382 error = -EINVAL;
383 goto err;
384 }
385
386 /* we now register the ICB */
387 cfg->pixelformat = pixelformat;
388 meram_mark(priv, &cfg->icb[0]);
389 if (is_nvcolor(pixelformat))
390 meram_mark(priv, &cfg->icb[1]);
391
392 /* initialize MERAM */
393 meram_init(priv, &cfg->icb[0], xres, yres, &out_pitch);
394 *pitch = out_pitch;
395 if (pixelformat == SH_MOBILE_MERAM_PF_NV)
396 meram_init(priv, &cfg->icb[1], xres, (yres + 1) / 2,
397 &out_pitch);
398 else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
399 meram_init(priv, &cfg->icb[1], 2 * xres, (yres + 1) / 2,
400 &out_pitch);
401
402 cfg->current_reg = 1;
403 meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
404 meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);
405
406 dev_dbg(&pdev->dev, "registered - can access via y=%08lx, c=%08lx",
407 *icb_addr_y, *icb_addr_c);
408
409err:
410 mutex_unlock(&priv->lock);
411 return error;
412}
413
414static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata,
415 struct sh_mobile_meram_cfg *cfg)
416{
417 struct sh_mobile_meram_priv *priv;
418
419 if (!pdata || !pdata->priv || !cfg)
420 return -EINVAL;
421
422 priv = pdata->priv;
423
424 mutex_lock(&priv->lock);
425
426 /* deinit & unmark */
427 if (is_nvcolor(cfg->pixelformat)) {
428 meram_deinit(priv, &cfg->icb[1]);
429 meram_unmark(priv, &cfg->icb[1]);
430 }
431 meram_deinit(priv, &cfg->icb[0]);
432 meram_unmark(priv, &cfg->icb[0]);
433
434 mutex_unlock(&priv->lock);
435
436 return 0;
437}
438
439static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
440 struct sh_mobile_meram_cfg *cfg,
441 unsigned long base_addr_y,
442 unsigned long base_addr_c,
443 unsigned long *icb_addr_y,
444 unsigned long *icb_addr_c)
445{
446 struct sh_mobile_meram_priv *priv;
447
448 if (!pdata || !pdata->priv || !cfg)
449 return -EINVAL;
450
451 priv = pdata->priv;
452
453 mutex_lock(&priv->lock);
454
455 meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
456 meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);
457
458 mutex_unlock(&priv->lock);
459
460 return 0;
461}
462
463static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
464 .module = THIS_MODULE,
465 .meram_register = sh_mobile_meram_register,
466 .meram_unregister = sh_mobile_meram_unregister,
467 .meram_update = sh_mobile_meram_update,
468};
469
470/*
471 * initialize MERAM
472 */
473
474static int sh_mobile_meram_remove(struct platform_device *pdev);
475
476static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
477{
478 struct sh_mobile_meram_priv *priv;
479 struct sh_mobile_meram_info *pdata = pdev->dev.platform_data;
480 struct resource *res;
481 int error;
482
483 if (!pdata) {
484 dev_err(&pdev->dev, "no platform data defined\n");
485 return -EINVAL;
486 }
487
488 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
489 if (!res) {
490 dev_err(&pdev->dev, "cannot get platform resources\n");
491 return -ENOENT;
492 }
493
494 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
495 if (!priv) {
496 dev_err(&pdev->dev, "cannot allocate device data\n");
497 return -ENOMEM;
498 }
499
500 platform_set_drvdata(pdev, priv);
501
502 /* initialize private data */
503 mutex_init(&priv->lock);
504 priv->base = ioremap_nocache(res->start, resource_size(res));
505 if (!priv->base) {
506 dev_err(&pdev->dev, "ioremap failed\n");
507 error = -EFAULT;
508 goto err;
509 }
510 pdata->ops = &sh_mobile_meram_ops;
511 pdata->priv = priv;
512 pdata->pdev = pdev;
513
514 /* initialize ICB addressing mode */
515 if (pdata->addr_mode == SH_MOBILE_MERAM_MODE1)
516 meram_write_reg(priv->base, MEVCR1, 1 << 29);
517
518 dev_info(&pdev->dev, "sh_mobile_meram initialized.");
519
520 return 0;
521
522err:
523 sh_mobile_meram_remove(pdev);
524
525 return error;
526}
527
528
529static int sh_mobile_meram_remove(struct platform_device *pdev)
530{
531 struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
532
533 if (priv->base)
534 iounmap(priv->base);
535
536 mutex_destroy(&priv->lock);
537
538 kfree(priv);
539
540 return 0;
541}
542
543static struct platform_driver sh_mobile_meram_driver = {
544 .driver = {
545 .name = "sh_mobile_meram",
546 .owner = THIS_MODULE,
547 },
548 .probe = sh_mobile_meram_probe,
549 .remove = sh_mobile_meram_remove,
550};
551
552static int __init sh_mobile_meram_init(void)
553{
554 return platform_driver_register(&sh_mobile_meram_driver);
555}
556
557static void __exit sh_mobile_meram_exit(void)
558{
559 platform_driver_unregister(&sh_mobile_meram_driver);
560}
561
562module_init(sh_mobile_meram_init);
563module_exit(sh_mobile_meram_exit);
564
565MODULE_DESCRIPTION("SuperH Mobile MERAM driver");
566MODULE_AUTHOR("Damian Hobson-Garcia / Takanari Hayama");
567MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sh_mobile_meram.h b/drivers/video/sh_mobile_meram.h
new file mode 100644
index 000000000000..82c54fbce8bd
--- /dev/null
+++ b/drivers/video/sh_mobile_meram.h
@@ -0,0 +1,41 @@
1#ifndef __sh_mobile_meram_h__
2#define __sh_mobile_meram_h__
3
4#include <linux/mutex.h>
5#include <video/sh_mobile_meram.h>
6
7/*
8 * MERAM private
9 */
10
11#define MERAM_ICB_Y 0x1
12#define MERAM_ICB_C 0x2
13
14/* MERAM cache size */
15#define SH_MOBILE_MERAM_ICB_NUM 32
16
17#define SH_MOBILE_MERAM_CACHE_OFFSET(p) ((p) >> 16)
18#define SH_MOBILE_MERAM_CACHE_SIZE(p) ((p) & 0xffff)
19
20struct sh_mobile_meram_priv {
21 void __iomem *base;
22 struct mutex lock;
23 unsigned long used_icb;
24 int used_meram_cache_regions;
25 unsigned long used_meram_cache[SH_MOBILE_MERAM_ICB_NUM];
26};
27
28int sh_mobile_meram_alloc_icb(const struct sh_mobile_meram_cfg *cfg,
29 int xres,
30 int yres,
31 unsigned int base_addr,
32 int yuv_mode,
33 int *marker_icb,
34 int *out_pitch);
35
36void sh_mobile_meram_free_icb(int marker_icb);
37
38#define SH_MOBILE_MERAM_START(ind, ab) \
39 (0xC0000000 | ((ab & 0x1) << 23) | ((ind & 0x1F) << 24))
40
41#endif /* !__sh_mobile_meram_h__ */
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 56ef6b3a9851..87f0be1e78b5 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1625,22 +1625,22 @@ static int sm501fb_start(struct sm501fb_info *info,
1625 return 0; /* everything is setup */ 1625 return 0; /* everything is setup */
1626 1626
1627 err_mem_res: 1627 err_mem_res:
1628 release_resource(info->fbmem_res); 1628 release_mem_region(info->fbmem_res->start,
1629 kfree(info->fbmem_res); 1629 resource_size(info->fbmem_res));
1630 1630
1631 err_regs2d_map: 1631 err_regs2d_map:
1632 iounmap(info->regs2d); 1632 iounmap(info->regs2d);
1633 1633
1634 err_regs2d_res: 1634 err_regs2d_res:
1635 release_resource(info->regs2d_res); 1635 release_mem_region(info->regs2d_res->start,
1636 kfree(info->regs2d_res); 1636 resource_size(info->regs2d_res));
1637 1637
1638 err_regs_map: 1638 err_regs_map:
1639 iounmap(info->regs); 1639 iounmap(info->regs);
1640 1640
1641 err_regs_res: 1641 err_regs_res:
1642 release_resource(info->regs_res); 1642 release_mem_region(info->regs_res->start,
1643 kfree(info->regs_res); 1643 resource_size(info->regs_res));
1644 1644
1645 err_release: 1645 err_release:
1646 return ret; 1646 return ret;
@@ -1652,16 +1652,16 @@ static void sm501fb_stop(struct sm501fb_info *info)
1652 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 0); 1652 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 0);
1653 1653
1654 iounmap(info->fbmem); 1654 iounmap(info->fbmem);
1655 release_resource(info->fbmem_res); 1655 release_mem_region(info->fbmem_res->start,
1656 kfree(info->fbmem_res); 1656 resource_size(info->fbmem_res));
1657 1657
1658 iounmap(info->regs2d); 1658 iounmap(info->regs2d);
1659 release_resource(info->regs2d_res); 1659 release_mem_region(info->regs2d_res->start,
1660 kfree(info->regs2d_res); 1660 resource_size(info->regs2d_res));
1661 1661
1662 iounmap(info->regs); 1662 iounmap(info->regs);
1663 release_resource(info->regs_res); 1663 release_mem_region(info->regs_res->start,
1664 kfree(info->regs_res); 1664 resource_size(info->regs_res));
1665} 1665}
1666 1666
1667static int sm501fb_init_fb(struct fb_info *fb, 1667static int sm501fb_init_fb(struct fb_info *fb,
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 695066b5b2e6..52b0f3e8ccac 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -29,6 +29,7 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/prefetch.h> 30#include <linux/prefetch.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/prefetch.h>
32#include <video/udlfb.h> 33#include <video/udlfb.h>
33#include "edid.h" 34#include "edid.h"
34 35
@@ -1587,10 +1588,19 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1587 goto error; 1588 goto error;
1588 } 1589 }
1589 1590
1590 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) 1591 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
1591 device_create_file(info->dev, &fb_device_attrs[i]); 1592 retval = device_create_file(info->dev, &fb_device_attrs[i]);
1593 if (retval) {
1594 pr_err("device_create_file failed %d\n", retval);
1595 goto err_del_attrs;
1596 }
1597 }
1592 1598
1593 device_create_bin_file(info->dev, &edid_attr); 1599 retval = device_create_bin_file(info->dev, &edid_attr);
1600 if (retval) {
1601 pr_err("device_create_bin_file failed %d\n", retval);
1602 goto err_del_attrs;
1603 }
1594 1604
1595 pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution." 1605 pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
1596 " Using %dK framebuffer memory\n", info->node, 1606 " Using %dK framebuffer memory\n", info->node,
@@ -1599,6 +1609,10 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1599 info->fix.smem_len * 2 : info->fix.smem_len) >> 10); 1609 info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
1600 return 0; 1610 return 0;
1601 1611
1612err_del_attrs:
1613 for (i -= 1; i >= 0; i--)
1614 device_remove_file(info->dev, &fb_device_attrs[i]);
1615
1602error: 1616error:
1603 if (dev) { 1617 if (dev) {
1604 1618