aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-10-14 20:19:52 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-10-14 20:19:52 -0400
commitef26b7943c5821aaff1efc14c098840c49fe15c0 (patch)
treea91834ef396633c5c56a0597c2fc525e0684fc30 /drivers/video
parent07aaae44f5a3962c3a410a6dd7936dfa7dece2b9 (diff)
parent3e28189038bb831512cf4f8313e1aead97c3e63f (diff)
Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap/Kconfig29
-rw-r--r--drivers/video/omap/Makefile8
-rw-r--r--drivers/video/omap/lcd_2430sdp.c203
-rw-r--r--drivers/video/omap/lcd_apollon.c136
-rw-r--r--drivers/video/omap/lcd_h4.c117
-rw-r--r--drivers/video/omap/lcd_ldp.c201
-rw-r--r--drivers/video/omap/lcd_omap3beagle.c130
-rw-r--r--drivers/video/omap/lcd_omap3evm.c193
-rw-r--r--drivers/video/omap/lcd_overo.c180
-rw-r--r--drivers/video/omap2/displays/Kconfig28
-rw-r--r--drivers/video/omap2/displays/Makefile3
-rw-r--r--drivers/video/omap2/displays/panel-dvi.c363
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c113
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c747
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c594
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.h288
-rw-r--r--drivers/video/omap2/displays/panel-taal.c123
-rw-r--r--drivers/video/omap2/dss/Kconfig2
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/core.c4
-rw-r--r--drivers/video/omap2/dss/dispc.c1700
-rw-r--r--drivers/video/omap2/dss/dispc.h57
-rw-r--r--drivers/video/omap2/dss/display.c31
-rw-r--r--drivers/video/omap2/dss/dpi.c28
-rw-r--r--drivers/video/omap2/dss/dsi.c929
-rw-r--r--drivers/video/omap2/dss/dss.c18
-rw-r--r--drivers/video/omap2/dss/dss.h156
-rw-r--r--drivers/video/omap2/dss/dss_features.c130
-rw-r--r--drivers/video/omap2/dss/dss_features.h17
-rw-r--r--drivers/video/omap2/dss/hdmi.c1260
-rw-r--r--drivers/video/omap2/dss/hdmi_panel.c (renamed from drivers/video/omap2/dss/hdmi_omap4_panel.c)68
-rw-r--r--drivers/video/omap2/dss/manager.c191
-rw-r--r--drivers/video/omap2/dss/overlay.c122
-rw-r--r--drivers/video/omap2/dss/rfbi.c45
-rw-r--r--drivers/video/omap2/dss/sdi.c19
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h138
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c1239
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h (renamed from drivers/video/omap2/dss/hdmi.h)400
-rw-r--r--drivers/video/omap2/dss/venc.c27
-rw-r--r--drivers/video/omap2/omapfb/Kconfig2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c134
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c6
42 files changed, 5811 insertions, 4370 deletions
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 196fa2e7f438..84ff23208c25 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -9,35 +9,6 @@ config FB_OMAP
9 help 9 help
10 Frame buffer driver for OMAP based boards. 10 Frame buffer driver for OMAP based boards.
11 11
12config FB_OMAP_LCD_VGA
13 bool "Use LCD in VGA mode"
14 depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP
15 help
16 Set LCD resolution as VGA (640 X 480).
17 Default resolution without this option is QVGA(320 X 240).
18 Please take a look at drivers/video/omap/lcd_ldp.c file
19 for lcd driver code.
20choice
21 depends on FB_OMAP && MACH_OVERO
22 prompt "Screen resolution"
23 default FB_OMAP_079M3R
24 help
25 Selected desired screen resolution
26
27config FB_OMAP_031M3R
28 boolean "640 x 480 @ 60 Hz Reduced blanking"
29
30config FB_OMAP_048M3R
31 boolean "800 x 600 @ 60 Hz Reduced blanking"
32
33config FB_OMAP_079M3R
34 boolean "1024 x 768 @ 60 Hz Reduced blanking"
35
36config FB_OMAP_092M9R
37 boolean "1280 x 720 @ 60 Hz Reduced blanking"
38
39endchoice
40
41config FB_OMAP_LCDC_EXTERNAL 12config FB_OMAP_LCDC_EXTERNAL
42 bool "External LCD controller support" 13 bool "External LCD controller support"
43 depends on FB_OMAP 14 depends on FB_OMAP
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 25db55696e14..ef78550917ff 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -17,7 +17,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
17objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o 17objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
18 18
19objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o 19objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
20objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
21objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o 20objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
22objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o 21objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
23objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o 22objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
@@ -26,14 +25,7 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
26objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o 25objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
27objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o 26objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
28 27
29objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
30objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
31objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
32objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
33objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
34objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
35objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o 28objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
36objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
37objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o 29objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
38 30
39omapfb-objs := $(objs-yy) 31omapfb-objs := $(objs-yy)
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
deleted file mode 100644
index e3eccc9af78e..000000000000
--- a/drivers/video/omap/lcd_2430sdp.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/*
2 * LCD panel support for the TI 2430SDP board
3 *
4 * Copyright (C) 2007 MontaVista
5 * Author: Hunyue Yau <hyau@mvista.com>
6 *
7 * Derived from drivers/video/omap/lcd-apollon.c
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/delay.h>
27#include <linux/gpio.h>
28#include <linux/i2c/twl.h>
29
30#include <plat/mux.h>
31#include <asm/mach-types.h>
32
33#include "omapfb.h"
34
35#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
36#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
37#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24
38#define SDP3430_LCD_PANEL_ENABLE_GPIO 28
39
40static unsigned backlight_gpio;
41static unsigned enable_gpio;
42
43#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
44#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
45#define ENABLE_VAUX2_DEDICATED 0x09
46#define ENABLE_VAUX2_DEV_GRP 0x20
47#define ENABLE_VAUX3_DEDICATED 0x03
48#define ENABLE_VAUX3_DEV_GRP 0x20
49
50#define ENABLE_VPLL2_DEDICATED 0x05
51#define ENABLE_VPLL2_DEV_GRP 0xE0
52#define TWL4030_VPLL2_DEV_GRP 0x33
53#define TWL4030_VPLL2_DEDICATED 0x36
54
55#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
56
57
58static int sdp2430_panel_init(struct lcd_panel *panel,
59 struct omapfb_device *fbdev)
60{
61 if (machine_is_omap_3430sdp()) {
62 enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO;
63 backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
64 } else {
65 enable_gpio = SDP2430_LCD_PANEL_ENABLE_GPIO;
66 backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
67 }
68
69 gpio_request(enable_gpio, "LCD enable"); /* LCD panel */
70 gpio_request(backlight_gpio, "LCD bl"); /* LCD backlight */
71 gpio_direction_output(enable_gpio, 0);
72 gpio_direction_output(backlight_gpio, 0);
73
74 return 0;
75}
76
77static void sdp2430_panel_cleanup(struct lcd_panel *panel)
78{
79 gpio_free(backlight_gpio);
80 gpio_free(enable_gpio);
81}
82
83static int sdp2430_panel_enable(struct lcd_panel *panel)
84{
85 u8 ded_val, ded_reg;
86 u8 grp_val, grp_reg;
87
88 if (machine_is_omap_3430sdp()) {
89 ded_reg = TWL4030_VAUX3_DEDICATED;
90 ded_val = ENABLE_VAUX3_DEDICATED;
91 grp_reg = TWL4030_VAUX3_DEV_GRP;
92 grp_val = ENABLE_VAUX3_DEV_GRP;
93
94 if (omap_rev() > OMAP3430_REV_ES1_0) {
95 t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
96 TWL4030_VPLL2_DEDICATED);
97 t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
98 TWL4030_VPLL2_DEV_GRP);
99 }
100 } else {
101 ded_reg = TWL4030_VAUX2_DEDICATED;
102 ded_val = ENABLE_VAUX2_DEDICATED;
103 grp_reg = TWL4030_VAUX2_DEV_GRP;
104 grp_val = ENABLE_VAUX2_DEV_GRP;
105 }
106
107 gpio_set_value(enable_gpio, 1);
108 gpio_set_value(backlight_gpio, 1);
109
110 if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
111 return -EIO;
112 if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
113 return -EIO;
114
115 return 0;
116}
117
118static void sdp2430_panel_disable(struct lcd_panel *panel)
119{
120 gpio_set_value(enable_gpio, 0);
121 gpio_set_value(backlight_gpio, 0);
122 if (omap_rev() > OMAP3430_REV_ES1_0) {
123 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
124 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
125 msleep(4);
126 }
127}
128
129static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
130{
131 return 0;
132}
133
134struct lcd_panel sdp2430_panel = {
135 .name = "sdp2430",
136 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
137 OMAP_LCDC_INV_HSYNC,
138
139 .bpp = 16,
140 .data_lines = 16,
141 .x_res = 240,
142 .y_res = 320,
143 .hsw = 3, /* hsync_len (4) - 1 */
144 .hfp = 3, /* right_margin (4) - 1 */
145 .hbp = 39, /* left_margin (40) - 1 */
146 .vsw = 1, /* vsync_len (2) - 1 */
147 .vfp = 2, /* lower_margin */
148 .vbp = 7, /* upper_margin (8) - 1 */
149
150 .pixel_clock = LCD_PIXCLOCK_MAX,
151
152 .init = sdp2430_panel_init,
153 .cleanup = sdp2430_panel_cleanup,
154 .enable = sdp2430_panel_enable,
155 .disable = sdp2430_panel_disable,
156 .get_caps = sdp2430_panel_get_caps,
157};
158
159static int sdp2430_panel_probe(struct platform_device *pdev)
160{
161 omapfb_register_panel(&sdp2430_panel);
162 return 0;
163}
164
165static int sdp2430_panel_remove(struct platform_device *pdev)
166{
167 return 0;
168}
169
170static int sdp2430_panel_suspend(struct platform_device *pdev,
171 pm_message_t mesg)
172{
173 return 0;
174}
175
176static int sdp2430_panel_resume(struct platform_device *pdev)
177{
178 return 0;
179}
180
181struct platform_driver sdp2430_panel_driver = {
182 .probe = sdp2430_panel_probe,
183 .remove = sdp2430_panel_remove,
184 .suspend = sdp2430_panel_suspend,
185 .resume = sdp2430_panel_resume,
186 .driver = {
187 .name = "sdp2430_lcd",
188 .owner = THIS_MODULE,
189 },
190};
191
192static int __init sdp2430_panel_drv_init(void)
193{
194 return platform_driver_register(&sdp2430_panel_driver);
195}
196
197static void __exit sdp2430_panel_drv_exit(void)
198{
199 platform_driver_unregister(&sdp2430_panel_driver);
200}
201
202module_init(sdp2430_panel_drv_init);
203module_exit(sdp2430_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
deleted file mode 100644
index 10459d8bd9a0..000000000000
--- a/drivers/video/omap/lcd_apollon.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * LCD panel support for the Samsung OMAP2 Apollon board
3 *
4 * Copyright (C) 2005,2006 Samsung Electronics
5 * Author: Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * Derived from drivers/video/omap/lcd-h4.c
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26
27#include <mach/gpio.h>
28
29#include "omapfb.h"
30
31/* #define USE_35INCH_LCD 1 */
32
33static int apollon_panel_init(struct lcd_panel *panel,
34 struct omapfb_device *fbdev)
35{
36 return 0;
37}
38
39static void apollon_panel_cleanup(struct lcd_panel *panel)
40{
41}
42
43static int apollon_panel_enable(struct lcd_panel *panel)
44{
45 return 0;
46}
47
48static void apollon_panel_disable(struct lcd_panel *panel)
49{
50}
51
52static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
53{
54 return 0;
55}
56
57struct lcd_panel apollon_panel = {
58 .name = "apollon",
59 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
60 OMAP_LCDC_INV_HSYNC,
61
62 .bpp = 16,
63 .data_lines = 18,
64#ifdef USE_35INCH_LCD
65 .x_res = 240,
66 .y_res = 320,
67 .hsw = 2,
68 .hfp = 3,
69 .hbp = 9,
70 .vsw = 4,
71 .vfp = 3,
72 .vbp = 5,
73#else
74 .x_res = 480,
75 .y_res = 272,
76 .hsw = 41,
77 .hfp = 2,
78 .hbp = 2,
79 .vsw = 10,
80 .vfp = 2,
81 .vbp = 2,
82#endif
83 .pixel_clock = 6250,
84
85 .init = apollon_panel_init,
86 .cleanup = apollon_panel_cleanup,
87 .enable = apollon_panel_enable,
88 .disable = apollon_panel_disable,
89 .get_caps = apollon_panel_get_caps,
90};
91
92static int apollon_panel_probe(struct platform_device *pdev)
93{
94 omapfb_register_panel(&apollon_panel);
95 return 0;
96}
97
98static int apollon_panel_remove(struct platform_device *pdev)
99{
100 return 0;
101}
102
103static int apollon_panel_suspend(struct platform_device *pdev,
104 pm_message_t mesg)
105{
106 return 0;
107}
108
109static int apollon_panel_resume(struct platform_device *pdev)
110{
111 return 0;
112}
113
114struct platform_driver apollon_panel_driver = {
115 .probe = apollon_panel_probe,
116 .remove = apollon_panel_remove,
117 .suspend = apollon_panel_suspend,
118 .resume = apollon_panel_resume,
119 .driver = {
120 .name = "apollon_lcd",
121 .owner = THIS_MODULE,
122 },
123};
124
125static int __init apollon_panel_drv_init(void)
126{
127 return platform_driver_register(&apollon_panel_driver);
128}
129
130static void __exit apollon_panel_drv_exit(void)
131{
132 platform_driver_unregister(&apollon_panel_driver);
133}
134
135module_init(apollon_panel_drv_init);
136module_exit(apollon_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
deleted file mode 100644
index 03a06a982750..000000000000
--- a/drivers/video/omap/lcd_h4.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * LCD panel support for the TI OMAP H4 board
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Imre Deak <imre.deak@nokia.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/platform_device.h>
24
25#include "omapfb.h"
26
27static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
28{
29 return 0;
30}
31
32static void h4_panel_cleanup(struct lcd_panel *panel)
33{
34}
35
36static int h4_panel_enable(struct lcd_panel *panel)
37{
38 return 0;
39}
40
41static void h4_panel_disable(struct lcd_panel *panel)
42{
43}
44
45static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
46{
47 return 0;
48}
49
50static struct lcd_panel h4_panel = {
51 .name = "h4",
52 .config = OMAP_LCDC_PANEL_TFT,
53
54 .bpp = 16,
55 .data_lines = 16,
56 .x_res = 240,
57 .y_res = 320,
58 .pixel_clock = 6250,
59 .hsw = 15,
60 .hfp = 15,
61 .hbp = 60,
62 .vsw = 1,
63 .vfp = 1,
64 .vbp = 1,
65
66 .init = h4_panel_init,
67 .cleanup = h4_panel_cleanup,
68 .enable = h4_panel_enable,
69 .disable = h4_panel_disable,
70 .get_caps = h4_panel_get_caps,
71};
72
73static int h4_panel_probe(struct platform_device *pdev)
74{
75 omapfb_register_panel(&h4_panel);
76 return 0;
77}
78
79static int h4_panel_remove(struct platform_device *pdev)
80{
81 return 0;
82}
83
84static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
85{
86 return 0;
87}
88
89static int h4_panel_resume(struct platform_device *pdev)
90{
91 return 0;
92}
93
94static struct platform_driver h4_panel_driver = {
95 .probe = h4_panel_probe,
96 .remove = h4_panel_remove,
97 .suspend = h4_panel_suspend,
98 .resume = h4_panel_resume,
99 .driver = {
100 .name = "lcd_h4",
101 .owner = THIS_MODULE,
102 },
103};
104
105static int __init h4_panel_drv_init(void)
106{
107 return platform_driver_register(&h4_panel_driver);
108}
109
110static void __exit h4_panel_drv_cleanup(void)
111{
112 platform_driver_unregister(&h4_panel_driver);
113}
114
115module_init(h4_panel_drv_init);
116module_exit(h4_panel_drv_cleanup);
117
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
deleted file mode 100644
index 0f5952cae85e..000000000000
--- a/drivers/video/omap/lcd_ldp.c
+++ /dev/null
@@ -1,201 +0,0 @@
1/*
2 * LCD panel support for the TI LDP board
3 *
4 * Copyright (C) 2007 WindRiver
5 * Author: Stanley Miao <stanley.miao@windriver.com>
6 *
7 * Derived from drivers/video/omap/lcd-2430sdp.c
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/delay.h>
27#include <linux/i2c/twl.h>
28
29#include <mach/gpio.h>
30#include <plat/mux.h>
31#include <asm/mach-types.h>
32
33#include "omapfb.h"
34
35#define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES)
36#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
37
38#define LCD_PANEL_RESET_GPIO 55
39#define LCD_PANEL_QVGA_GPIO 56
40
41#ifdef CONFIG_FB_OMAP_LCD_VGA
42#define LCD_XRES 480
43#define LCD_YRES 640
44#define LCD_PIXCLOCK_MAX 41700
45#else
46#define LCD_XRES 240
47#define LCD_YRES 320
48#define LCD_PIXCLOCK_MAX 185186
49#endif
50
51#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
52#define ENABLE_VAUX2_DEDICATED 0x09
53#define ENABLE_VAUX2_DEV_GRP 0x20
54#define ENABLE_VAUX3_DEDICATED 0x03
55#define ENABLE_VAUX3_DEV_GRP 0x20
56
57#define ENABLE_VPLL2_DEDICATED 0x05
58#define ENABLE_VPLL2_DEV_GRP 0xE0
59#define TWL4030_VPLL2_DEV_GRP 0x33
60#define TWL4030_VPLL2_DEDICATED 0x36
61
62#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
63
64
65static int ldp_panel_init(struct lcd_panel *panel,
66 struct omapfb_device *fbdev)
67{
68 gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
69 gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
70 gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
71 gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
72
73 gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
74 gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
75 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
76 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
77
78#ifdef CONFIG_FB_OMAP_LCD_VGA
79 gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
80#else
81 gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
82#endif
83 gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
84
85 return 0;
86}
87
88static void ldp_panel_cleanup(struct lcd_panel *panel)
89{
90 gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
91 gpio_free(LCD_PANEL_ENABLE_GPIO);
92 gpio_free(LCD_PANEL_QVGA_GPIO);
93 gpio_free(LCD_PANEL_RESET_GPIO);
94}
95
96static int ldp_panel_enable(struct lcd_panel *panel)
97{
98 if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
99 TWL4030_VPLL2_DEDICATED))
100 return -EIO;
101 if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
102 TWL4030_VPLL2_DEV_GRP))
103 return -EIO;
104
105 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
106 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
107
108 if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
109 TWL4030_VAUX3_DEDICATED))
110 return -EIO;
111 if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
112 TWL4030_VAUX3_DEV_GRP))
113 return -EIO;
114
115 return 0;
116}
117
118static void ldp_panel_disable(struct lcd_panel *panel)
119{
120 gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
121 gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
122
123 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
124 t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
125 msleep(4);
126}
127
128static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
129{
130 return 0;
131}
132
133struct lcd_panel ldp_panel = {
134 .name = "ldp",
135 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
136 OMAP_LCDC_INV_HSYNC,
137
138 .bpp = 16,
139 .data_lines = 18,
140 .x_res = LCD_XRES,
141 .y_res = LCD_YRES,
142 .hsw = 3, /* hsync_len (4) - 1 */
143 .hfp = 3, /* right_margin (4) - 1 */
144 .hbp = 39, /* left_margin (40) - 1 */
145 .vsw = 1, /* vsync_len (2) - 1 */
146 .vfp = 2, /* lower_margin */
147 .vbp = 7, /* upper_margin (8) - 1 */
148
149 .pixel_clock = LCD_PIXCLOCK_MAX,
150
151 .init = ldp_panel_init,
152 .cleanup = ldp_panel_cleanup,
153 .enable = ldp_panel_enable,
154 .disable = ldp_panel_disable,
155 .get_caps = ldp_panel_get_caps,
156};
157
158static int ldp_panel_probe(struct platform_device *pdev)
159{
160 omapfb_register_panel(&ldp_panel);
161 return 0;
162}
163
164static int ldp_panel_remove(struct platform_device *pdev)
165{
166 return 0;
167}
168
169static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
170{
171 return 0;
172}
173
174static int ldp_panel_resume(struct platform_device *pdev)
175{
176 return 0;
177}
178
179struct platform_driver ldp_panel_driver = {
180 .probe = ldp_panel_probe,
181 .remove = ldp_panel_remove,
182 .suspend = ldp_panel_suspend,
183 .resume = ldp_panel_resume,
184 .driver = {
185 .name = "ldp_lcd",
186 .owner = THIS_MODULE,
187 },
188};
189
190static int __init ldp_panel_drv_init(void)
191{
192 return platform_driver_register(&ldp_panel_driver);
193}
194
195static void __exit ldp_panel_drv_exit(void)
196{
197 platform_driver_unregister(&ldp_panel_driver);
198}
199
200module_init(ldp_panel_drv_init);
201module_exit(ldp_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
deleted file mode 100644
index d7c6c3e0afc6..000000000000
--- a/drivers/video/omap/lcd_omap3beagle.c
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 * LCD panel support for the TI OMAP3 Beagle board
3 *
4 * Author: Koen Kooi <koen@openembedded.org>
5 *
6 * Derived from drivers/video/omap/lcd-omap3evm.c
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 as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
26#include <linux/i2c/twl.h>
27
28#include <asm/mach-types.h>
29
30#include "omapfb.h"
31
32#define LCD_PANEL_ENABLE_GPIO 170
33
34static int omap3beagle_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev)
36{
37 gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
38 return 0;
39}
40
41static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
42{
43 gpio_free(LCD_PANEL_ENABLE_GPIO);
44}
45
46static int omap3beagle_panel_enable(struct lcd_panel *panel)
47{
48 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
49 return 0;
50}
51
52static void omap3beagle_panel_disable(struct lcd_panel *panel)
53{
54 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
55}
56
57static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
58{
59 return 0;
60}
61
62struct lcd_panel omap3beagle_panel = {
63 .name = "omap3beagle",
64 .config = OMAP_LCDC_PANEL_TFT,
65
66 .bpp = 16,
67 .data_lines = 24,
68 .x_res = 1024,
69 .y_res = 768,
70 .hsw = 3, /* hsync_len (4) - 1 */
71 .hfp = 3, /* right_margin (4) - 1 */
72 .hbp = 39, /* left_margin (40) - 1 */
73 .vsw = 1, /* vsync_len (2) - 1 */
74 .vfp = 2, /* lower_margin */
75 .vbp = 7, /* upper_margin (8) - 1 */
76
77 .pixel_clock = 64000,
78
79 .init = omap3beagle_panel_init,
80 .cleanup = omap3beagle_panel_cleanup,
81 .enable = omap3beagle_panel_enable,
82 .disable = omap3beagle_panel_disable,
83 .get_caps = omap3beagle_panel_get_caps,
84};
85
86static int omap3beagle_panel_probe(struct platform_device *pdev)
87{
88 omapfb_register_panel(&omap3beagle_panel);
89 return 0;
90}
91
92static int omap3beagle_panel_remove(struct platform_device *pdev)
93{
94 return 0;
95}
96
97static int omap3beagle_panel_suspend(struct platform_device *pdev,
98 pm_message_t mesg)
99{
100 return 0;
101}
102
103static int omap3beagle_panel_resume(struct platform_device *pdev)
104{
105 return 0;
106}
107
108struct platform_driver omap3beagle_panel_driver = {
109 .probe = omap3beagle_panel_probe,
110 .remove = omap3beagle_panel_remove,
111 .suspend = omap3beagle_panel_suspend,
112 .resume = omap3beagle_panel_resume,
113 .driver = {
114 .name = "omap3beagle_lcd",
115 .owner = THIS_MODULE,
116 },
117};
118
119static int __init omap3beagle_panel_drv_init(void)
120{
121 return platform_driver_register(&omap3beagle_panel_driver);
122}
123
124static void __exit omap3beagle_panel_drv_exit(void)
125{
126 platform_driver_unregister(&omap3beagle_panel_driver);
127}
128
129module_init(omap3beagle_panel_drv_init);
130module_exit(omap3beagle_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
deleted file mode 100644
index 06840da0b094..000000000000
--- a/drivers/video/omap/lcd_omap3evm.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/*
2 * LCD panel support for the TI OMAP3 EVM board
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * Derived from drivers/video/omap/lcd-apollon.c
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 as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
26#include <linux/i2c/twl.h>
27
28#include <plat/mux.h>
29#include <asm/mach-types.h>
30
31#include "omapfb.h"
32
33#define LCD_PANEL_ENABLE_GPIO 153
34#define LCD_PANEL_LR 2
35#define LCD_PANEL_UD 3
36#define LCD_PANEL_INI 152
37#define LCD_PANEL_QVGA 154
38#define LCD_PANEL_RESB 155
39
40#define ENABLE_VDAC_DEDICATED 0x03
41#define ENABLE_VDAC_DEV_GRP 0x20
42#define ENABLE_VPLL2_DEDICATED 0x05
43#define ENABLE_VPLL2_DEV_GRP 0xE0
44
45#define TWL_LED_LEDEN 0x00
46#define TWL_PWMA_PWMAON 0x00
47#define TWL_PWMA_PWMAOFF 0x01
48
49static unsigned int bklight_level;
50
51static int omap3evm_panel_init(struct lcd_panel *panel,
52 struct omapfb_device *fbdev)
53{
54 gpio_request(LCD_PANEL_LR, "LCD lr");
55 gpio_request(LCD_PANEL_UD, "LCD ud");
56 gpio_request(LCD_PANEL_INI, "LCD ini");
57 gpio_request(LCD_PANEL_RESB, "LCD resb");
58 gpio_request(LCD_PANEL_QVGA, "LCD qvga");
59
60 gpio_direction_output(LCD_PANEL_RESB, 1);
61 gpio_direction_output(LCD_PANEL_INI, 1);
62 gpio_direction_output(LCD_PANEL_QVGA, 0);
63 gpio_direction_output(LCD_PANEL_LR, 1);
64 gpio_direction_output(LCD_PANEL_UD, 1);
65
66 twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
67 twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
68 twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
69 bklight_level = 100;
70
71 return 0;
72}
73
74static void omap3evm_panel_cleanup(struct lcd_panel *panel)
75{
76 gpio_free(LCD_PANEL_QVGA);
77 gpio_free(LCD_PANEL_RESB);
78 gpio_free(LCD_PANEL_INI);
79 gpio_free(LCD_PANEL_UD);
80 gpio_free(LCD_PANEL_LR);
81}
82
83static int omap3evm_panel_enable(struct lcd_panel *panel)
84{
85 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
86 return 0;
87}
88
89static void omap3evm_panel_disable(struct lcd_panel *panel)
90{
91 gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
92}
93
94static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
95{
96 return 0;
97}
98
99static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
100 unsigned int level)
101{
102 u8 c;
103 if ((level >= 0) && (level <= 100)) {
104 c = (125 * (100 - level)) / 100 + 2;
105 twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
106 bklight_level = level;
107 }
108 return 0;
109}
110
111static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
112{
113 return bklight_level;
114}
115
116static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
117{
118 return 100;
119}
120
121struct lcd_panel omap3evm_panel = {
122 .name = "omap3evm",
123 .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
124 OMAP_LCDC_INV_HSYNC,
125
126 .bpp = 16,
127 .data_lines = 18,
128 .x_res = 480,
129 .y_res = 640,
130 .hsw = 3, /* hsync_len (4) - 1 */
131 .hfp = 3, /* right_margin (4) - 1 */
132 .hbp = 39, /* left_margin (40) - 1 */
133 .vsw = 1, /* vsync_len (2) - 1 */
134 .vfp = 2, /* lower_margin */
135 .vbp = 7, /* upper_margin (8) - 1 */
136
137 .pixel_clock = 26000,
138
139 .init = omap3evm_panel_init,
140 .cleanup = omap3evm_panel_cleanup,
141 .enable = omap3evm_panel_enable,
142 .disable = omap3evm_panel_disable,
143 .get_caps = omap3evm_panel_get_caps,
144 .set_bklight_level = omap3evm_bklight_setlevel,
145 .get_bklight_level = omap3evm_bklight_getlevel,
146 .get_bklight_max = omap3evm_bklight_getmaxlevel,
147};
148
149static int omap3evm_panel_probe(struct platform_device *pdev)
150{
151 omapfb_register_panel(&omap3evm_panel);
152 return 0;
153}
154
155static int omap3evm_panel_remove(struct platform_device *pdev)
156{
157 return 0;
158}
159
160static int omap3evm_panel_suspend(struct platform_device *pdev,
161 pm_message_t mesg)
162{
163 return 0;
164}
165
166static int omap3evm_panel_resume(struct platform_device *pdev)
167{
168 return 0;
169}
170
171struct platform_driver omap3evm_panel_driver = {
172 .probe = omap3evm_panel_probe,
173 .remove = omap3evm_panel_remove,
174 .suspend = omap3evm_panel_suspend,
175 .resume = omap3evm_panel_resume,
176 .driver = {
177 .name = "omap3evm_lcd",
178 .owner = THIS_MODULE,
179 },
180};
181
182static int __init omap3evm_panel_drv_init(void)
183{
184 return platform_driver_register(&omap3evm_panel_driver);
185}
186
187static void __exit omap3evm_panel_drv_exit(void)
188{
189 platform_driver_unregister(&omap3evm_panel_driver);
190}
191
192module_init(omap3evm_panel_drv_init);
193module_exit(omap3evm_panel_drv_exit);
diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
deleted file mode 100644
index 564933ffac6e..000000000000
--- a/drivers/video/omap/lcd_overo.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/*
2 * LCD panel support for the Gumstix Overo
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c/twl.h>
25
26#include <mach/gpio.h>
27#include <plat/mux.h>
28#include <asm/mach-types.h>
29
30#include "omapfb.h"
31
32#define LCD_ENABLE 144
33
34static int overo_panel_init(struct lcd_panel *panel,
35 struct omapfb_device *fbdev)
36{
37 if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") == 0) &&
38 (gpio_direction_output(LCD_ENABLE, 1) == 0))
39 gpio_export(LCD_ENABLE, 0);
40 else
41 printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
42
43 return 0;
44}
45
46static void overo_panel_cleanup(struct lcd_panel *panel)
47{
48 gpio_free(LCD_ENABLE);
49}
50
51static int overo_panel_enable(struct lcd_panel *panel)
52{
53 gpio_set_value(LCD_ENABLE, 1);
54 return 0;
55}
56
57static void overo_panel_disable(struct lcd_panel *panel)
58{
59 gpio_set_value(LCD_ENABLE, 0);
60}
61
62static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
63{
64 return 0;
65}
66
67struct lcd_panel overo_panel = {
68 .name = "overo",
69 .config = OMAP_LCDC_PANEL_TFT,
70 .bpp = 16,
71 .data_lines = 24,
72
73#if defined CONFIG_FB_OMAP_031M3R
74
75 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
76 .x_res = 640,
77 .y_res = 480,
78 .hfp = 48,
79 .hsw = 32,
80 .hbp = 80,
81 .vfp = 3,
82 .vsw = 4,
83 .vbp = 7,
84 .pixel_clock = 23500,
85
86#elif defined CONFIG_FB_OMAP_048M3R
87
88 /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
89 .x_res = 800,
90 .y_res = 600,
91 .hfp = 48,
92 .hsw = 32,
93 .hbp = 80,
94 .vfp = 3,
95 .vsw = 4,
96 .vbp = 11,
97 .pixel_clock = 35500,
98
99#elif defined CONFIG_FB_OMAP_079M3R
100
101 /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
102 .x_res = 1024,
103 .y_res = 768,
104 .hfp = 48,
105 .hsw = 32,
106 .hbp = 80,
107 .vfp = 3,
108 .vsw = 4,
109 .vbp = 15,
110 .pixel_clock = 56000,
111
112#elif defined CONFIG_FB_OMAP_092M9R
113
114 /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
115 .x_res = 1280,
116 .y_res = 720,
117 .hfp = 48,
118 .hsw = 32,
119 .hbp = 80,
120 .vfp = 3,
121 .vsw = 5,
122 .vbp = 13,
123 .pixel_clock = 64000,
124
125#else
126
127 /* use 640 x 480 if no config option */
128 /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
129 .x_res = 640,
130 .y_res = 480,
131 .hfp = 48,
132 .hsw = 32,
133 .hbp = 80,
134 .vfp = 3,
135 .vsw = 4,
136 .vbp = 7,
137 .pixel_clock = 23500,
138
139#endif
140
141 .init = overo_panel_init,
142 .cleanup = overo_panel_cleanup,
143 .enable = overo_panel_enable,
144 .disable = overo_panel_disable,
145 .get_caps = overo_panel_get_caps,
146};
147
148static int overo_panel_probe(struct platform_device *pdev)
149{
150 omapfb_register_panel(&overo_panel);
151 return 0;
152}
153
154static int overo_panel_remove(struct platform_device *pdev)
155{
156 /* omapfb does not have unregister_panel */
157 return 0;
158}
159
160static struct platform_driver overo_panel_driver = {
161 .probe = overo_panel_probe,
162 .remove = overo_panel_remove,
163 .driver = {
164 .name = "overo_lcd",
165 .owner = THIS_MODULE,
166 },
167};
168
169static int __init overo_panel_drv_init(void)
170{
171 return platform_driver_register(&overo_panel_driver);
172}
173
174static void __exit overo_panel_drv_exit(void)
175{
176 platform_driver_unregister(&overo_panel_driver);
177}
178
179module_init(overo_panel_drv_init);
180module_exit(overo_panel_drv_exit);
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 609a28073178..8d8e1fe1901c 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -10,6 +10,13 @@ config PANEL_GENERIC_DPI
10 Supports LCD Panel used in TI SDP3430 and EVM boards, 10 Supports LCD Panel used in TI SDP3430 and EVM boards,
11 OMAP3517 EVM boards and CM-T35. 11 OMAP3517 EVM boards and CM-T35.
12 12
13config PANEL_DVI
14 tristate "DVI output"
15 depends on OMAP2_DSS_DPI
16 help
17 Driver for external monitors, connected via DVI. The driver uses i2c
18 to read EDID information from the monitor.
19
13config PANEL_LGPHILIPS_LB035Q02 20config PANEL_LGPHILIPS_LB035Q02
14 tristate "LG.Philips LB035Q02 LCD Panel" 21 tristate "LG.Philips LB035Q02 LCD Panel"
15 depends on OMAP2_DSS_DPI && SPI 22 depends on OMAP2_DSS_DPI && SPI
@@ -19,20 +26,30 @@ config PANEL_LGPHILIPS_LB035Q02
19config PANEL_SHARP_LS037V7DW01 26config PANEL_SHARP_LS037V7DW01
20 tristate "Sharp LS037V7DW01 LCD Panel" 27 tristate "Sharp LS037V7DW01 LCD Panel"
21 depends on OMAP2_DSS_DPI 28 depends on OMAP2_DSS_DPI
22 select BACKLIGHT_CLASS_DEVICE 29 depends on BACKLIGHT_CLASS_DEVICE
23 help 30 help
24 LCD Panel used in TI's SDP3430 and EVM boards 31 LCD Panel used in TI's SDP3430 and EVM boards
25 32
26config PANEL_NEC_NL8048HL11_01B 33config PANEL_NEC_NL8048HL11_01B
27 tristate "NEC NL8048HL11-01B Panel" 34 tristate "NEC NL8048HL11-01B Panel"
28 depends on OMAP2_DSS_DPI 35 depends on OMAP2_DSS_DPI
36 depends on SPI
37 depends on BACKLIGHT_CLASS_DEVICE
29 help 38 help
30 This NEC NL8048HL11-01B panel is TFT LCD 39 This NEC NL8048HL11-01B panel is TFT LCD
31 used in the Zoom2/3/3630 sdp boards. 40 used in the Zoom2/3/3630 sdp boards.
32 41
42config PANEL_PICODLP
43 tristate "TI PICO DLP mini-projector"
44 depends on OMAP2_DSS && I2C
45 help
46 A mini-projector used in TI's SDP4430 and EVM boards
47 For more info please visit http://www.dlp.com/projector/
48
33config PANEL_TAAL 49config PANEL_TAAL
34 tristate "Taal DSI Panel" 50 tristate "Taal DSI Panel"
35 depends on OMAP2_DSS_DSI 51 depends on OMAP2_DSS_DSI
52 depends on BACKLIGHT_CLASS_DEVICE
36 help 53 help
37 Taal DSI command mode panel from TPO. 54 Taal DSI command mode panel from TPO.
38 55
@@ -45,7 +62,14 @@ config PANEL_TPO_TD043MTEA1
45config PANEL_ACX565AKM 62config PANEL_ACX565AKM
46 tristate "ACX565AKM Panel" 63 tristate "ACX565AKM Panel"
47 depends on OMAP2_DSS_SDI && SPI 64 depends on OMAP2_DSS_SDI && SPI
48 select BACKLIGHT_CLASS_DEVICE 65 depends on BACKLIGHT_CLASS_DEVICE
49 help 66 help
50 This is the LCD panel used on Nokia N900 67 This is the LCD panel used on Nokia N900
68
69config PANEL_N8X0
70 tristate "N8X0 Panel"
71 depends on OMAP2_DSS_RFBI && SPI
72 depends on BACKLIGHT_CLASS_DEVICE
73 help
74 This is the LCD panel used on Nokia N8x0
51endmenu 75endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 0f601ab3abf4..fbfafc6eebb4 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,8 +1,11 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_DVI) += panel-dvi.o
2obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o 3obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
3obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 4obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
4obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 5obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
5 6
6obj-$(CONFIG_PANEL_TAAL) += panel-taal.o 7obj-$(CONFIG_PANEL_TAAL) += panel-taal.o
8obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o
7obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o 9obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
8obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o 10obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
11obj-$(CONFIG_PANEL_N8X0) += panel-n8x0.o
diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-dvi.c
new file mode 100644
index 000000000000..03eb14af33e0
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-dvi.c
@@ -0,0 +1,363 @@
1/*
2 * DVI output support
3 *
4 * Copyright (C) 2011 Texas Instruments Inc
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/slab.h>
22#include <video/omapdss.h>
23#include <linux/i2c.h>
24#include <drm/drm_edid.h>
25
26#include <video/omap-panel-dvi.h>
27
28static const struct omap_video_timings panel_dvi_default_timings = {
29 .x_res = 640,
30 .y_res = 480,
31
32 .pixel_clock = 23500,
33
34 .hfp = 48,
35 .hsw = 32,
36 .hbp = 80,
37
38 .vfp = 3,
39 .vsw = 4,
40 .vbp = 7,
41};
42
43struct panel_drv_data {
44 struct omap_dss_device *dssdev;
45
46 struct mutex lock;
47};
48
49static inline struct panel_dvi_platform_data
50*get_pdata(const struct omap_dss_device *dssdev)
51{
52 return dssdev->data;
53}
54
55static int panel_dvi_power_on(struct omap_dss_device *dssdev)
56{
57 struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
58 int r;
59
60 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
61 return 0;
62
63 r = omapdss_dpi_display_enable(dssdev);
64 if (r)
65 goto err0;
66
67 if (pdata->platform_enable) {
68 r = pdata->platform_enable(dssdev);
69 if (r)
70 goto err1;
71 }
72
73 return 0;
74err1:
75 omapdss_dpi_display_disable(dssdev);
76err0:
77 return r;
78}
79
80static void panel_dvi_power_off(struct omap_dss_device *dssdev)
81{
82 struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
83
84 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
85 return;
86
87 if (pdata->platform_disable)
88 pdata->platform_disable(dssdev);
89
90 omapdss_dpi_display_disable(dssdev);
91}
92
93static int panel_dvi_probe(struct omap_dss_device *dssdev)
94{
95 struct panel_drv_data *ddata;
96
97 ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
98 if (!ddata)
99 return -ENOMEM;
100
101 dssdev->panel.timings = panel_dvi_default_timings;
102 dssdev->panel.config = OMAP_DSS_LCD_TFT;
103
104 ddata->dssdev = dssdev;
105 mutex_init(&ddata->lock);
106
107 dev_set_drvdata(&dssdev->dev, ddata);
108
109 return 0;
110}
111
112static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
113{
114 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
115
116 mutex_lock(&ddata->lock);
117
118 dev_set_drvdata(&dssdev->dev, NULL);
119
120 mutex_unlock(&ddata->lock);
121
122 kfree(ddata);
123}
124
125static int panel_dvi_enable(struct omap_dss_device *dssdev)
126{
127 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
128 int r;
129
130 mutex_lock(&ddata->lock);
131
132 r = panel_dvi_power_on(dssdev);
133 if (r == 0)
134 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
135
136 mutex_unlock(&ddata->lock);
137
138 return r;
139}
140
141static void panel_dvi_disable(struct omap_dss_device *dssdev)
142{
143 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
144
145 mutex_lock(&ddata->lock);
146
147 panel_dvi_power_off(dssdev);
148
149 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
150
151 mutex_unlock(&ddata->lock);
152}
153
154static int panel_dvi_suspend(struct omap_dss_device *dssdev)
155{
156 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
157
158 mutex_lock(&ddata->lock);
159
160 panel_dvi_power_off(dssdev);
161
162 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
163
164 mutex_unlock(&ddata->lock);
165
166 return 0;
167}
168
169static int panel_dvi_resume(struct omap_dss_device *dssdev)
170{
171 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
172 int r;
173
174 mutex_lock(&ddata->lock);
175
176 r = panel_dvi_power_on(dssdev);
177 if (r == 0)
178 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
179
180 mutex_unlock(&ddata->lock);
181
182 return r;
183}
184
185static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
186 struct omap_video_timings *timings)
187{
188 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
189
190 mutex_lock(&ddata->lock);
191 dpi_set_timings(dssdev, timings);
192 mutex_unlock(&ddata->lock);
193}
194
195static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
196 struct omap_video_timings *timings)
197{
198 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
199
200 mutex_lock(&ddata->lock);
201 *timings = dssdev->panel.timings;
202 mutex_unlock(&ddata->lock);
203}
204
205static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
206 struct omap_video_timings *timings)
207{
208 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
209 int r;
210
211 mutex_lock(&ddata->lock);
212 r = dpi_check_timings(dssdev, timings);
213 mutex_unlock(&ddata->lock);
214
215 return r;
216}
217
218
219static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
220 unsigned char *buf, u16 count, u8 offset)
221{
222 int r, retries;
223
224 for (retries = 3; retries > 0; retries--) {
225 struct i2c_msg msgs[] = {
226 {
227 .addr = DDC_ADDR,
228 .flags = 0,
229 .len = 1,
230 .buf = &offset,
231 }, {
232 .addr = DDC_ADDR,
233 .flags = I2C_M_RD,
234 .len = count,
235 .buf = buf,
236 }
237 };
238
239 r = i2c_transfer(adapter, msgs, 2);
240 if (r == 2)
241 return 0;
242
243 if (r != -EAGAIN)
244 break;
245 }
246
247 return r < 0 ? r : -EIO;
248}
249
250static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
251 u8 *edid, int len)
252{
253 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
254 struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
255 struct i2c_adapter *adapter;
256 int r, l, bytes_read;
257
258 mutex_lock(&ddata->lock);
259
260 if (pdata->i2c_bus_num == 0) {
261 r = -ENODEV;
262 goto err;
263 }
264
265 adapter = i2c_get_adapter(pdata->i2c_bus_num);
266 if (!adapter) {
267 dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
268 pdata->i2c_bus_num);
269 r = -EINVAL;
270 goto err;
271 }
272
273 l = min(EDID_LENGTH, len);
274 r = panel_dvi_ddc_read(adapter, edid, l, 0);
275 if (r)
276 goto err;
277
278 bytes_read = l;
279
280 /* if there are extensions, read second block */
281 if (len > EDID_LENGTH && edid[0x7e] > 0) {
282 l = min(EDID_LENGTH, len - EDID_LENGTH);
283
284 r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH,
285 l, EDID_LENGTH);
286 if (r)
287 goto err;
288
289 bytes_read += l;
290 }
291
292 mutex_unlock(&ddata->lock);
293
294 return bytes_read;
295
296err:
297 mutex_unlock(&ddata->lock);
298 return r;
299}
300
301static bool panel_dvi_detect(struct omap_dss_device *dssdev)
302{
303 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
304 struct panel_dvi_platform_data *pdata = get_pdata(dssdev);
305 struct i2c_adapter *adapter;
306 unsigned char out;
307 int r;
308
309 mutex_lock(&ddata->lock);
310
311 if (pdata->i2c_bus_num == 0)
312 goto out;
313
314 adapter = i2c_get_adapter(pdata->i2c_bus_num);
315 if (!adapter)
316 goto out;
317
318 r = panel_dvi_ddc_read(adapter, &out, 1, 0);
319
320 mutex_unlock(&ddata->lock);
321
322 return r == 0;
323
324out:
325 mutex_unlock(&ddata->lock);
326 return true;
327}
328
329static struct omap_dss_driver panel_dvi_driver = {
330 .probe = panel_dvi_probe,
331 .remove = __exit_p(panel_dvi_remove),
332
333 .enable = panel_dvi_enable,
334 .disable = panel_dvi_disable,
335 .suspend = panel_dvi_suspend,
336 .resume = panel_dvi_resume,
337
338 .set_timings = panel_dvi_set_timings,
339 .get_timings = panel_dvi_get_timings,
340 .check_timings = panel_dvi_check_timings,
341
342 .read_edid = panel_dvi_read_edid,
343 .detect = panel_dvi_detect,
344
345 .driver = {
346 .name = "dvi",
347 .owner = THIS_MODULE,
348 },
349};
350
351static int __init panel_dvi_init(void)
352{
353 return omap_dss_register_driver(&panel_dvi_driver);
354}
355
356static void __exit panel_dvi_exit(void)
357{
358 omap_dss_unregister_driver(&panel_dvi_driver);
359}
360
361module_init(panel_dvi_init);
362module_exit(panel_dvi_exit);
363MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 9c90f75653fb..519c47d2057f 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -58,30 +58,6 @@ struct panel_config {
58 58
59/* Panel configurations */ 59/* Panel configurations */
60static struct panel_config generic_dpi_panels[] = { 60static struct panel_config generic_dpi_panels[] = {
61 /* Generic Panel */
62 {
63 {
64 .x_res = 640,
65 .y_res = 480,
66
67 .pixel_clock = 23500,
68
69 .hfp = 48,
70 .hsw = 32,
71 .hbp = 80,
72
73 .vfp = 3,
74 .vsw = 4,
75 .vbp = 7,
76 },
77 .acbi = 0x0,
78 .acb = 0x0,
79 .config = OMAP_DSS_LCD_TFT,
80 .power_on_delay = 0,
81 .power_off_delay = 0,
82 .name = "generic",
83 },
84
85 /* Sharp LQ043T1DG01 */ 61 /* Sharp LQ043T1DG01 */
86 { 62 {
87 { 63 {
@@ -232,6 +208,95 @@ static struct panel_config generic_dpi_panels[] = {
232 .power_off_delay = 0, 208 .power_off_delay = 0,
233 .name = "powertip_ph480272t", 209 .name = "powertip_ph480272t",
234 }, 210 },
211
212 /* Innolux AT070TN83 */
213 {
214 {
215 .x_res = 800,
216 .y_res = 480,
217
218 .pixel_clock = 40000,
219
220 .hsw = 48,
221 .hfp = 1,
222 .hbp = 1,
223
224 .vsw = 3,
225 .vfp = 12,
226 .vbp = 25,
227 },
228 .acbi = 0x0,
229 .acb = 0x28,
230 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
231 OMAP_DSS_LCD_IHS,
232 .power_on_delay = 0,
233 .power_off_delay = 0,
234 .name = "innolux_at070tn83",
235 },
236
237 /* NEC NL2432DR22-11B */
238 {
239 {
240 .x_res = 240,
241 .y_res = 320,
242
243 .pixel_clock = 5400,
244
245 .hsw = 3,
246 .hfp = 3,
247 .hbp = 39,
248
249 .vsw = 1,
250 .vfp = 2,
251 .vbp = 7,
252 },
253 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
254 OMAP_DSS_LCD_IHS,
255 .name = "nec_nl2432dr22-11b",
256 },
257
258 /* Unknown panel used in OMAP H4 */
259 {
260 {
261 .x_res = 240,
262 .y_res = 320,
263
264 .pixel_clock = 6250,
265
266 .hsw = 15,
267 .hfp = 15,
268 .hbp = 60,
269
270 .vsw = 1,
271 .vfp = 1,
272 .vbp = 1,
273 },
274 .config = OMAP_DSS_LCD_TFT,
275
276 .name = "h4",
277 },
278
279 /* Unknown panel used in Samsung OMAP2 Apollon */
280 {
281 {
282 .x_res = 480,
283 .y_res = 272,
284
285 .pixel_clock = 6250,
286
287 .hsw = 41,
288 .hfp = 2,
289 .hbp = 2,
290
291 .vsw = 10,
292 .vfp = 2,
293 .vbp = 2,
294 },
295 .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
296 OMAP_DSS_LCD_IHS,
297
298 .name = "apollon",
299 },
235}; 300};
236 301
237struct panel_drv_data { 302struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
new file mode 100644
index 000000000000..150e8bae35a1
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -0,0 +1,747 @@
1/* #define DEBUG */
2
3#include <linux/module.h>
4#include <linux/delay.h>
5#include <linux/slab.h>
6#include <linux/gpio.h>
7#include <linux/spi/spi.h>
8#include <linux/backlight.h>
9#include <linux/fb.h>
10
11#include <video/omapdss.h>
12#include <video/omap-panel-n8x0.h>
13
14#define BLIZZARD_REV_CODE 0x00
15#define BLIZZARD_CONFIG 0x02
16#define BLIZZARD_PLL_DIV 0x04
17#define BLIZZARD_PLL_LOCK_RANGE 0x06
18#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
19#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
20#define BLIZZARD_PLL_MODE 0x0c
21#define BLIZZARD_CLK_SRC 0x0e
22#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
23#define BLIZZARD_MEM_BANK0_STATUS 0x14
24#define BLIZZARD_PANEL_CONFIGURATION 0x28
25#define BLIZZARD_HDISP 0x2a
26#define BLIZZARD_HNDP 0x2c
27#define BLIZZARD_VDISP0 0x2e
28#define BLIZZARD_VDISP1 0x30
29#define BLIZZARD_VNDP 0x32
30#define BLIZZARD_HSW 0x34
31#define BLIZZARD_VSW 0x38
32#define BLIZZARD_DISPLAY_MODE 0x68
33#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
34#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
35#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
36#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
37#define BLIZZARD_POWER_SAVE 0xE6
38#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
39
40/* Data source select */
41/* For S1D13745 */
42#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
43#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
44#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
45#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
46/* For S1D13744 */
47#define BLIZZARD_SRC_WRITE_LCD 0x00
48#define BLIZZARD_SRC_BLT_LCD 0x06
49
50#define BLIZZARD_COLOR_RGB565 0x01
51#define BLIZZARD_COLOR_YUV420 0x09
52
53#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
54#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
55
56#define MIPID_CMD_READ_DISP_ID 0x04
57#define MIPID_CMD_READ_RED 0x06
58#define MIPID_CMD_READ_GREEN 0x07
59#define MIPID_CMD_READ_BLUE 0x08
60#define MIPID_CMD_READ_DISP_STATUS 0x09
61#define MIPID_CMD_RDDSDR 0x0F
62#define MIPID_CMD_SLEEP_IN 0x10
63#define MIPID_CMD_SLEEP_OUT 0x11
64#define MIPID_CMD_DISP_OFF 0x28
65#define MIPID_CMD_DISP_ON 0x29
66
67static struct panel_drv_data {
68 struct mutex lock;
69
70 struct omap_dss_device *dssdev;
71 struct spi_device *spidev;
72 struct backlight_device *bldev;
73
74 int blizzard_ver;
75} s_drv_data;
76
77
78static inline
79struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev)
80{
81 return dssdev->data;
82}
83
84static inline
85struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
86{
87 return &s_drv_data;
88}
89
90
91static inline void blizzard_cmd(u8 cmd)
92{
93 omap_rfbi_write_command(&cmd, 1);
94}
95
96static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
97{
98 omap_rfbi_write_command(&cmd, 1);
99 omap_rfbi_write_data(buf, len);
100}
101
102static inline void blizzard_read(u8 cmd, u8 *buf, int len)
103{
104 omap_rfbi_write_command(&cmd, 1);
105 omap_rfbi_read_data(buf, len);
106}
107
108static u8 blizzard_read_reg(u8 cmd)
109{
110 u8 data;
111 blizzard_read(cmd, &data, 1);
112 return data;
113}
114
115static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
116 int x, int y, int w, int h)
117{
118 struct panel_drv_data *ddata = get_drv_data(dssdev);
119 u8 tmp[18];
120 int x_end, y_end;
121
122 x_end = x + w - 1;
123 y_end = y + h - 1;
124
125 tmp[0] = x;
126 tmp[1] = x >> 8;
127 tmp[2] = y;
128 tmp[3] = y >> 8;
129 tmp[4] = x_end;
130 tmp[5] = x_end >> 8;
131 tmp[6] = y_end;
132 tmp[7] = y_end >> 8;
133
134 /* scaling? */
135 tmp[8] = x;
136 tmp[9] = x >> 8;
137 tmp[10] = y;
138 tmp[11] = y >> 8;
139 tmp[12] = x_end;
140 tmp[13] = x_end >> 8;
141 tmp[14] = y_end;
142 tmp[15] = y_end >> 8;
143
144 tmp[16] = BLIZZARD_COLOR_RGB565;
145
146 if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745)
147 tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
148 else
149 tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ?
150 BLIZZARD_SRC_WRITE_LCD :
151 BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
152
153 omap_rfbi_configure(dssdev, 16, 8);
154
155 blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
156
157 omap_rfbi_configure(dssdev, 16, 16);
158}
159
160static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
161 int wlen, u8 *rbuf, int rlen)
162{
163 struct spi_message m;
164 struct spi_transfer *x, xfer[4];
165 u16 w;
166 int r;
167
168 spi_message_init(&m);
169
170 memset(xfer, 0, sizeof(xfer));
171 x = &xfer[0];
172
173 cmd &= 0xff;
174 x->tx_buf = &cmd;
175 x->bits_per_word = 9;
176 x->len = 2;
177 spi_message_add_tail(x, &m);
178
179 if (wlen) {
180 x++;
181 x->tx_buf = wbuf;
182 x->len = wlen;
183 x->bits_per_word = 9;
184 spi_message_add_tail(x, &m);
185 }
186
187 if (rlen) {
188 x++;
189 x->rx_buf = &w;
190 x->len = 1;
191 spi_message_add_tail(x, &m);
192
193 if (rlen > 1) {
194 /* Arrange for the extra clock before the first
195 * data bit.
196 */
197 x->bits_per_word = 9;
198 x->len = 2;
199
200 x++;
201 x->rx_buf = &rbuf[1];
202 x->len = rlen - 1;
203 spi_message_add_tail(x, &m);
204 }
205 }
206
207 r = spi_sync(spi, &m);
208 if (r < 0)
209 dev_dbg(&spi->dev, "spi_sync %d\n", r);
210
211 if (rlen)
212 rbuf[0] = w & 0xff;
213}
214
215static inline void mipid_cmd(struct spi_device *spi, int cmd)
216{
217 mipid_transfer(spi, cmd, NULL, 0, NULL, 0);
218}
219
220static inline void mipid_write(struct spi_device *spi,
221 int reg, const u8 *buf, int len)
222{
223 mipid_transfer(spi, reg, buf, len, NULL, 0);
224}
225
226static inline void mipid_read(struct spi_device *spi,
227 int reg, u8 *buf, int len)
228{
229 mipid_transfer(spi, reg, NULL, 0, buf, len);
230}
231
232static void set_data_lines(struct spi_device *spi, int data_lines)
233{
234 u16 par;
235
236 switch (data_lines) {
237 case 16:
238 par = 0x150;
239 break;
240 case 18:
241 par = 0x160;
242 break;
243 case 24:
244 par = 0x170;
245 break;
246 }
247
248 mipid_write(spi, 0x3a, (u8 *)&par, 2);
249}
250
251static void send_init_string(struct spi_device *spi)
252{
253 u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
254 mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar));
255}
256
257static void send_display_on(struct spi_device *spi)
258{
259 mipid_cmd(spi, MIPID_CMD_DISP_ON);
260}
261
262static void send_display_off(struct spi_device *spi)
263{
264 mipid_cmd(spi, MIPID_CMD_DISP_OFF);
265}
266
267static void send_sleep_out(struct spi_device *spi)
268{
269 mipid_cmd(spi, MIPID_CMD_SLEEP_OUT);
270 msleep(120);
271}
272
273static void send_sleep_in(struct spi_device *spi)
274{
275 mipid_cmd(spi, MIPID_CMD_SLEEP_IN);
276 msleep(50);
277}
278
279static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
280{
281 int r;
282 struct panel_n8x0_data *bdata = get_board_data(dssdev);
283 struct panel_drv_data *ddata = get_drv_data(dssdev);
284 struct spi_device *spi = ddata->spidev;
285 u8 rev, conf;
286 u8 display_id[3];
287 const char *panel_name;
288
289 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
290 return 0;
291
292 gpio_direction_output(bdata->ctrl_pwrdown, 1);
293
294 if (bdata->platform_enable) {
295 r = bdata->platform_enable(dssdev);
296 if (r)
297 goto err_plat_en;
298 }
299
300 r = omapdss_rfbi_display_enable(dssdev);
301 if (r)
302 goto err_rfbi_en;
303
304 rev = blizzard_read_reg(BLIZZARD_REV_CODE);
305 conf = blizzard_read_reg(BLIZZARD_CONFIG);
306
307 switch (rev & 0xfc) {
308 case 0x9c:
309 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744;
310 dev_info(&dssdev->dev, "s1d13744 LCD controller rev %d "
311 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
312 break;
313 case 0xa4:
314 ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745;
315 dev_info(&dssdev->dev, "s1d13745 LCD controller rev %d "
316 "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
317 break;
318 default:
319 dev_err(&dssdev->dev, "invalid s1d1374x revision %02x\n", rev);
320 r = -ENODEV;
321 goto err_inv_chip;
322 }
323
324 /* panel */
325
326 gpio_direction_output(bdata->panel_reset, 1);
327
328 mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3);
329 dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n",
330 display_id[0], display_id[1], display_id[2]);
331
332 switch (display_id[0]) {
333 case 0x45:
334 panel_name = "lph8923";
335 break;
336 case 0x83:
337 panel_name = "ls041y3";
338 break;
339 default:
340 dev_err(&dssdev->dev, "invalid display ID 0x%x\n",
341 display_id[0]);
342 r = -ENODEV;
343 goto err_inv_panel;
344 }
345
346 dev_info(&dssdev->dev, "%s rev %02x LCD detected\n",
347 panel_name, display_id[1]);
348
349 send_sleep_out(spi);
350 send_init_string(spi);
351 set_data_lines(spi, 24);
352 send_display_on(spi);
353
354 return 0;
355
356err_inv_panel:
357 /*
358 * HACK: we should turn off the panel here, but there is some problem
359 * with the initialization sequence, and we fail to init the panel if we
360 * have turned it off
361 */
362 /* gpio_direction_output(bdata->panel_reset, 0); */
363err_inv_chip:
364 omapdss_rfbi_display_disable(dssdev);
365err_rfbi_en:
366 if (bdata->platform_disable)
367 bdata->platform_disable(dssdev);
368err_plat_en:
369 gpio_direction_output(bdata->ctrl_pwrdown, 0);
370 return r;
371}
372
373static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
374{
375 struct panel_n8x0_data *bdata = get_board_data(dssdev);
376 struct panel_drv_data *ddata = get_drv_data(dssdev);
377 struct spi_device *spi = ddata->spidev;
378
379 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
380 return;
381
382 send_display_off(spi);
383 send_sleep_in(spi);
384
385 if (bdata->platform_disable)
386 bdata->platform_disable(dssdev);
387
388 /*
389 * HACK: we should turn off the panel here, but there is some problem
390 * with the initialization sequence, and we fail to init the panel if we
391 * have turned it off
392 */
393 /* gpio_direction_output(bdata->panel_reset, 0); */
394 gpio_direction_output(bdata->ctrl_pwrdown, 0);
395 omapdss_rfbi_display_disable(dssdev);
396}
397
398static const struct rfbi_timings n8x0_panel_timings = {
399 .cs_on_time = 0,
400
401 .we_on_time = 9000,
402 .we_off_time = 18000,
403 .we_cycle_time = 36000,
404
405 .re_on_time = 9000,
406 .re_off_time = 27000,
407 .re_cycle_time = 36000,
408
409 .access_time = 27000,
410 .cs_off_time = 36000,
411
412 .cs_pulse_width = 0,
413};
414
415static int n8x0_bl_update_status(struct backlight_device *dev)
416{
417 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
418 struct panel_n8x0_data *bdata = get_board_data(dssdev);
419 struct panel_drv_data *ddata = get_drv_data(dssdev);
420 int r;
421 int level;
422
423 mutex_lock(&ddata->lock);
424
425 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
426 dev->props.power == FB_BLANK_UNBLANK)
427 level = dev->props.brightness;
428 else
429 level = 0;
430
431 dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
432
433 if (!bdata->set_backlight)
434 r = -EINVAL;
435 else
436 r = bdata->set_backlight(dssdev, level);
437
438 mutex_unlock(&ddata->lock);
439
440 return r;
441}
442
443static int n8x0_bl_get_intensity(struct backlight_device *dev)
444{
445 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
446 dev->props.power == FB_BLANK_UNBLANK)
447 return dev->props.brightness;
448
449 return 0;
450}
451
452static const struct backlight_ops n8x0_bl_ops = {
453 .get_brightness = n8x0_bl_get_intensity,
454 .update_status = n8x0_bl_update_status,
455};
456
457static int n8x0_panel_probe(struct omap_dss_device *dssdev)
458{
459 struct panel_n8x0_data *bdata = get_board_data(dssdev);
460 struct panel_drv_data *ddata;
461 struct backlight_device *bldev;
462 struct backlight_properties props;
463 int r;
464
465 dev_dbg(&dssdev->dev, "probe\n");
466
467 if (!bdata)
468 return -EINVAL;
469
470 s_drv_data.dssdev = dssdev;
471
472 ddata = &s_drv_data;
473
474 mutex_init(&ddata->lock);
475
476 dssdev->panel.config = OMAP_DSS_LCD_TFT;
477 dssdev->panel.timings.x_res = 800;
478 dssdev->panel.timings.y_res = 480;
479 dssdev->ctrl.pixel_size = 16;
480 dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
481
482 memset(&props, 0, sizeof(props));
483 props.max_brightness = 127;
484 props.type = BACKLIGHT_PLATFORM;
485 bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
486 dssdev, &n8x0_bl_ops, &props);
487 if (IS_ERR(bldev)) {
488 r = PTR_ERR(bldev);
489 dev_err(&dssdev->dev, "register backlight failed\n");
490 return r;
491 }
492
493 ddata->bldev = bldev;
494
495 bldev->props.fb_blank = FB_BLANK_UNBLANK;
496 bldev->props.power = FB_BLANK_UNBLANK;
497 bldev->props.brightness = 127;
498
499 n8x0_bl_update_status(bldev);
500
501 return 0;
502}
503
504static void n8x0_panel_remove(struct omap_dss_device *dssdev)
505{
506 struct panel_drv_data *ddata = get_drv_data(dssdev);
507 struct backlight_device *bldev;
508
509 dev_dbg(&dssdev->dev, "remove\n");
510
511 bldev = ddata->bldev;
512 bldev->props.power = FB_BLANK_POWERDOWN;
513 n8x0_bl_update_status(bldev);
514 backlight_device_unregister(bldev);
515
516 dev_set_drvdata(&dssdev->dev, NULL);
517}
518
519static int n8x0_panel_enable(struct omap_dss_device *dssdev)
520{
521 struct panel_drv_data *ddata = get_drv_data(dssdev);
522 int r;
523
524 dev_dbg(&dssdev->dev, "enable\n");
525
526 mutex_lock(&ddata->lock);
527
528 rfbi_bus_lock();
529
530 r = n8x0_panel_power_on(dssdev);
531
532 rfbi_bus_unlock();
533
534 if (r) {
535 mutex_unlock(&ddata->lock);
536 return r;
537 }
538
539 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
540
541 mutex_unlock(&ddata->lock);
542
543 return 0;
544}
545
546static void n8x0_panel_disable(struct omap_dss_device *dssdev)
547{
548 struct panel_drv_data *ddata = get_drv_data(dssdev);
549
550 dev_dbg(&dssdev->dev, "disable\n");
551
552 mutex_lock(&ddata->lock);
553
554 rfbi_bus_lock();
555
556 n8x0_panel_power_off(dssdev);
557
558 rfbi_bus_unlock();
559
560 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
561
562 mutex_unlock(&ddata->lock);
563}
564
565static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
566{
567 struct panel_drv_data *ddata = get_drv_data(dssdev);
568
569 dev_dbg(&dssdev->dev, "suspend\n");
570
571 mutex_lock(&ddata->lock);
572
573 rfbi_bus_lock();
574
575 n8x0_panel_power_off(dssdev);
576
577 rfbi_bus_unlock();
578
579 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
580
581 mutex_unlock(&ddata->lock);
582
583 return 0;
584}
585
586static int n8x0_panel_resume(struct omap_dss_device *dssdev)
587{
588 struct panel_drv_data *ddata = get_drv_data(dssdev);
589 int r;
590
591 dev_dbg(&dssdev->dev, "resume\n");
592
593 mutex_lock(&ddata->lock);
594
595 rfbi_bus_lock();
596
597 r = n8x0_panel_power_on(dssdev);
598
599 rfbi_bus_unlock();
600
601 if (r) {
602 mutex_unlock(&ddata->lock);
603 return r;
604 }
605
606 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
607
608 mutex_unlock(&ddata->lock);
609
610 return 0;
611}
612
613static void n8x0_panel_get_timings(struct omap_dss_device *dssdev,
614 struct omap_video_timings *timings)
615{
616 *timings = dssdev->panel.timings;
617}
618
619static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
620 u16 *xres, u16 *yres)
621{
622 *xres = dssdev->panel.timings.x_res;
623 *yres = dssdev->panel.timings.y_res;
624}
625
626static void update_done(void *data)
627{
628 rfbi_bus_unlock();
629}
630
631static int n8x0_panel_update(struct omap_dss_device *dssdev,
632 u16 x, u16 y, u16 w, u16 h)
633{
634 struct panel_drv_data *ddata = get_drv_data(dssdev);
635
636 dev_dbg(&dssdev->dev, "update\n");
637
638 mutex_lock(&ddata->lock);
639 rfbi_bus_lock();
640
641 omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
642
643 blizzard_ctrl_setup_update(dssdev, x, y, w, h);
644
645 omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
646
647 mutex_unlock(&ddata->lock);
648
649 return 0;
650}
651
652static int n8x0_panel_sync(struct omap_dss_device *dssdev)
653{
654 struct panel_drv_data *ddata = get_drv_data(dssdev);
655
656 dev_dbg(&dssdev->dev, "sync\n");
657
658 mutex_lock(&ddata->lock);
659 rfbi_bus_lock();
660 rfbi_bus_unlock();
661 mutex_unlock(&ddata->lock);
662
663 return 0;
664}
665
666static struct omap_dss_driver n8x0_panel_driver = {
667 .probe = n8x0_panel_probe,
668 .remove = n8x0_panel_remove,
669
670 .enable = n8x0_panel_enable,
671 .disable = n8x0_panel_disable,
672 .suspend = n8x0_panel_suspend,
673 .resume = n8x0_panel_resume,
674
675 .update = n8x0_panel_update,
676 .sync = n8x0_panel_sync,
677
678 .get_resolution = n8x0_panel_get_resolution,
679 .get_recommended_bpp = omapdss_default_get_recommended_bpp,
680
681 .get_timings = n8x0_panel_get_timings,
682
683 .driver = {
684 .name = "n8x0_panel",
685 .owner = THIS_MODULE,
686 },
687};
688
689/* PANEL */
690
691static int mipid_spi_probe(struct spi_device *spi)
692{
693 dev_dbg(&spi->dev, "mipid_spi_probe\n");
694
695 spi->mode = SPI_MODE_0;
696
697 s_drv_data.spidev = spi;
698
699 return 0;
700}
701
702static int mipid_spi_remove(struct spi_device *spi)
703{
704 dev_dbg(&spi->dev, "mipid_spi_remove\n");
705 return 0;
706}
707
708static struct spi_driver mipid_spi_driver = {
709 .driver = {
710 .name = "lcd_mipid",
711 .bus = &spi_bus_type,
712 .owner = THIS_MODULE,
713 },
714 .probe = mipid_spi_probe,
715 .remove = __devexit_p(mipid_spi_remove),
716};
717
718static int __init n8x0_panel_drv_init(void)
719{
720 int r;
721
722 r = spi_register_driver(&mipid_spi_driver);
723 if (r) {
724 pr_err("n8x0_panel: spi driver registration failed\n");
725 return r;
726 }
727
728 r = omap_dss_register_driver(&n8x0_panel_driver);
729 if (r) {
730 pr_err("n8x0_panel: dss driver registration failed\n");
731 spi_unregister_driver(&mipid_spi_driver);
732 return r;
733 }
734
735 return 0;
736}
737
738static void __exit n8x0_panel_drv_exit(void)
739{
740 spi_unregister_driver(&mipid_spi_driver);
741
742 omap_dss_unregister_driver(&n8x0_panel_driver);
743}
744
745module_init(n8x0_panel_drv_init);
746module_exit(n8x0_panel_drv_exit);
747MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
new file mode 100644
index 000000000000..98ebdaddab5a
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -0,0 +1,594 @@
1/*
2 * picodlp panel driver
3 * picodlp_i2c_driver: i2c_client driver
4 *
5 * Copyright (C) 2009-2011 Texas Instruments
6 * Author: Mythri P K <mythripk@ti.com>
7 * Mayuresh Janorkar <mayur@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/module.h>
23#include <linux/input.h>
24#include <linux/platform_device.h>
25#include <linux/interrupt.h>
26#include <linux/firmware.h>
27#include <linux/slab.h>
28#include <linux/mutex.h>
29#include <linux/i2c.h>
30#include <linux/delay.h>
31#include <linux/gpio.h>
32
33#include <video/omapdss.h>
34#include <video/omap-panel-picodlp.h>
35
36#include "panel-picodlp.h"
37
38struct picodlp_data {
39 struct mutex lock;
40 struct i2c_client *picodlp_i2c_client;
41};
42
43static struct i2c_board_info picodlp_i2c_board_info = {
44 I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b),
45};
46
47struct picodlp_i2c_data {
48 struct mutex xfer_lock;
49};
50
51static struct i2c_device_id picodlp_i2c_id[] = {
52 { "picodlp_i2c_driver", 0 },
53};
54
55struct picodlp_i2c_command {
56 u8 reg;
57 u32 value;
58};
59
60static struct omap_video_timings pico_ls_timings = {
61 .x_res = 864,
62 .y_res = 480,
63 .hsw = 7,
64 .hfp = 11,
65 .hbp = 7,
66
67 .pixel_clock = 19200,
68
69 .vsw = 2,
70 .vfp = 3,
71 .vbp = 14,
72};
73
74static inline struct picodlp_panel_data
75 *get_panel_data(const struct omap_dss_device *dssdev)
76{
77 return (struct picodlp_panel_data *) dssdev->data;
78}
79
80static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg)
81{
82 u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4];
83 struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
84 struct i2c_msg msg[2];
85
86 mutex_lock(&picodlp_i2c_data->xfer_lock);
87
88 msg[0].addr = client->addr;
89 msg[0].flags = 0;
90 msg[0].len = 2;
91 msg[0].buf = read_cmd;
92
93 msg[1].addr = client->addr;
94 msg[1].flags = I2C_M_RD;
95 msg[1].len = 4;
96 msg[1].buf = data;
97
98 i2c_transfer(client->adapter, msg, 2);
99 mutex_unlock(&picodlp_i2c_data->xfer_lock);
100 return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24));
101}
102
103static int picodlp_i2c_write_block(struct i2c_client *client,
104 u8 *data, int len)
105{
106 struct i2c_msg msg;
107 int i, r, msg_count = 1;
108
109 struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
110
111 if (len < 1 || len > 32) {
112 dev_err(&client->dev,
113 "too long syn_write_block len %d\n", len);
114 return -EIO;
115 }
116 mutex_lock(&picodlp_i2c_data->xfer_lock);
117
118 msg.addr = client->addr;
119 msg.flags = 0;
120 msg.len = len;
121 msg.buf = data;
122 r = i2c_transfer(client->adapter, &msg, msg_count);
123 mutex_unlock(&picodlp_i2c_data->xfer_lock);
124
125 /*
126 * i2c_transfer returns:
127 * number of messages sent in case of success
128 * a negative error number in case of failure
129 */
130 if (r != msg_count)
131 goto err;
132
133 /* In case of success */
134 for (i = 0; i < len; i++)
135 dev_dbg(&client->dev,
136 "addr %x bw 0x%02x[%d]: 0x%02x\n",
137 client->addr, data[0] + i, i, data[i]);
138
139 return 0;
140err:
141 dev_err(&client->dev, "picodlp_i2c_write error\n");
142 return r;
143}
144
145static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value)
146{
147 u8 data[5];
148 int i;
149
150 data[0] = reg;
151 for (i = 1; i < 5; i++)
152 data[i] = (value >> (32 - (i) * 8)) & 0xFF;
153
154 return picodlp_i2c_write_block(client, data, 5);
155}
156
157static int picodlp_i2c_write_array(struct i2c_client *client,
158 const struct picodlp_i2c_command commands[],
159 int count)
160{
161 int i, r = 0;
162 for (i = 0; i < count; i++) {
163 r = picodlp_i2c_write(client, commands[i].reg,
164 commands[i].value);
165 if (r)
166 return r;
167 }
168 return r;
169}
170
171static int picodlp_wait_for_dma_done(struct i2c_client *client)
172{
173 u8 trial = 100;
174
175 do {
176 msleep(1);
177 if (!trial--)
178 return -ETIMEDOUT;
179 } while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS);
180
181 return 0;
182}
183
184/**
185 * picodlp_i2c_init: i2c_initialization routine
186 * client: i2c_client for communication
187 *
188 * return
189 * 0 : Success, no error
190 * error code : Failure
191 */
192static int picodlp_i2c_init(struct i2c_client *client)
193{
194 int r;
195 static const struct picodlp_i2c_command init_cmd_set1[] = {
196 {SOFT_RESET, 1},
197 {DMD_PARK_TRIGGER, 1},
198 {MISC_REG, 5},
199 {SEQ_CONTROL, 0},
200 {SEQ_VECTOR, 0x100},
201 {DMD_BLOCK_COUNT, 7},
202 {DMD_VCC_CONTROL, 0x109},
203 {DMD_PARK_PULSE_COUNT, 0xA},
204 {DMD_PARK_PULSE_WIDTH, 0xB},
205 {DMD_PARK_DELAY, 0x2ED},
206 {DMD_SHADOW_ENABLE, 0},
207 {FLASH_OPCODE, 0xB},
208 {FLASH_DUMMY_BYTES, 1},
209 {FLASH_ADDR_BYTES, 3},
210 {PBC_CONTROL, 0},
211 {FLASH_START_ADDR, CMT_LUT_0_START_ADDR},
212 {FLASH_READ_BYTES, CMT_LUT_0_SIZE},
213 {CMT_SPLASH_LUT_START_ADDR, 0},
214 {CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL},
215 {PBC_CONTROL, 1},
216 };
217
218 static const struct picodlp_i2c_command init_cmd_set2[] = {
219 {PBC_CONTROL, 0},
220 {CMT_SPLASH_LUT_DEST_SELECT, 0},
221 {PBC_CONTROL, 0},
222 {FLASH_START_ADDR, SEQUENCE_0_START_ADDR},
223 {FLASH_READ_BYTES, SEQUENCE_0_SIZE},
224 {SEQ_RESET_LUT_START_ADDR, 0},
225 {SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT},
226 {PBC_CONTROL, 1},
227 };
228
229 static const struct picodlp_i2c_command init_cmd_set3[] = {
230 {PBC_CONTROL, 0},
231 {SEQ_RESET_LUT_DEST_SELECT, 0},
232 {PBC_CONTROL, 0},
233 {FLASH_START_ADDR, DRC_TABLE_0_START_ADDR},
234 {FLASH_READ_BYTES, DRC_TABLE_0_SIZE},
235 {SEQ_RESET_LUT_START_ADDR, 0},
236 {SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL},
237 {PBC_CONTROL, 1},
238 };
239
240 static const struct picodlp_i2c_command init_cmd_set4[] = {
241 {PBC_CONTROL, 0},
242 {SEQ_RESET_LUT_DEST_SELECT, 0},
243 {SDC_ENABLE, 1},
244 {AGC_CTRL, 7},
245 {CCA_C1A, 0x100},
246 {CCA_C1B, 0x0},
247 {CCA_C1C, 0x0},
248 {CCA_C2A, 0x0},
249 {CCA_C2B, 0x100},
250 {CCA_C2C, 0x0},
251 {CCA_C3A, 0x0},
252 {CCA_C3B, 0x0},
253 {CCA_C3C, 0x100},
254 {CCA_C7A, 0x100},
255 {CCA_C7B, 0x100},
256 {CCA_C7C, 0x100},
257 {CCA_ENABLE, 1},
258 {CPU_IF_MODE, 1},
259 {SHORT_FLIP, 1},
260 {CURTAIN_CONTROL, 0},
261 {DMD_PARK_TRIGGER, 0},
262 {R_DRIVE_CURRENT, 0x298},
263 {G_DRIVE_CURRENT, 0x298},
264 {B_DRIVE_CURRENT, 0x298},
265 {RGB_DRIVER_ENABLE, 7},
266 {SEQ_CONTROL, 0},
267 {ACTGEN_CONTROL, 0x10},
268 {SEQUENCE_MODE, SEQ_LOCK},
269 {DATA_FORMAT, RGB888},
270 {INPUT_RESOLUTION, WVGA_864_LANDSCAPE},
271 {INPUT_SOURCE, PARALLEL_RGB},
272 {CPU_IF_SYNC_METHOD, 1},
273 {SEQ_CONTROL, 1}
274 };
275
276 r = picodlp_i2c_write_array(client, init_cmd_set1,
277 ARRAY_SIZE(init_cmd_set1));
278 if (r)
279 return r;
280
281 r = picodlp_wait_for_dma_done(client);
282 if (r)
283 return r;
284
285 r = picodlp_i2c_write_array(client, init_cmd_set2,
286 ARRAY_SIZE(init_cmd_set2));
287 if (r)
288 return r;
289
290 r = picodlp_wait_for_dma_done(client);
291 if (r)
292 return r;
293
294 r = picodlp_i2c_write_array(client, init_cmd_set3,
295 ARRAY_SIZE(init_cmd_set3));
296 if (r)
297 return r;
298
299 r = picodlp_wait_for_dma_done(client);
300 if (r)
301 return r;
302
303 r = picodlp_i2c_write_array(client, init_cmd_set4,
304 ARRAY_SIZE(init_cmd_set4));
305 if (r)
306 return r;
307
308 return 0;
309}
310
311static int picodlp_i2c_probe(struct i2c_client *client,
312 const struct i2c_device_id *id)
313{
314 struct picodlp_i2c_data *picodlp_i2c_data;
315
316 picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL);
317
318 if (!picodlp_i2c_data)
319 return -ENOMEM;
320
321 mutex_init(&picodlp_i2c_data->xfer_lock);
322 i2c_set_clientdata(client, picodlp_i2c_data);
323
324 return 0;
325}
326
327static int picodlp_i2c_remove(struct i2c_client *client)
328{
329 struct picodlp_i2c_data *picodlp_i2c_data =
330 i2c_get_clientdata(client);
331 kfree(picodlp_i2c_data);
332 return 0;
333}
334
335static struct i2c_driver picodlp_i2c_driver = {
336 .driver = {
337 .name = "picodlp_i2c_driver",
338 },
339 .probe = picodlp_i2c_probe,
340 .remove = picodlp_i2c_remove,
341 .id_table = picodlp_i2c_id,
342};
343
344static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
345{
346 int r, trial = 100;
347 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
348 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
349
350 if (dssdev->platform_enable) {
351 r = dssdev->platform_enable(dssdev);
352 if (r)
353 return r;
354 }
355
356 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
357 msleep(1);
358 gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
359
360 while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) {
361 if (!trial--) {
362 dev_err(&dssdev->dev, "emu_done signal not"
363 " going high\n");
364 return -ETIMEDOUT;
365 }
366 msleep(5);
367 }
368 /*
369 * As per dpp2600 programming guide,
370 * it is required to sleep for 1000ms after emu_done signal goes high
371 * then only i2c commands can be successfully sent to dpp2600
372 */
373 msleep(1000);
374 r = omapdss_dpi_display_enable(dssdev);
375 if (r) {
376 dev_err(&dssdev->dev, "failed to enable DPI\n");
377 goto err1;
378 }
379
380 r = picodlp_i2c_init(picod->picodlp_i2c_client);
381 if (r)
382 goto err;
383
384 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
385
386 return r;
387err:
388 omapdss_dpi_display_disable(dssdev);
389err1:
390 if (dssdev->platform_disable)
391 dssdev->platform_disable(dssdev);
392
393 return r;
394}
395
396static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
397{
398 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
399
400 omapdss_dpi_display_disable(dssdev);
401
402 gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
403 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
404
405 if (dssdev->platform_disable)
406 dssdev->platform_disable(dssdev);
407}
408
409static int picodlp_panel_probe(struct omap_dss_device *dssdev)
410{
411 struct picodlp_data *picod;
412 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
413 struct i2c_adapter *adapter;
414 struct i2c_client *picodlp_i2c_client;
415 int r = 0, picodlp_adapter_id;
416
417 dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_ONOFF |
418 OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS;
419 dssdev->panel.acb = 0x0;
420 dssdev->panel.timings = pico_ls_timings;
421
422 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL);
423 if (!picod)
424 return -ENOMEM;
425
426 mutex_init(&picod->lock);
427
428 picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id;
429
430 adapter = i2c_get_adapter(picodlp_adapter_id);
431 if (!adapter) {
432 dev_err(&dssdev->dev, "can't get i2c adapter\n");
433 r = -ENODEV;
434 goto err;
435 }
436
437 picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
438 if (!picodlp_i2c_client) {
439 dev_err(&dssdev->dev, "can't add i2c device::"
440 " picodlp_i2c_client is NULL\n");
441 r = -ENODEV;
442 goto err;
443 }
444
445 picod->picodlp_i2c_client = picodlp_i2c_client;
446
447 dev_set_drvdata(&dssdev->dev, picod);
448 return r;
449err:
450 kfree(picod);
451 return r;
452}
453
454static void picodlp_panel_remove(struct omap_dss_device *dssdev)
455{
456 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
457
458 i2c_unregister_device(picod->picodlp_i2c_client);
459 dev_set_drvdata(&dssdev->dev, NULL);
460 dev_dbg(&dssdev->dev, "removing picodlp panel\n");
461
462 kfree(picod);
463}
464
465static int picodlp_panel_enable(struct omap_dss_device *dssdev)
466{
467 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
468 int r;
469
470 dev_dbg(&dssdev->dev, "enabling picodlp panel\n");
471
472 mutex_lock(&picod->lock);
473 if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
474 mutex_unlock(&picod->lock);
475 return -EINVAL;
476 }
477
478 r = picodlp_panel_power_on(dssdev);
479 mutex_unlock(&picod->lock);
480
481 return r;
482}
483
484static void picodlp_panel_disable(struct omap_dss_device *dssdev)
485{
486 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
487
488 mutex_lock(&picod->lock);
489 /* Turn off DLP Power */
490 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
491 picodlp_panel_power_off(dssdev);
492
493 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
494 mutex_unlock(&picod->lock);
495
496 dev_dbg(&dssdev->dev, "disabling picodlp panel\n");
497}
498
499static int picodlp_panel_suspend(struct omap_dss_device *dssdev)
500{
501 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
502
503 mutex_lock(&picod->lock);
504 /* Turn off DLP Power */
505 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
506 mutex_unlock(&picod->lock);
507 dev_err(&dssdev->dev, "unable to suspend picodlp panel,"
508 " panel is not ACTIVE\n");
509 return -EINVAL;
510 }
511
512 picodlp_panel_power_off(dssdev);
513
514 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
515 mutex_unlock(&picod->lock);
516
517 dev_dbg(&dssdev->dev, "suspending picodlp panel\n");
518 return 0;
519}
520
521static int picodlp_panel_resume(struct omap_dss_device *dssdev)
522{
523 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
524 int r;
525
526 mutex_lock(&picod->lock);
527 if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
528 mutex_unlock(&picod->lock);
529 dev_err(&dssdev->dev, "unable to resume picodlp panel,"
530 " panel is not ACTIVE\n");
531 return -EINVAL;
532 }
533
534 r = picodlp_panel_power_on(dssdev);
535 mutex_unlock(&picod->lock);
536 dev_dbg(&dssdev->dev, "resuming picodlp panel\n");
537 return r;
538}
539
540static void picodlp_get_resolution(struct omap_dss_device *dssdev,
541 u16 *xres, u16 *yres)
542{
543 *xres = dssdev->panel.timings.x_res;
544 *yres = dssdev->panel.timings.y_res;
545}
546
547static struct omap_dss_driver picodlp_driver = {
548 .probe = picodlp_panel_probe,
549 .remove = picodlp_panel_remove,
550
551 .enable = picodlp_panel_enable,
552 .disable = picodlp_panel_disable,
553
554 .get_resolution = picodlp_get_resolution,
555
556 .suspend = picodlp_panel_suspend,
557 .resume = picodlp_panel_resume,
558
559 .driver = {
560 .name = "picodlp_panel",
561 .owner = THIS_MODULE,
562 },
563};
564
565static int __init picodlp_init(void)
566{
567 int r = 0;
568
569 r = i2c_add_driver(&picodlp_i2c_driver);
570 if (r) {
571 printk(KERN_WARNING "picodlp_i2c_driver" \
572 " registration failed\n");
573 return r;
574 }
575
576 r = omap_dss_register_driver(&picodlp_driver);
577 if (r)
578 i2c_del_driver(&picodlp_i2c_driver);
579
580 return r;
581}
582
583static void __exit picodlp_exit(void)
584{
585 i2c_del_driver(&picodlp_i2c_driver);
586 omap_dss_unregister_driver(&picodlp_driver);
587}
588
589module_init(picodlp_init);
590module_exit(picodlp_exit);
591
592MODULE_AUTHOR("Mythri P K <mythripk@ti.com>");
593MODULE_DESCRIPTION("picodlp driver");
594MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-picodlp.h b/drivers/video/omap2/displays/panel-picodlp.h
new file mode 100644
index 000000000000..a34b431a7267
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-picodlp.h
@@ -0,0 +1,288 @@
1/*
2 * Header file required by picodlp panel driver
3 *
4 * Copyright (C) 2009-2011 Texas Instruments
5 * Author: Mythri P K <mythripk@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H
21#define __OMAP2_DISPLAY_PANEL_PICODLP_H
22
23/* Commands used for configuring picodlp panel */
24
25#define MAIN_STATUS 0x03
26#define PBC_CONTROL 0x08
27#define INPUT_SOURCE 0x0B
28#define INPUT_RESOLUTION 0x0C
29#define DATA_FORMAT 0x0D
30#define IMG_ROTATION 0x0E
31#define LONG_FLIP 0x0F
32#define SHORT_FLIP 0x10
33#define TEST_PAT_SELECT 0x11
34#define R_DRIVE_CURRENT 0x12
35#define G_DRIVE_CURRENT 0x13
36#define B_DRIVE_CURRENT 0x14
37#define READ_REG_SELECT 0x15
38#define RGB_DRIVER_ENABLE 0x16
39
40#define CPU_IF_MODE 0x18
41#define FRAME_RATE 0x19
42#define CPU_IF_SYNC_METHOD 0x1A
43#define CPU_IF_SOF 0x1B
44#define CPU_IF_EOF 0x1C
45#define CPU_IF_SLEEP 0x1D
46
47#define SEQUENCE_MODE 0x1E
48#define SOFT_RESET 0x1F
49#define FRONT_END_RESET 0x21
50#define AUTO_PWR_ENABLE 0x22
51
52#define VSYNC_LINE_DELAY 0x23
53#define CPU_PI_HORIZ_START 0x24
54#define CPU_PI_VERT_START 0x25
55#define CPU_PI_HORIZ_WIDTH 0x26
56#define CPU_PI_VERT_HEIGHT 0x27
57
58#define PIXEL_MASK_CROP 0x28
59#define CROP_FIRST_LINE 0x29
60#define CROP_LAST_LINE 0x2A
61#define CROP_FIRST_PIXEL 0x2B
62#define CROP_LAST_PIXEL 0x2C
63#define DMD_PARK_TRIGGER 0x2D
64
65#define MISC_REG 0x30
66
67/* AGC registers */
68#define AGC_CTRL 0x50
69#define AGC_CLIPPED_PIXS 0x55
70#define AGC_BRIGHT_PIXS 0x56
71#define AGC_BG_PIXS 0x57
72#define AGC_SAFETY_MARGIN 0x17
73
74/* Color Coordinate Adjustment registers */
75#define CCA_ENABLE 0x5E
76#define CCA_C1A 0x5F
77#define CCA_C1B 0x60
78#define CCA_C1C 0x61
79#define CCA_C2A 0x62
80#define CCA_C2B 0x63
81#define CCA_C2C 0x64
82#define CCA_C3A 0x65
83#define CCA_C3B 0x66
84#define CCA_C3C 0x67
85#define CCA_C7A 0x71
86#define CCA_C7B 0x72
87#define CCA_C7C 0x73
88
89/**
90 * DLP Pico Processor 2600 comes with flash
91 * We can do DMA operations from flash for accessing Look Up Tables
92 */
93#define DMA_STATUS 0x100
94#define FLASH_ADDR_BYTES 0x74
95#define FLASH_DUMMY_BYTES 0x75
96#define FLASH_WRITE_BYTES 0x76
97#define FLASH_READ_BYTES 0x77
98#define FLASH_OPCODE 0x78
99#define FLASH_START_ADDR 0x79
100#define FLASH_DUMMY2 0x7A
101#define FLASH_WRITE_DATA 0x7B
102
103#define TEMPORAL_DITH_DISABLE 0x7E
104#define SEQ_CONTROL 0x82
105#define SEQ_VECTOR 0x83
106
107/* DMD is Digital Micromirror Device */
108#define DMD_BLOCK_COUNT 0x84
109#define DMD_VCC_CONTROL 0x86
110#define DMD_PARK_PULSE_COUNT 0x87
111#define DMD_PARK_PULSE_WIDTH 0x88
112#define DMD_PARK_DELAY 0x89
113#define DMD_SHADOW_ENABLE 0x8E
114#define SEQ_STATUS 0x8F
115#define FLASH_CLOCK_CONTROL 0x98
116#define DMD_PARK 0x2D
117
118#define SDRAM_BIST_ENABLE 0x46
119#define DDR_DRIVER_STRENGTH 0x9A
120#define SDC_ENABLE 0x9D
121#define SDC_BUFF_SWAP_DISABLE 0xA3
122#define CURTAIN_CONTROL 0xA6
123#define DDR_BUS_SWAP_ENABLE 0xA7
124#define DMD_TRC_ENABLE 0xA8
125#define DMD_BUS_SWAP_ENABLE 0xA9
126
127#define ACTGEN_ENABLE 0xAE
128#define ACTGEN_CONTROL 0xAF
129#define ACTGEN_HORIZ_BP 0xB0
130#define ACTGEN_VERT_BP 0xB1
131
132/* Look Up Table access */
133#define CMT_SPLASH_LUT_START_ADDR 0xFA
134#define CMT_SPLASH_LUT_DEST_SELECT 0xFB
135#define CMT_SPLASH_LUT_DATA 0xFC
136#define SEQ_RESET_LUT_START_ADDR 0xFD
137#define SEQ_RESET_LUT_DEST_SELECT 0xFE
138#define SEQ_RESET_LUT_DATA 0xFF
139
140/* Input source definitions */
141#define PARALLEL_RGB 0
142#define INT_TEST_PATTERN 1
143#define SPLASH_SCREEN 2
144#define CPU_INTF 3
145#define BT656 4
146
147/* Standard input resolution definitions */
148#define QWVGA_LANDSCAPE 3 /* (427h*240v) */
149#define WVGA_864_LANDSCAPE 21 /* (864h*480v) */
150#define WVGA_DMD_OPTICAL_TEST 35 /* (608h*684v) */
151
152/* Standard data format definitions */
153#define RGB565 0
154#define RGB666 1
155#define RGB888 2
156
157/* Test Pattern definitions */
158#define TPG_CHECKERBOARD 0
159#define TPG_BLACK 1
160#define TPG_WHITE 2
161#define TPG_RED 3
162#define TPG_BLUE 4
163#define TPG_GREEN 5
164#define TPG_VLINES_BLACK 6
165#define TPG_HLINES_BLACK 7
166#define TPG_VLINES_ALT 8
167#define TPG_HLINES_ALT 9
168#define TPG_DIAG_LINES 10
169#define TPG_GREYRAMP_VERT 11
170#define TPG_GREYRAMP_HORIZ 12
171#define TPG_ANSI_CHECKERBOARD 13
172
173/* sequence mode definitions */
174#define SEQ_FREE_RUN 0
175#define SEQ_LOCK 1
176
177/* curtain color definitions */
178#define CURTAIN_BLACK 0
179#define CURTAIN_RED 1
180#define CURTAIN_GREEN 2
181#define CURTAIN_BLUE 3
182#define CURTAIN_YELLOW 4
183#define CURTAIN_MAGENTA 5
184#define CURTAIN_CYAN 6
185#define CURTAIN_WHITE 7
186
187/* LUT definitions */
188#define CMT_LUT_NONE 0
189#define CMT_LUT_GREEN 1
190#define CMT_LUT_RED 2
191#define CMT_LUT_BLUE 3
192#define CMT_LUT_ALL 4
193#define SPLASH_LUT 5
194
195#define SEQ_LUT_NONE 0
196#define SEQ_DRC_LUT_0 1
197#define SEQ_DRC_LUT_1 2
198#define SEQ_DRC_LUT_2 3
199#define SEQ_DRC_LUT_3 4
200#define SEQ_SEQ_LUT 5
201#define SEQ_DRC_LUT_ALL 6
202#define WPC_PROGRAM_LUT 7
203
204#define BITSTREAM_START_ADDR 0x00000000
205#define BITSTREAM_SIZE 0x00040000
206
207#define WPC_FW_0_START_ADDR 0x00040000
208#define WPC_FW_0_SIZE 0x00000ce8
209
210#define SEQUENCE_0_START_ADDR 0x00044000
211#define SEQUENCE_0_SIZE 0x00001000
212
213#define SEQUENCE_1_START_ADDR 0x00045000
214#define SEQUENCE_1_SIZE 0x00000d10
215
216#define SEQUENCE_2_START_ADDR 0x00046000
217#define SEQUENCE_2_SIZE 0x00000d10
218
219#define SEQUENCE_3_START_ADDR 0x00047000
220#define SEQUENCE_3_SIZE 0x00000d10
221
222#define SEQUENCE_4_START_ADDR 0x00048000
223#define SEQUENCE_4_SIZE 0x00000d10
224
225#define SEQUENCE_5_START_ADDR 0x00049000
226#define SEQUENCE_5_SIZE 0x00000d10
227
228#define SEQUENCE_6_START_ADDR 0x0004a000
229#define SEQUENCE_6_SIZE 0x00000d10
230
231#define CMT_LUT_0_START_ADDR 0x0004b200
232#define CMT_LUT_0_SIZE 0x00000600
233
234#define CMT_LUT_1_START_ADDR 0x0004b800
235#define CMT_LUT_1_SIZE 0x00000600
236
237#define CMT_LUT_2_START_ADDR 0x0004be00
238#define CMT_LUT_2_SIZE 0x00000600
239
240#define CMT_LUT_3_START_ADDR 0x0004c400
241#define CMT_LUT_3_SIZE 0x00000600
242
243#define CMT_LUT_4_START_ADDR 0x0004ca00
244#define CMT_LUT_4_SIZE 0x00000600
245
246#define CMT_LUT_5_START_ADDR 0x0004d000
247#define CMT_LUT_5_SIZE 0x00000600
248
249#define CMT_LUT_6_START_ADDR 0x0004d600
250#define CMT_LUT_6_SIZE 0x00000600
251
252#define DRC_TABLE_0_START_ADDR 0x0004dc00
253#define DRC_TABLE_0_SIZE 0x00000100
254
255#define SPLASH_0_START_ADDR 0x0004dd00
256#define SPLASH_0_SIZE 0x00032280
257
258#define SEQUENCE_7_START_ADDR 0x00080000
259#define SEQUENCE_7_SIZE 0x00000d10
260
261#define SEQUENCE_8_START_ADDR 0x00081800
262#define SEQUENCE_8_SIZE 0x00000d10
263
264#define SEQUENCE_9_START_ADDR 0x00083000
265#define SEQUENCE_9_SIZE 0x00000d10
266
267#define CMT_LUT_7_START_ADDR 0x0008e000
268#define CMT_LUT_7_SIZE 0x00000600
269
270#define CMT_LUT_8_START_ADDR 0x0008e800
271#define CMT_LUT_8_SIZE 0x00000600
272
273#define CMT_LUT_9_START_ADDR 0x0008f000
274#define CMT_LUT_9_SIZE 0x00000600
275
276#define SPLASH_1_START_ADDR 0x0009a000
277#define SPLASH_1_SIZE 0x00032280
278
279#define SPLASH_2_START_ADDR 0x000cd000
280#define SPLASH_2_SIZE 0x00032280
281
282#define SPLASH_3_START_ADDR 0x00100000
283#define SPLASH_3_SIZE 0x00032280
284
285#define OPT_SPLASH_0_START_ADDR 0x00134000
286#define OPT_SPLASH_0_SIZE 0x000cb100
287
288#endif
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index ca00843ed2fe..80c3f6ab1a94 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -35,26 +35,12 @@
35 35
36#include <video/omapdss.h> 36#include <video/omapdss.h>
37#include <video/omap-panel-nokia-dsi.h> 37#include <video/omap-panel-nokia-dsi.h>
38#include <video/mipi_display.h>
38 39
39/* DSI Virtual channel. Hardcoded for now. */ 40/* DSI Virtual channel. Hardcoded for now. */
40#define TCH 0 41#define TCH 0
41 42
42#define DCS_READ_NUM_ERRORS 0x05 43#define DCS_READ_NUM_ERRORS 0x05
43#define DCS_READ_POWER_MODE 0x0a
44#define DCS_READ_MADCTL 0x0b
45#define DCS_READ_PIXEL_FORMAT 0x0c
46#define DCS_RDDSDR 0x0f
47#define DCS_SLEEP_IN 0x10
48#define DCS_SLEEP_OUT 0x11
49#define DCS_DISPLAY_OFF 0x28
50#define DCS_DISPLAY_ON 0x29
51#define DCS_COLUMN_ADDR 0x2a
52#define DCS_PAGE_ADDR 0x2b
53#define DCS_MEMORY_WRITE 0x2c
54#define DCS_TEAR_OFF 0x34
55#define DCS_TEAR_ON 0x35
56#define DCS_MEM_ACC_CTRL 0x36
57#define DCS_PIXEL_FORMAT 0x3a
58#define DCS_BRIGHTNESS 0x51 44#define DCS_BRIGHTNESS 0x51
59#define DCS_CTRL_DISPLAY 0x53 45#define DCS_CTRL_DISPLAY 0x53
60#define DCS_WRITE_CABC 0x55 46#define DCS_WRITE_CABC 0x55
@@ -222,8 +208,6 @@ struct taal_data {
222 208
223 struct delayed_work te_timeout_work; 209 struct delayed_work te_timeout_work;
224 210
225 bool use_dsi_bl;
226
227 bool cabc_broken; 211 bool cabc_broken;
228 unsigned cabc_mode; 212 unsigned cabc_mode;
229 213
@@ -302,7 +286,7 @@ static int taal_sleep_in(struct taal_data *td)
302 286
303 hw_guard_wait(td); 287 hw_guard_wait(td);
304 288
305 cmd = DCS_SLEEP_IN; 289 cmd = MIPI_DCS_ENTER_SLEEP_MODE;
306 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1); 290 r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
307 if (r) 291 if (r)
308 return r; 292 return r;
@@ -321,7 +305,7 @@ static int taal_sleep_out(struct taal_data *td)
321 305
322 hw_guard_wait(td); 306 hw_guard_wait(td);
323 307
324 r = taal_dcs_write_0(td, DCS_SLEEP_OUT); 308 r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
325 if (r) 309 if (r)
326 return r; 310 return r;
327 311
@@ -356,7 +340,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
356 u8 mode; 340 u8 mode;
357 int b5, b6, b7; 341 int b5, b6, b7;
358 342
359 r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode); 343 r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
360 if (r) 344 if (r)
361 return r; 345 return r;
362 346
@@ -390,7 +374,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
390 mode &= ~((1<<7) | (1<<6) | (1<<5)); 374 mode &= ~((1<<7) | (1<<6) | (1<<5));
391 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); 375 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
392 376
393 return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode); 377 return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
394} 378}
395 379
396static int taal_set_update_window(struct taal_data *td, 380static int taal_set_update_window(struct taal_data *td,
@@ -403,7 +387,7 @@ static int taal_set_update_window(struct taal_data *td,
403 u16 y2 = y + h - 1; 387 u16 y2 = y + h - 1;
404 388
405 u8 buf[5]; 389 u8 buf[5];
406 buf[0] = DCS_COLUMN_ADDR; 390 buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
407 buf[1] = (x1 >> 8) & 0xff; 391 buf[1] = (x1 >> 8) & 0xff;
408 buf[2] = (x1 >> 0) & 0xff; 392 buf[2] = (x1 >> 0) & 0xff;
409 buf[3] = (x2 >> 8) & 0xff; 393 buf[3] = (x2 >> 8) & 0xff;
@@ -413,7 +397,7 @@ static int taal_set_update_window(struct taal_data *td,
413 if (r) 397 if (r)
414 return r; 398 return r;
415 399
416 buf[0] = DCS_PAGE_ADDR; 400 buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
417 buf[1] = (y1 >> 8) & 0xff; 401 buf[1] = (y1 >> 8) & 0xff;
418 buf[2] = (y1 >> 0) & 0xff; 402 buf[2] = (y1 >> 0) & 0xff;
419 buf[3] = (y2 >> 8) & 0xff; 403 buf[3] = (y2 >> 8) & 0xff;
@@ -555,7 +539,6 @@ static int taal_bl_update_status(struct backlight_device *dev)
555{ 539{
556 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); 540 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
557 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 541 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
558 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
559 int r; 542 int r;
560 int level; 543 int level;
561 544
@@ -569,23 +552,16 @@ static int taal_bl_update_status(struct backlight_device *dev)
569 552
570 mutex_lock(&td->lock); 553 mutex_lock(&td->lock);
571 554
572 if (td->use_dsi_bl) { 555 if (td->enabled) {
573 if (td->enabled) { 556 dsi_bus_lock(dssdev);
574 dsi_bus_lock(dssdev);
575 557
576 r = taal_wake_up(dssdev); 558 r = taal_wake_up(dssdev);
577 if (!r) 559 if (!r)
578 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level); 560 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
579 561
580 dsi_bus_unlock(dssdev); 562 dsi_bus_unlock(dssdev);
581 } else {
582 r = 0;
583 }
584 } else { 563 } else {
585 if (!panel_data->set_backlight) 564 r = 0;
586 r = -EINVAL;
587 else
588 r = panel_data->set_backlight(dssdev, level);
589 } 565 }
590 566
591 mutex_unlock(&td->lock); 567 mutex_unlock(&td->lock);
@@ -964,7 +940,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
964{ 940{
965 struct backlight_properties props; 941 struct backlight_properties props;
966 struct taal_data *td; 942 struct taal_data *td;
967 struct backlight_device *bldev; 943 struct backlight_device *bldev = NULL;
968 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); 944 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
969 struct panel_config *panel_config = NULL; 945 struct panel_config *panel_config = NULL;
970 int r, i; 946 int r, i;
@@ -990,7 +966,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
990 966
991 dssdev->panel.config = OMAP_DSS_LCD_TFT; 967 dssdev->panel.config = OMAP_DSS_LCD_TFT;
992 dssdev->panel.timings = panel_config->timings; 968 dssdev->panel.timings = panel_config->timings;
993 dssdev->ctrl.pixel_size = 24; 969 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
994 970
995 td = kzalloc(sizeof(*td), GFP_KERNEL); 971 td = kzalloc(sizeof(*td), GFP_KERNEL);
996 if (!td) { 972 if (!td) {
@@ -1025,35 +1001,26 @@ static int taal_probe(struct omap_dss_device *dssdev)
1025 1001
1026 taal_hw_reset(dssdev); 1002 taal_hw_reset(dssdev);
1027 1003
1028 /* if no platform set_backlight() defined, presume DSI backlight 1004 if (panel_data->use_dsi_backlight) {
1029 * control */ 1005 memset(&props, 0, sizeof(struct backlight_properties));
1030 memset(&props, 0, sizeof(struct backlight_properties));
1031 if (!panel_data->set_backlight)
1032 td->use_dsi_bl = true;
1033
1034 if (td->use_dsi_bl)
1035 props.max_brightness = 255; 1006 props.max_brightness = 255;
1036 else
1037 props.max_brightness = 127;
1038
1039 props.type = BACKLIGHT_RAW;
1040 bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
1041 dssdev, &taal_bl_ops, &props);
1042 if (IS_ERR(bldev)) {
1043 r = PTR_ERR(bldev);
1044 goto err_bl;
1045 }
1046 1007
1047 td->bldev = bldev; 1008 props.type = BACKLIGHT_RAW;
1009 bldev = backlight_device_register(dev_name(&dssdev->dev),
1010 &dssdev->dev, dssdev, &taal_bl_ops, &props);
1011 if (IS_ERR(bldev)) {
1012 r = PTR_ERR(bldev);
1013 goto err_bl;
1014 }
1015
1016 td->bldev = bldev;
1048 1017
1049 bldev->props.fb_blank = FB_BLANK_UNBLANK; 1018 bldev->props.fb_blank = FB_BLANK_UNBLANK;
1050 bldev->props.power = FB_BLANK_UNBLANK; 1019 bldev->props.power = FB_BLANK_UNBLANK;
1051 if (td->use_dsi_bl)
1052 bldev->props.brightness = 255; 1020 bldev->props.brightness = 255;
1053 else
1054 bldev->props.brightness = 127;
1055 1021
1056 taal_bl_update_status(bldev); 1022 taal_bl_update_status(bldev);
1023 }
1057 1024
1058 if (panel_data->use_ext_te) { 1025 if (panel_data->use_ext_te) {
1059 int gpio = panel_data->ext_te_gpio; 1026 int gpio = panel_data->ext_te_gpio;
@@ -1111,7 +1078,8 @@ err_irq:
1111 if (panel_data->use_ext_te) 1078 if (panel_data->use_ext_te)
1112 gpio_free(panel_data->ext_te_gpio); 1079 gpio_free(panel_data->ext_te_gpio);
1113err_gpio: 1080err_gpio:
1114 backlight_device_unregister(bldev); 1081 if (bldev != NULL)
1082 backlight_device_unregister(bldev);
1115err_bl: 1083err_bl:
1116 destroy_workqueue(td->workqueue); 1084 destroy_workqueue(td->workqueue);
1117err_wq: 1085err_wq:
@@ -1140,9 +1108,11 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
1140 } 1108 }
1141 1109
1142 bldev = td->bldev; 1110 bldev = td->bldev;
1143 bldev->props.power = FB_BLANK_POWERDOWN; 1111 if (bldev != NULL) {
1144 taal_bl_update_status(bldev); 1112 bldev->props.power = FB_BLANK_POWERDOWN;
1145 backlight_device_unregister(bldev); 1113 taal_bl_update_status(bldev);
1114 backlight_device_unregister(bldev);
1115 }
1146 1116
1147 taal_cancel_ulps_work(dssdev); 1117 taal_cancel_ulps_work(dssdev);
1148 taal_cancel_esd_work(dssdev); 1118 taal_cancel_esd_work(dssdev);
@@ -1195,7 +1165,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1195 if (r) 1165 if (r)
1196 goto err; 1166 goto err;
1197 1167
1198 r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ 1168 r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
1169 MIPI_DCS_PIXEL_FMT_24BIT);
1199 if (r) 1170 if (r)
1200 goto err; 1171 goto err;
1201 1172
@@ -1209,7 +1180,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1209 goto err; 1180 goto err;
1210 } 1181 }
1211 1182
1212 r = taal_dcs_write_0(td, DCS_DISPLAY_ON); 1183 r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
1213 if (r) 1184 if (r)
1214 goto err; 1185 goto err;
1215 1186
@@ -1246,7 +1217,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
1246 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1217 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1247 int r; 1218 int r;
1248 1219
1249 r = taal_dcs_write_0(td, DCS_DISPLAY_OFF); 1220 r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
1250 if (!r) 1221 if (!r)
1251 r = taal_sleep_in(td); 1222 r = taal_sleep_in(td);
1252 1223
@@ -1529,9 +1500,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1529 int r; 1500 int r;
1530 1501
1531 if (enable) 1502 if (enable)
1532 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0); 1503 r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1533 else 1504 else
1534 r = taal_dcs_write_0(td, DCS_TEAR_OFF); 1505 r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
1535 1506
1536 if (!panel_data->use_ext_te) 1507 if (!panel_data->use_ext_te)
1537 omapdss_dsi_enable_te(dssdev, enable); 1508 omapdss_dsi_enable_te(dssdev, enable);
@@ -1851,7 +1822,7 @@ static void taal_esd_work(struct work_struct *work)
1851 goto err; 1822 goto err;
1852 } 1823 }
1853 1824
1854 r = taal_dcs_read_1(td, DCS_RDDSDR, &state1); 1825 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
1855 if (r) { 1826 if (r) {
1856 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1827 dev_err(&dssdev->dev, "failed to read Taal status\n");
1857 goto err; 1828 goto err;
@@ -1864,7 +1835,7 @@ static void taal_esd_work(struct work_struct *work)
1864 goto err; 1835 goto err;
1865 } 1836 }
1866 1837
1867 r = taal_dcs_read_1(td, DCS_RDDSDR, &state2); 1838 r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
1868 if (r) { 1839 if (r) {
1869 dev_err(&dssdev->dev, "failed to read Taal status\n"); 1840 dev_err(&dssdev->dev, "failed to read Taal status\n");
1870 goto err; 1841 goto err;
@@ -1880,7 +1851,7 @@ static void taal_esd_work(struct work_struct *work)
1880 /* Self-diagnostics result is also shown on TE GPIO line. We need 1851 /* Self-diagnostics result is also shown on TE GPIO line. We need
1881 * to re-enable TE after self diagnostics */ 1852 * to re-enable TE after self diagnostics */
1882 if (td->te_enabled && panel_data->use_ext_te) { 1853 if (td->te_enabled && panel_data->use_ext_te) {
1883 r = taal_dcs_write_1(td, DCS_TEAR_ON, 0); 1854 r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
1884 if (r) 1855 if (r)
1885 goto err; 1856 goto err;
1886 } 1857 }
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 0d12524db14b..7be7c06a249e 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,5 +1,5 @@
1menuconfig OMAP2_DSS 1menuconfig OMAP2_DSS
2 tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)" 2 tristate "OMAP2+ Display Subsystem support"
3 depends on ARCH_OMAP2PLUS 3 depends on ARCH_OMAP2PLUS
4 help 4 help
5 OMAP2+ Display Subsystem support. 5 OMAP2+ Display Subsystem support.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 10d9d3bb3e24..bd34ac5b2026 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -6,4 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 6omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 7omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ 8omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
9 hdmi_omap4_panel.o 9 hdmi_panel.o ti_hdmi_4xxx_ip.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 76821fefce9a..86ec12e16c7c 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -145,6 +145,10 @@ static int dss_initialize_debugfs(void)
145 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, 145 debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
146 &venc_dump_regs, &dss_debug_fops); 146 &venc_dump_regs, &dss_debug_fops);
147#endif 147#endif
148#ifdef CONFIG_OMAP4_DSS_HDMI
149 debugfs_create_file("hdmi", S_IRUGO, dss_debugfs_dir,
150 &hdmi_dump_regs, &dss_debug_fops);
151#endif
148 return 0; 152 return 0;
149} 153}
150 154
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0f3961a1ce26..6892cfd2e3b7 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -106,7 +106,7 @@ static struct {
106 int irq; 106 int irq;
107 struct clk *dss_clk; 107 struct clk *dss_clk;
108 108
109 u32 fifo_size[3]; 109 u32 fifo_size[MAX_DSS_OVERLAYS];
110 110
111 spinlock_t irq_lock; 111 spinlock_t irq_lock;
112 u32 irq_error_mask; 112 u32 irq_error_mask;
@@ -171,172 +171,98 @@ static int dispc_get_ctx_loss_count(void)
171 171
172static void dispc_save_context(void) 172static void dispc_save_context(void)
173{ 173{
174 int i; 174 int i, j;
175 175
176 DSSDBG("dispc_save_context\n"); 176 DSSDBG("dispc_save_context\n");
177 177
178 SR(IRQENABLE); 178 SR(IRQENABLE);
179 SR(CONTROL); 179 SR(CONTROL);
180 SR(CONFIG); 180 SR(CONFIG);
181 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
182 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
183 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
184 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
185 SR(LINE_NUMBER); 181 SR(LINE_NUMBER);
186 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD)); 182 if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
187 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 183 dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
188 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
189 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
190 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
191 SR(GLOBAL_ALPHA); 184 SR(GLOBAL_ALPHA);
192 SR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
193 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
194 if (dss_has_feature(FEAT_MGR_LCD2)) { 185 if (dss_has_feature(FEAT_MGR_LCD2)) {
195 SR(CONTROL2); 186 SR(CONTROL2);
196 SR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
197 SR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
198 SR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
199 SR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
200 SR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
201 SR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
202 SR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
203 SR(CONFIG2); 187 SR(CONFIG2);
204 } 188 }
205 189
206 SR(OVL_BA0(OMAP_DSS_GFX)); 190 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
207 SR(OVL_BA1(OMAP_DSS_GFX)); 191 SR(DEFAULT_COLOR(i));
208 SR(OVL_POSITION(OMAP_DSS_GFX)); 192 SR(TRANS_COLOR(i));
209 SR(OVL_SIZE(OMAP_DSS_GFX)); 193 SR(SIZE_MGR(i));
210 SR(OVL_ATTRIBUTES(OMAP_DSS_GFX)); 194 if (i == OMAP_DSS_CHANNEL_DIGIT)
211 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX)); 195 continue;
212 SR(OVL_ROW_INC(OMAP_DSS_GFX)); 196 SR(TIMING_H(i));
213 SR(OVL_PIXEL_INC(OMAP_DSS_GFX)); 197 SR(TIMING_V(i));
214 SR(OVL_WINDOW_SKIP(OMAP_DSS_GFX)); 198 SR(POL_FREQ(i));
215 SR(OVL_TABLE_BA(OMAP_DSS_GFX)); 199 SR(DIVISORo(i));
216 200
217 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD)); 201 SR(DATA_CYCLE1(i));
218 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 202 SR(DATA_CYCLE2(i));
219 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 203 SR(DATA_CYCLE3(i));
220 204
221 if (dss_has_feature(FEAT_CPR)) {
222 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
223 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
224 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
225 }
226 if (dss_has_feature(FEAT_MGR_LCD2)) {
227 if (dss_has_feature(FEAT_CPR)) { 205 if (dss_has_feature(FEAT_CPR)) {
228 SR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 206 SR(CPR_COEF_R(i));
229 SR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 207 SR(CPR_COEF_G(i));
230 SR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 208 SR(CPR_COEF_B(i));
231 } 209 }
232
233 SR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
234 SR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
235 SR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
236 } 210 }
237 211
238 if (dss_has_feature(FEAT_PRELOAD)) 212 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
239 SR(OVL_PRELOAD(OMAP_DSS_GFX)); 213 SR(OVL_BA0(i));
240 214 SR(OVL_BA1(i));
241 /* VID1 */ 215 SR(OVL_POSITION(i));
242 SR(OVL_BA0(OMAP_DSS_VIDEO1)); 216 SR(OVL_SIZE(i));
243 SR(OVL_BA1(OMAP_DSS_VIDEO1)); 217 SR(OVL_ATTRIBUTES(i));
244 SR(OVL_POSITION(OMAP_DSS_VIDEO1)); 218 SR(OVL_FIFO_THRESHOLD(i));
245 SR(OVL_SIZE(OMAP_DSS_VIDEO1)); 219 SR(OVL_ROW_INC(i));
246 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1)); 220 SR(OVL_PIXEL_INC(i));
247 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1)); 221 if (dss_has_feature(FEAT_PRELOAD))
248 SR(OVL_ROW_INC(OMAP_DSS_VIDEO1)); 222 SR(OVL_PRELOAD(i));
249 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1)); 223 if (i == OMAP_DSS_GFX) {
250 SR(OVL_FIR(OMAP_DSS_VIDEO1)); 224 SR(OVL_WINDOW_SKIP(i));
251 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1)); 225 SR(OVL_TABLE_BA(i));
252 SR(OVL_ACCU0(OMAP_DSS_VIDEO1)); 226 continue;
253 SR(OVL_ACCU1(OMAP_DSS_VIDEO1)); 227 }
254 228 SR(OVL_FIR(i));
255 for (i = 0; i < 8; i++) 229 SR(OVL_PICTURE_SIZE(i));
256 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i)); 230 SR(OVL_ACCU0(i));
257 231 SR(OVL_ACCU1(i));
258 for (i = 0; i < 8; i++)
259 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
260
261 for (i = 0; i < 5; i++)
262 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
263
264 if (dss_has_feature(FEAT_FIR_COEF_V)) {
265 for (i = 0; i < 8; i++)
266 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
267 }
268
269 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
270 SR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
271 SR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
272 SR(OVL_FIR2(OMAP_DSS_VIDEO1));
273 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
274 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
275
276 for (i = 0; i < 8; i++)
277 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
278
279 for (i = 0; i < 8; i++)
280 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
281
282 for (i = 0; i < 8; i++)
283 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
284 }
285 if (dss_has_feature(FEAT_ATTR2))
286 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
287
288 if (dss_has_feature(FEAT_PRELOAD))
289 SR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
290
291 /* VID2 */
292 SR(OVL_BA0(OMAP_DSS_VIDEO2));
293 SR(OVL_BA1(OMAP_DSS_VIDEO2));
294 SR(OVL_POSITION(OMAP_DSS_VIDEO2));
295 SR(OVL_SIZE(OMAP_DSS_VIDEO2));
296 SR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
297 SR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
298 SR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
299 SR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
300 SR(OVL_FIR(OMAP_DSS_VIDEO2));
301 SR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
302 SR(OVL_ACCU0(OMAP_DSS_VIDEO2));
303 SR(OVL_ACCU1(OMAP_DSS_VIDEO2));
304 232
305 for (i = 0; i < 8; i++) 233 for (j = 0; j < 8; j++)
306 SR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i)); 234 SR(OVL_FIR_COEF_H(i, j));
307 235
308 for (i = 0; i < 8; i++) 236 for (j = 0; j < 8; j++)
309 SR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i)); 237 SR(OVL_FIR_COEF_HV(i, j));
310 238
311 for (i = 0; i < 5; i++) 239 for (j = 0; j < 5; j++)
312 SR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 240 SR(OVL_CONV_COEF(i, j));
313 241
314 if (dss_has_feature(FEAT_FIR_COEF_V)) { 242 if (dss_has_feature(FEAT_FIR_COEF_V)) {
315 for (i = 0; i < 8; i++) 243 for (j = 0; j < 8; j++)
316 SR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 244 SR(OVL_FIR_COEF_V(i, j));
317 } 245 }
318 246
319 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 247 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
320 SR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); 248 SR(OVL_BA0_UV(i));
321 SR(OVL_BA1_UV(OMAP_DSS_VIDEO2)); 249 SR(OVL_BA1_UV(i));
322 SR(OVL_FIR2(OMAP_DSS_VIDEO2)); 250 SR(OVL_FIR2(i));
323 SR(OVL_ACCU2_0(OMAP_DSS_VIDEO2)); 251 SR(OVL_ACCU2_0(i));
324 SR(OVL_ACCU2_1(OMAP_DSS_VIDEO2)); 252 SR(OVL_ACCU2_1(i));
325 253
326 for (i = 0; i < 8; i++) 254 for (j = 0; j < 8; j++)
327 SR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i)); 255 SR(OVL_FIR_COEF_H2(i, j));
328 256
329 for (i = 0; i < 8; i++) 257 for (j = 0; j < 8; j++)
330 SR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i)); 258 SR(OVL_FIR_COEF_HV2(i, j));
331 259
332 for (i = 0; i < 8; i++) 260 for (j = 0; j < 8; j++)
333 SR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i)); 261 SR(OVL_FIR_COEF_V2(i, j));
262 }
263 if (dss_has_feature(FEAT_ATTR2))
264 SR(OVL_ATTRIBUTES2(i));
334 } 265 }
335 if (dss_has_feature(FEAT_ATTR2))
336 SR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
337
338 if (dss_has_feature(FEAT_PRELOAD))
339 SR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
340 266
341 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 267 if (dss_has_feature(FEAT_CORE_CLK_DIV))
342 SR(DIVISOR); 268 SR(DIVISOR);
@@ -349,7 +275,7 @@ static void dispc_save_context(void)
349 275
350static void dispc_restore_context(void) 276static void dispc_restore_context(void)
351{ 277{
352 int i, ctx; 278 int i, j, ctx;
353 279
354 DSSDBG("dispc_restore_context\n"); 280 DSSDBG("dispc_restore_context\n");
355 281
@@ -367,165 +293,89 @@ static void dispc_restore_context(void)
367 /*RR(IRQENABLE);*/ 293 /*RR(IRQENABLE);*/
368 /*RR(CONTROL);*/ 294 /*RR(CONTROL);*/
369 RR(CONFIG); 295 RR(CONFIG);
370 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
371 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
372 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
373 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
374 RR(LINE_NUMBER); 296 RR(LINE_NUMBER);
375 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD)); 297 if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
376 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD)); 298 dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
377 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD));
378 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD));
379 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
380 RR(GLOBAL_ALPHA); 299 RR(GLOBAL_ALPHA);
381 RR(SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT)); 300 if (dss_has_feature(FEAT_MGR_LCD2))
382 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
383 if (dss_has_feature(FEAT_MGR_LCD2)) {
384 RR(DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
385 RR(TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
386 RR(SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
387 RR(TIMING_H(OMAP_DSS_CHANNEL_LCD2));
388 RR(TIMING_V(OMAP_DSS_CHANNEL_LCD2));
389 RR(POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
390 RR(DIVISORo(OMAP_DSS_CHANNEL_LCD2));
391 RR(CONFIG2); 301 RR(CONFIG2);
392 }
393
394 RR(OVL_BA0(OMAP_DSS_GFX));
395 RR(OVL_BA1(OMAP_DSS_GFX));
396 RR(OVL_POSITION(OMAP_DSS_GFX));
397 RR(OVL_SIZE(OMAP_DSS_GFX));
398 RR(OVL_ATTRIBUTES(OMAP_DSS_GFX));
399 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
400 RR(OVL_ROW_INC(OMAP_DSS_GFX));
401 RR(OVL_PIXEL_INC(OMAP_DSS_GFX));
402 RR(OVL_WINDOW_SKIP(OMAP_DSS_GFX));
403 RR(OVL_TABLE_BA(OMAP_DSS_GFX));
404
405 302
406 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD)); 303 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
407 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD)); 304 RR(DEFAULT_COLOR(i));
408 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD)); 305 RR(TRANS_COLOR(i));
306 RR(SIZE_MGR(i));
307 if (i == OMAP_DSS_CHANNEL_DIGIT)
308 continue;
309 RR(TIMING_H(i));
310 RR(TIMING_V(i));
311 RR(POL_FREQ(i));
312 RR(DIVISORo(i));
409 313
410 if (dss_has_feature(FEAT_CPR)) { 314 RR(DATA_CYCLE1(i));
411 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD)); 315 RR(DATA_CYCLE2(i));
412 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD)); 316 RR(DATA_CYCLE3(i));
413 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
414 }
415 if (dss_has_feature(FEAT_MGR_LCD2)) {
416 RR(DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2));
417 RR(DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2));
418 RR(DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2));
419 317
420 if (dss_has_feature(FEAT_CPR)) { 318 if (dss_has_feature(FEAT_CPR)) {
421 RR(CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 319 RR(CPR_COEF_R(i));
422 RR(CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 320 RR(CPR_COEF_G(i));
423 RR(CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 321 RR(CPR_COEF_B(i));
424 } 322 }
425 } 323 }
426 324
427 if (dss_has_feature(FEAT_PRELOAD)) 325 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
428 RR(OVL_PRELOAD(OMAP_DSS_GFX)); 326 RR(OVL_BA0(i));
429 327 RR(OVL_BA1(i));
430 /* VID1 */ 328 RR(OVL_POSITION(i));
431 RR(OVL_BA0(OMAP_DSS_VIDEO1)); 329 RR(OVL_SIZE(i));
432 RR(OVL_BA1(OMAP_DSS_VIDEO1)); 330 RR(OVL_ATTRIBUTES(i));
433 RR(OVL_POSITION(OMAP_DSS_VIDEO1)); 331 RR(OVL_FIFO_THRESHOLD(i));
434 RR(OVL_SIZE(OMAP_DSS_VIDEO1)); 332 RR(OVL_ROW_INC(i));
435 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO1)); 333 RR(OVL_PIXEL_INC(i));
436 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1)); 334 if (dss_has_feature(FEAT_PRELOAD))
437 RR(OVL_ROW_INC(OMAP_DSS_VIDEO1)); 335 RR(OVL_PRELOAD(i));
438 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO1)); 336 if (i == OMAP_DSS_GFX) {
439 RR(OVL_FIR(OMAP_DSS_VIDEO1)); 337 RR(OVL_WINDOW_SKIP(i));
440 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1)); 338 RR(OVL_TABLE_BA(i));
441 RR(OVL_ACCU0(OMAP_DSS_VIDEO1)); 339 continue;
442 RR(OVL_ACCU1(OMAP_DSS_VIDEO1)); 340 }
443 341 RR(OVL_FIR(i));
444 for (i = 0; i < 8; i++) 342 RR(OVL_PICTURE_SIZE(i));
445 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, i)); 343 RR(OVL_ACCU0(i));
446 344 RR(OVL_ACCU1(i));
447 for (i = 0; i < 8; i++)
448 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, i));
449
450 for (i = 0; i < 5; i++)
451 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO1, i));
452
453 if (dss_has_feature(FEAT_FIR_COEF_V)) {
454 for (i = 0; i < 8; i++)
455 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, i));
456 }
457
458 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
459 RR(OVL_BA0_UV(OMAP_DSS_VIDEO1));
460 RR(OVL_BA1_UV(OMAP_DSS_VIDEO1));
461 RR(OVL_FIR2(OMAP_DSS_VIDEO1));
462 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO1));
463 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO1));
464
465 for (i = 0; i < 8; i++)
466 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, i));
467
468 for (i = 0; i < 8; i++)
469 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, i));
470
471 for (i = 0; i < 8; i++)
472 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, i));
473 }
474 if (dss_has_feature(FEAT_ATTR2))
475 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
476
477 if (dss_has_feature(FEAT_PRELOAD))
478 RR(OVL_PRELOAD(OMAP_DSS_VIDEO1));
479
480 /* VID2 */
481 RR(OVL_BA0(OMAP_DSS_VIDEO2));
482 RR(OVL_BA1(OMAP_DSS_VIDEO2));
483 RR(OVL_POSITION(OMAP_DSS_VIDEO2));
484 RR(OVL_SIZE(OMAP_DSS_VIDEO2));
485 RR(OVL_ATTRIBUTES(OMAP_DSS_VIDEO2));
486 RR(OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2));
487 RR(OVL_ROW_INC(OMAP_DSS_VIDEO2));
488 RR(OVL_PIXEL_INC(OMAP_DSS_VIDEO2));
489 RR(OVL_FIR(OMAP_DSS_VIDEO2));
490 RR(OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2));
491 RR(OVL_ACCU0(OMAP_DSS_VIDEO2));
492 RR(OVL_ACCU1(OMAP_DSS_VIDEO2));
493 345
494 for (i = 0; i < 8; i++) 346 for (j = 0; j < 8; j++)
495 RR(OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, i)); 347 RR(OVL_FIR_COEF_H(i, j));
496 348
497 for (i = 0; i < 8; i++) 349 for (j = 0; j < 8; j++)
498 RR(OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, i)); 350 RR(OVL_FIR_COEF_HV(i, j));
499 351
500 for (i = 0; i < 5; i++) 352 for (j = 0; j < 5; j++)
501 RR(OVL_CONV_COEF(OMAP_DSS_VIDEO2, i)); 353 RR(OVL_CONV_COEF(i, j));
502 354
503 if (dss_has_feature(FEAT_FIR_COEF_V)) { 355 if (dss_has_feature(FEAT_FIR_COEF_V)) {
504 for (i = 0; i < 8; i++) 356 for (j = 0; j < 8; j++)
505 RR(OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, i)); 357 RR(OVL_FIR_COEF_V(i, j));
506 } 358 }
507 359
508 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) { 360 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
509 RR(OVL_BA0_UV(OMAP_DSS_VIDEO2)); 361 RR(OVL_BA0_UV(i));
510 RR(OVL_BA1_UV(OMAP_DSS_VIDEO2)); 362 RR(OVL_BA1_UV(i));
511 RR(OVL_FIR2(OMAP_DSS_VIDEO2)); 363 RR(OVL_FIR2(i));
512 RR(OVL_ACCU2_0(OMAP_DSS_VIDEO2)); 364 RR(OVL_ACCU2_0(i));
513 RR(OVL_ACCU2_1(OMAP_DSS_VIDEO2)); 365 RR(OVL_ACCU2_1(i));
514 366
515 for (i = 0; i < 8; i++) 367 for (j = 0; j < 8; j++)
516 RR(OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, i)); 368 RR(OVL_FIR_COEF_H2(i, j));
517 369
518 for (i = 0; i < 8; i++) 370 for (j = 0; j < 8; j++)
519 RR(OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, i)); 371 RR(OVL_FIR_COEF_HV2(i, j));
520 372
521 for (i = 0; i < 8; i++) 373 for (j = 0; j < 8; j++)
522 RR(OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, i)); 374 RR(OVL_FIR_COEF_V2(i, j));
375 }
376 if (dss_has_feature(FEAT_ATTR2))
377 RR(OVL_ATTRIBUTES2(i));
523 } 378 }
524 if (dss_has_feature(FEAT_ATTR2))
525 RR(OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
526
527 if (dss_has_feature(FEAT_PRELOAD))
528 RR(OVL_PRELOAD(OMAP_DSS_VIDEO2));
529 379
530 if (dss_has_feature(FEAT_CORE_CLK_DIV)) 380 if (dss_has_feature(FEAT_CORE_CLK_DIV))
531 RR(DIVISOR); 381 RR(DIVISOR);
@@ -570,13 +420,28 @@ void dispc_runtime_put(void)
570 WARN_ON(r < 0); 420 WARN_ON(r < 0);
571} 421}
572 422
423static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
424{
425 if (channel == OMAP_DSS_CHANNEL_LCD ||
426 channel == OMAP_DSS_CHANNEL_LCD2)
427 return true;
428 else
429 return false;
430}
431
432static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
433{
434 struct omap_overlay_manager *mgr =
435 omap_dss_get_overlay_manager(channel);
573 436
574bool dispc_go_busy(enum omap_channel channel) 437 return mgr ? mgr->device : NULL;
438}
439
440bool dispc_mgr_go_busy(enum omap_channel channel)
575{ 441{
576 int bit; 442 int bit;
577 443
578 if (channel == OMAP_DSS_CHANNEL_LCD || 444 if (dispc_mgr_is_lcd(channel))
579 channel == OMAP_DSS_CHANNEL_LCD2)
580 bit = 5; /* GOLCD */ 445 bit = 5; /* GOLCD */
581 else 446 else
582 bit = 6; /* GODIGIT */ 447 bit = 6; /* GODIGIT */
@@ -587,13 +452,12 @@ bool dispc_go_busy(enum omap_channel channel)
587 return REG_GET(DISPC_CONTROL, bit, bit) == 1; 452 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
588} 453}
589 454
590void dispc_go(enum omap_channel channel) 455void dispc_mgr_go(enum omap_channel channel)
591{ 456{
592 int bit; 457 int bit;
593 bool enable_bit, go_bit; 458 bool enable_bit, go_bit;
594 459
595 if (channel == OMAP_DSS_CHANNEL_LCD || 460 if (dispc_mgr_is_lcd(channel))
596 channel == OMAP_DSS_CHANNEL_LCD2)
597 bit = 0; /* LCDENABLE */ 461 bit = 0; /* LCDENABLE */
598 else 462 else
599 bit = 1; /* DIGITALENABLE */ 463 bit = 1; /* DIGITALENABLE */
@@ -607,8 +471,7 @@ void dispc_go(enum omap_channel channel)
607 if (!enable_bit) 471 if (!enable_bit)
608 return; 472 return;
609 473
610 if (channel == OMAP_DSS_CHANNEL_LCD || 474 if (dispc_mgr_is_lcd(channel))
611 channel == OMAP_DSS_CHANNEL_LCD2)
612 bit = 5; /* GOLCD */ 475 bit = 5; /* GOLCD */
613 else 476 else
614 bit = 6; /* GODIGIT */ 477 bit = 6; /* GODIGIT */
@@ -632,43 +495,44 @@ void dispc_go(enum omap_channel channel)
632 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 495 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
633} 496}
634 497
635static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) 498static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
636{ 499{
637 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); 500 dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
638} 501}
639 502
640static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value) 503static void dispc_ovl_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
641{ 504{
642 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value); 505 dispc_write_reg(DISPC_OVL_FIR_COEF_HV(plane, reg), value);
643} 506}
644 507
645static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value) 508static void dispc_ovl_write_firv_reg(enum omap_plane plane, int reg, u32 value)
646{ 509{
647 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value); 510 dispc_write_reg(DISPC_OVL_FIR_COEF_V(plane, reg), value);
648} 511}
649 512
650static void _dispc_write_firh2_reg(enum omap_plane plane, int reg, u32 value) 513static void dispc_ovl_write_firh2_reg(enum omap_plane plane, int reg, u32 value)
651{ 514{
652 BUG_ON(plane == OMAP_DSS_GFX); 515 BUG_ON(plane == OMAP_DSS_GFX);
653 516
654 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value); 517 dispc_write_reg(DISPC_OVL_FIR_COEF_H2(plane, reg), value);
655} 518}
656 519
657static void _dispc_write_firhv2_reg(enum omap_plane plane, int reg, u32 value) 520static void dispc_ovl_write_firhv2_reg(enum omap_plane plane, int reg,
521 u32 value)
658{ 522{
659 BUG_ON(plane == OMAP_DSS_GFX); 523 BUG_ON(plane == OMAP_DSS_GFX);
660 524
661 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value); 525 dispc_write_reg(DISPC_OVL_FIR_COEF_HV2(plane, reg), value);
662} 526}
663 527
664static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value) 528static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
665{ 529{
666 BUG_ON(plane == OMAP_DSS_GFX); 530 BUG_ON(plane == OMAP_DSS_GFX);
667 531
668 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value); 532 dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
669} 533}
670 534
671static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup, 535static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
672 int vscaleup, int five_taps, 536 int vscaleup, int five_taps,
673 enum omap_color_component color_comp) 537 enum omap_color_component color_comp)
674{ 538{
@@ -769,11 +633,11 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
769 | FLD_VAL(v_coef[i].vc2, 31, 24); 633 | FLD_VAL(v_coef[i].vc2, 31, 24);
770 634
771 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) { 635 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
772 _dispc_write_firh_reg(plane, i, h); 636 dispc_ovl_write_firh_reg(plane, i, h);
773 _dispc_write_firhv_reg(plane, i, hv); 637 dispc_ovl_write_firhv_reg(plane, i, hv);
774 } else { 638 } else {
775 _dispc_write_firh2_reg(plane, i, h); 639 dispc_ovl_write_firh2_reg(plane, i, h);
776 _dispc_write_firhv2_reg(plane, i, hv); 640 dispc_ovl_write_firhv2_reg(plane, i, hv);
777 } 641 }
778 642
779 } 643 }
@@ -784,15 +648,16 @@ static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
784 v = FLD_VAL(v_coef[i].vc00, 7, 0) 648 v = FLD_VAL(v_coef[i].vc00, 7, 0)
785 | FLD_VAL(v_coef[i].vc22, 15, 8); 649 | FLD_VAL(v_coef[i].vc22, 15, 8);
786 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) 650 if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
787 _dispc_write_firv_reg(plane, i, v); 651 dispc_ovl_write_firv_reg(plane, i, v);
788 else 652 else
789 _dispc_write_firv2_reg(plane, i, v); 653 dispc_ovl_write_firv2_reg(plane, i, v);
790 } 654 }
791 } 655 }
792} 656}
793 657
794static void _dispc_setup_color_conv_coef(void) 658static void _dispc_setup_color_conv_coef(void)
795{ 659{
660 int i;
796 const struct color_conv_coef { 661 const struct color_conv_coef {
797 int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; 662 int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
798 int full_range; 663 int full_range;
@@ -806,65 +671,54 @@ static void _dispc_setup_color_conv_coef(void)
806 671
807 ct = &ctbl_bt601_5; 672 ct = &ctbl_bt601_5;
808 673
809 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0), 674 for (i = 1; i < dss_feat_get_num_ovls(); i++) {
810 CVAL(ct->rcr, ct->ry)); 675 dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0),
811 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1), 676 CVAL(ct->rcr, ct->ry));
812 CVAL(ct->gy, ct->rcb)); 677 dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1),
813 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2), 678 CVAL(ct->gy, ct->rcb));
814 CVAL(ct->gcb, ct->gcr)); 679 dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2),
815 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3), 680 CVAL(ct->gcb, ct->gcr));
816 CVAL(ct->bcr, ct->by)); 681 dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3),
817 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4), 682 CVAL(ct->bcr, ct->by));
818 CVAL(0, ct->bcb)); 683 dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4),
819 684 CVAL(0, ct->bcb));
820 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0),
821 CVAL(ct->rcr, ct->ry));
822 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1),
823 CVAL(ct->gy, ct->rcb));
824 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2),
825 CVAL(ct->gcb, ct->gcr));
826 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3),
827 CVAL(ct->bcr, ct->by));
828 dispc_write_reg(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4),
829 CVAL(0, ct->bcb));
830 685
831#undef CVAL 686 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range,
687 11, 11);
688 }
832 689
833 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1), 690#undef CVAL
834 ct->full_range, 11, 11);
835 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2),
836 ct->full_range, 11, 11);
837} 691}
838 692
839 693
840static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr) 694static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr)
841{ 695{
842 dispc_write_reg(DISPC_OVL_BA0(plane), paddr); 696 dispc_write_reg(DISPC_OVL_BA0(plane), paddr);
843} 697}
844 698
845static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr) 699static void dispc_ovl_set_ba1(enum omap_plane plane, u32 paddr)
846{ 700{
847 dispc_write_reg(DISPC_OVL_BA1(plane), paddr); 701 dispc_write_reg(DISPC_OVL_BA1(plane), paddr);
848} 702}
849 703
850static void _dispc_set_plane_ba0_uv(enum omap_plane plane, u32 paddr) 704static void dispc_ovl_set_ba0_uv(enum omap_plane plane, u32 paddr)
851{ 705{
852 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr); 706 dispc_write_reg(DISPC_OVL_BA0_UV(plane), paddr);
853} 707}
854 708
855static void _dispc_set_plane_ba1_uv(enum omap_plane plane, u32 paddr) 709static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr)
856{ 710{
857 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); 711 dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
858} 712}
859 713
860static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y) 714static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
861{ 715{
862 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); 716 u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
863 717
864 dispc_write_reg(DISPC_OVL_POSITION(plane), val); 718 dispc_write_reg(DISPC_OVL_POSITION(plane), val);
865} 719}
866 720
867static void _dispc_set_pic_size(enum omap_plane plane, int width, int height) 721static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
868{ 722{
869 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 723 u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
870 724
@@ -874,7 +728,7 @@ static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
874 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); 728 dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
875} 729}
876 730
877static void _dispc_set_vid_size(enum omap_plane plane, int width, int height) 731static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
878{ 732{
879 u32 val; 733 u32 val;
880 734
@@ -885,44 +739,61 @@ static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
885 dispc_write_reg(DISPC_OVL_SIZE(plane), val); 739 dispc_write_reg(DISPC_OVL_SIZE(plane), val);
886} 740}
887 741
888static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable) 742static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
889{ 743{
890 if (!dss_has_feature(FEAT_PRE_MULT_ALPHA)) 744 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
745
746 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
891 return; 747 return;
892 748
893 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) && 749 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
894 plane == OMAP_DSS_VIDEO1) 750}
751
752static void dispc_ovl_enable_zorder_planes(void)
753{
754 int i;
755
756 if (!dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
895 return; 757 return;
896 758
897 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); 759 for (i = 0; i < dss_feat_get_num_ovls(); i++)
760 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
898} 761}
899 762
900static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) 763static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
901{ 764{
902 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 765 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
766
767 if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
903 return; 768 return;
904 769
905 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) && 770 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
906 plane == OMAP_DSS_VIDEO1) 771}
772
773static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
774{
775 static const unsigned shifts[] = { 0, 8, 16, 24, };
776 int shift;
777 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
778
779 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
907 return; 780 return;
908 781
909 if (plane == OMAP_DSS_GFX) 782 shift = shifts[plane];
910 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0); 783 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, shift + 7, shift);
911 else if (plane == OMAP_DSS_VIDEO2)
912 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 23, 16);
913} 784}
914 785
915static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc) 786static void dispc_ovl_set_pix_inc(enum omap_plane plane, s32 inc)
916{ 787{
917 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc); 788 dispc_write_reg(DISPC_OVL_PIXEL_INC(plane), inc);
918} 789}
919 790
920static void _dispc_set_row_inc(enum omap_plane plane, s32 inc) 791static void dispc_ovl_set_row_inc(enum omap_plane plane, s32 inc)
921{ 792{
922 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc); 793 dispc_write_reg(DISPC_OVL_ROW_INC(plane), inc);
923} 794}
924 795
925static void _dispc_set_color_mode(enum omap_plane plane, 796static void dispc_ovl_set_color_mode(enum omap_plane plane,
926 enum omap_color_mode color_mode) 797 enum omap_color_mode color_mode)
927{ 798{
928 u32 m = 0; 799 u32 m = 0;
@@ -1003,7 +874,7 @@ static void _dispc_set_color_mode(enum omap_plane plane,
1003 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1); 874 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
1004} 875}
1005 876
1006void dispc_set_channel_out(enum omap_plane plane, 877static void dispc_ovl_set_channel_out(enum omap_plane plane,
1007 enum omap_channel channel) 878 enum omap_channel channel)
1008{ 879{
1009 int shift; 880 int shift;
@@ -1016,6 +887,7 @@ void dispc_set_channel_out(enum omap_plane plane,
1016 break; 887 break;
1017 case OMAP_DSS_VIDEO1: 888 case OMAP_DSS_VIDEO1:
1018 case OMAP_DSS_VIDEO2: 889 case OMAP_DSS_VIDEO2:
890 case OMAP_DSS_VIDEO3:
1019 shift = 16; 891 shift = 16;
1020 break; 892 break;
1021 default: 893 default:
@@ -1050,24 +922,13 @@ void dispc_set_channel_out(enum omap_plane plane,
1050 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 922 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1051} 923}
1052 924
1053static void dispc_set_burst_size(enum omap_plane plane, 925static void dispc_ovl_set_burst_size(enum omap_plane plane,
1054 enum omap_burst_size burst_size) 926 enum omap_burst_size burst_size)
1055{ 927{
928 static const unsigned shifts[] = { 6, 14, 14, 14, };
1056 int shift; 929 int shift;
1057 930
1058 switch (plane) { 931 shift = shifts[plane];
1059 case OMAP_DSS_GFX:
1060 shift = 6;
1061 break;
1062 case OMAP_DSS_VIDEO1:
1063 case OMAP_DSS_VIDEO2:
1064 shift = 14;
1065 break;
1066 default:
1067 BUG();
1068 return;
1069 }
1070
1071 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift); 932 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), burst_size, shift + 1, shift);
1072} 933}
1073 934
@@ -1078,10 +939,10 @@ static void dispc_configure_burst_sizes(void)
1078 939
1079 /* Configure burst size always to maximum size */ 940 /* Configure burst size always to maximum size */
1080 for (i = 0; i < omap_dss_get_num_overlays(); ++i) 941 for (i = 0; i < omap_dss_get_num_overlays(); ++i)
1081 dispc_set_burst_size(i, burst_size); 942 dispc_ovl_set_burst_size(i, burst_size);
1082} 943}
1083 944
1084u32 dispc_get_burst_size(enum omap_plane plane) 945u32 dispc_ovl_get_burst_size(enum omap_plane plane)
1085{ 946{
1086 unsigned unit = dss_feat_get_burst_size_unit(); 947 unsigned unit = dss_feat_get_burst_size_unit();
1087 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ 948 /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */
@@ -1102,7 +963,7 @@ void dispc_enable_gamma_table(bool enable)
1102 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); 963 REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
1103} 964}
1104 965
1105void dispc_enable_cpr(enum omap_channel channel, bool enable) 966void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
1106{ 967{
1107 u16 reg; 968 u16 reg;
1108 969
@@ -1116,12 +977,12 @@ void dispc_enable_cpr(enum omap_channel channel, bool enable)
1116 REG_FLD_MOD(reg, enable, 15, 15); 977 REG_FLD_MOD(reg, enable, 15, 15);
1117} 978}
1118 979
1119void dispc_set_cpr_coef(enum omap_channel channel, 980void dispc_mgr_set_cpr_coef(enum omap_channel channel,
1120 struct omap_dss_cpr_coefs *coefs) 981 struct omap_dss_cpr_coefs *coefs)
1121{ 982{
1122 u32 coef_r, coef_g, coef_b; 983 u32 coef_r, coef_g, coef_b;
1123 984
1124 if (channel != OMAP_DSS_CHANNEL_LCD && channel != OMAP_DSS_CHANNEL_LCD2) 985 if (!dispc_mgr_is_lcd(channel))
1125 return; 986 return;
1126 987
1127 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) | 988 coef_r = FLD_VAL(coefs->rr, 31, 22) | FLD_VAL(coefs->rg, 20, 11) |
@@ -1136,7 +997,7 @@ void dispc_set_cpr_coef(enum omap_channel channel,
1136 dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b); 997 dispc_write_reg(DISPC_CPR_COEF_B(channel), coef_b);
1137} 998}
1138 999
1139static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) 1000static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
1140{ 1001{
1141 u32 val; 1002 u32 val;
1142 1003
@@ -1147,19 +1008,16 @@ static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
1147 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); 1008 dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
1148} 1009}
1149 1010
1150void dispc_enable_replication(enum omap_plane plane, bool enable) 1011static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
1151{ 1012{
1152 int bit; 1013 static const unsigned shifts[] = { 5, 10, 10, 10 };
1153 1014 int shift;
1154 if (plane == OMAP_DSS_GFX)
1155 bit = 5;
1156 else
1157 bit = 10;
1158 1015
1159 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit); 1016 shift = shifts[plane];
1017 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
1160} 1018}
1161 1019
1162void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height) 1020void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
1163{ 1021{
1164 u32 val; 1022 u32 val;
1165 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1023 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
@@ -1186,19 +1044,20 @@ static void dispc_read_plane_fifo_sizes(void)
1186 1044
1187 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end); 1045 dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
1188 1046
1189 for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { 1047 for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
1190 size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end); 1048 size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
1191 size *= unit; 1049 size *= unit;
1192 dispc.fifo_size[plane] = size; 1050 dispc.fifo_size[plane] = size;
1193 } 1051 }
1194} 1052}
1195 1053
1196u32 dispc_get_plane_fifo_size(enum omap_plane plane) 1054u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
1197{ 1055{
1198 return dispc.fifo_size[plane]; 1056 return dispc.fifo_size[plane];
1199} 1057}
1200 1058
1201void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) 1059static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low,
1060 u32 high)
1202{ 1061{
1203 u8 hi_start, hi_end, lo_start, lo_end; 1062 u8 hi_start, hi_end, lo_start, lo_end;
1204 u32 unit; 1063 u32 unit;
@@ -1233,7 +1092,7 @@ void dispc_enable_fifomerge(bool enable)
1233 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); 1092 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
1234} 1093}
1235 1094
1236static void _dispc_set_fir(enum omap_plane plane, 1095static void dispc_ovl_set_fir(enum omap_plane plane,
1237 int hinc, int vinc, 1096 int hinc, int vinc,
1238 enum omap_color_component color_comp) 1097 enum omap_color_component color_comp)
1239{ 1098{
@@ -1256,7 +1115,7 @@ static void _dispc_set_fir(enum omap_plane plane,
1256 } 1115 }
1257} 1116}
1258 1117
1259static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) 1118static void dispc_ovl_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1260{ 1119{
1261 u32 val; 1120 u32 val;
1262 u8 hor_start, hor_end, vert_start, vert_end; 1121 u8 hor_start, hor_end, vert_start, vert_end;
@@ -1270,7 +1129,7 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
1270 dispc_write_reg(DISPC_OVL_ACCU0(plane), val); 1129 dispc_write_reg(DISPC_OVL_ACCU0(plane), val);
1271} 1130}
1272 1131
1273static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) 1132static void dispc_ovl_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1274{ 1133{
1275 u32 val; 1134 u32 val;
1276 u8 hor_start, hor_end, vert_start, vert_end; 1135 u8 hor_start, hor_end, vert_start, vert_end;
@@ -1284,7 +1143,8 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
1284 dispc_write_reg(DISPC_OVL_ACCU1(plane), val); 1143 dispc_write_reg(DISPC_OVL_ACCU1(plane), val);
1285} 1144}
1286 1145
1287static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu) 1146static void dispc_ovl_set_vid_accu2_0(enum omap_plane plane, int haccu,
1147 int vaccu)
1288{ 1148{
1289 u32 val; 1149 u32 val;
1290 1150
@@ -1292,7 +1152,8 @@ static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu)
1292 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val); 1152 dispc_write_reg(DISPC_OVL_ACCU2_0(plane), val);
1293} 1153}
1294 1154
1295static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu) 1155static void dispc_ovl_set_vid_accu2_1(enum omap_plane plane, int haccu,
1156 int vaccu)
1296{ 1157{
1297 u32 val; 1158 u32 val;
1298 1159
@@ -1300,7 +1161,7 @@ static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu)
1300 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val); 1161 dispc_write_reg(DISPC_OVL_ACCU2_1(plane), val);
1301} 1162}
1302 1163
1303static void _dispc_set_scale_param(enum omap_plane plane, 1164static void dispc_ovl_set_scale_param(enum omap_plane plane,
1304 u16 orig_width, u16 orig_height, 1165 u16 orig_width, u16 orig_height,
1305 u16 out_width, u16 out_height, 1166 u16 out_width, u16 out_height,
1306 bool five_taps, u8 rotation, 1167 bool five_taps, u8 rotation,
@@ -1312,15 +1173,16 @@ static void _dispc_set_scale_param(enum omap_plane plane,
1312 hscaleup = orig_width <= out_width; 1173 hscaleup = orig_width <= out_width;
1313 vscaleup = orig_height <= out_height; 1174 vscaleup = orig_height <= out_height;
1314 1175
1315 _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps, color_comp); 1176 dispc_ovl_set_scale_coef(plane, hscaleup, vscaleup, five_taps,
1177 color_comp);
1316 1178
1317 fir_hinc = 1024 * orig_width / out_width; 1179 fir_hinc = 1024 * orig_width / out_width;
1318 fir_vinc = 1024 * orig_height / out_height; 1180 fir_vinc = 1024 * orig_height / out_height;
1319 1181
1320 _dispc_set_fir(plane, fir_hinc, fir_vinc, color_comp); 1182 dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp);
1321} 1183}
1322 1184
1323static void _dispc_set_scaling_common(enum omap_plane plane, 1185static void dispc_ovl_set_scaling_common(enum omap_plane plane,
1324 u16 orig_width, u16 orig_height, 1186 u16 orig_width, u16 orig_height,
1325 u16 out_width, u16 out_height, 1187 u16 out_width, u16 out_height,
1326 bool ilace, bool five_taps, 1188 bool ilace, bool five_taps,
@@ -1331,7 +1193,7 @@ static void _dispc_set_scaling_common(enum omap_plane plane,
1331 int accu1 = 0; 1193 int accu1 = 0;
1332 u32 l; 1194 u32 l;
1333 1195
1334 _dispc_set_scale_param(plane, orig_width, orig_height, 1196 dispc_ovl_set_scale_param(plane, orig_width, orig_height,
1335 out_width, out_height, five_taps, 1197 out_width, out_height, five_taps,
1336 rotation, DISPC_COLOR_COMPONENT_RGB_Y); 1198 rotation, DISPC_COLOR_COMPONENT_RGB_Y);
1337 l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 1199 l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
@@ -1370,11 +1232,11 @@ static void _dispc_set_scaling_common(enum omap_plane plane,
1370 } 1232 }
1371 } 1233 }
1372 1234
1373 _dispc_set_vid_accu0(plane, 0, accu0); 1235 dispc_ovl_set_vid_accu0(plane, 0, accu0);
1374 _dispc_set_vid_accu1(plane, 0, accu1); 1236 dispc_ovl_set_vid_accu1(plane, 0, accu1);
1375} 1237}
1376 1238
1377static void _dispc_set_scaling_uv(enum omap_plane plane, 1239static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
1378 u16 orig_width, u16 orig_height, 1240 u16 orig_width, u16 orig_height,
1379 u16 out_width, u16 out_height, 1241 u16 out_width, u16 out_height,
1380 bool ilace, bool five_taps, 1242 bool ilace, bool five_taps,
@@ -1422,7 +1284,7 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
1422 if (out_height != orig_height) 1284 if (out_height != orig_height)
1423 scale_y = true; 1285 scale_y = true;
1424 1286
1425 _dispc_set_scale_param(plane, orig_width, orig_height, 1287 dispc_ovl_set_scale_param(plane, orig_width, orig_height,
1426 out_width, out_height, five_taps, 1288 out_width, out_height, five_taps,
1427 rotation, DISPC_COLOR_COMPONENT_UV); 1289 rotation, DISPC_COLOR_COMPONENT_UV);
1428 1290
@@ -1433,11 +1295,11 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
1433 /* set V scaling */ 1295 /* set V scaling */
1434 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6); 1296 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_y ? 1 : 0, 6, 6);
1435 1297
1436 _dispc_set_vid_accu2_0(plane, 0x80, 0); 1298 dispc_ovl_set_vid_accu2_0(plane, 0x80, 0);
1437 _dispc_set_vid_accu2_1(plane, 0x80, 0); 1299 dispc_ovl_set_vid_accu2_1(plane, 0x80, 0);
1438} 1300}
1439 1301
1440static void _dispc_set_scaling(enum omap_plane plane, 1302static void dispc_ovl_set_scaling(enum omap_plane plane,
1441 u16 orig_width, u16 orig_height, 1303 u16 orig_width, u16 orig_height,
1442 u16 out_width, u16 out_height, 1304 u16 out_width, u16 out_height,
1443 bool ilace, bool five_taps, 1305 bool ilace, bool five_taps,
@@ -1446,14 +1308,14 @@ static void _dispc_set_scaling(enum omap_plane plane,
1446{ 1308{
1447 BUG_ON(plane == OMAP_DSS_GFX); 1309 BUG_ON(plane == OMAP_DSS_GFX);
1448 1310
1449 _dispc_set_scaling_common(plane, 1311 dispc_ovl_set_scaling_common(plane,
1450 orig_width, orig_height, 1312 orig_width, orig_height,
1451 out_width, out_height, 1313 out_width, out_height,
1452 ilace, five_taps, 1314 ilace, five_taps,
1453 fieldmode, color_mode, 1315 fieldmode, color_mode,
1454 rotation); 1316 rotation);
1455 1317
1456 _dispc_set_scaling_uv(plane, 1318 dispc_ovl_set_scaling_uv(plane,
1457 orig_width, orig_height, 1319 orig_width, orig_height,
1458 out_width, out_height, 1320 out_width, out_height,
1459 ilace, five_taps, 1321 ilace, five_taps,
@@ -1461,7 +1323,7 @@ static void _dispc_set_scaling(enum omap_plane plane,
1461 rotation); 1323 rotation);
1462} 1324}
1463 1325
1464static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1326static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1465 bool mirroring, enum omap_color_mode color_mode) 1327 bool mirroring, enum omap_color_mode color_mode)
1466{ 1328{
1467 bool row_repeat = false; 1329 bool row_repeat = false;
@@ -1789,12 +1651,11 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1789 enum omap_color_mode color_mode) 1651 enum omap_color_mode color_mode)
1790{ 1652{
1791 u32 fclk = 0; 1653 u32 fclk = 0;
1792 /* FIXME venc pclk? */ 1654 u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
1793 u64 tmp, pclk = dispc_pclk_rate(channel);
1794 1655
1795 if (height > out_height) { 1656 if (height > out_height) {
1796 /* FIXME get real display PPL */ 1657 struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
1797 unsigned int ppl = 800; 1658 unsigned int ppl = dssdev->panel.timings.x_res;
1798 1659
1799 tmp = pclk * height * out_width; 1660 tmp = pclk * height * out_width;
1800 do_div(tmp, 2 * out_height * ppl); 1661 do_div(tmp, 2 * out_height * ppl);
@@ -1846,114 +1707,120 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1846 else 1707 else
1847 vf = 1; 1708 vf = 1;
1848 1709
1849 /* FIXME venc pclk? */ 1710 return dispc_mgr_pclk_rate(channel) * vf * hf;
1850 return dispc_pclk_rate(channel) * vf * hf;
1851} 1711}
1852 1712
1853int dispc_setup_plane(enum omap_plane plane, 1713static int dispc_ovl_calc_scaling(enum omap_plane plane,
1854 u32 paddr, u16 screen_width, 1714 enum omap_channel channel, u16 width, u16 height,
1855 u16 pos_x, u16 pos_y,
1856 u16 width, u16 height,
1857 u16 out_width, u16 out_height, 1715 u16 out_width, u16 out_height,
1858 enum omap_color_mode color_mode, 1716 enum omap_color_mode color_mode, bool *five_taps)
1859 bool ilace, 1717{
1860 enum omap_dss_rotation_type rotation_type, 1718 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
1861 u8 rotation, bool mirror, 1719 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
1862 u8 global_alpha, u8 pre_mult_alpha, 1720 unsigned long fclk = 0;
1863 enum omap_channel channel, u32 puv_addr)
1864{
1865 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1866 bool five_taps = 0;
1867 bool fieldmode = 0;
1868 int cconv = 0;
1869 unsigned offset0, offset1;
1870 s32 row_inc;
1871 s32 pix_inc;
1872 u16 frame_height = height;
1873 unsigned int field_offset = 0;
1874 1721
1875 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 1722 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
1876 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n", 1723 if (width != out_width || height != out_height)
1877 plane, paddr, screen_width, pos_x, pos_y, 1724 return -EINVAL;
1878 width, height, 1725 else
1879 out_width, out_height, 1726 return 0;
1880 ilace, color_mode, 1727 }
1881 rotation, mirror, channel);
1882 1728
1883 if (paddr == 0) 1729 if (out_width < width / maxdownscale ||
1730 out_width > width * 8)
1884 return -EINVAL; 1731 return -EINVAL;
1885 1732
1886 if (ilace && height == out_height) 1733 if (out_height < height / maxdownscale ||
1887 fieldmode = 1; 1734 out_height > height * 8)
1735 return -EINVAL;
1888 1736
1889 if (ilace) { 1737 /* Must use 5-tap filter? */
1890 if (fieldmode) 1738 *five_taps = height > out_height * 2;
1891 height /= 2;
1892 pos_y /= 2;
1893 out_height /= 2;
1894 1739
1895 DSSDBG("adjusting for ilace: height %d, pos_y %d, " 1740 if (!*five_taps) {
1896 "out_height %d\n", 1741 fclk = calc_fclk(channel, width, height, out_width,
1897 height, pos_y, out_height); 1742 out_height);
1743
1744 /* Try 5-tap filter if 3-tap fclk is too high */
1745 if (cpu_is_omap34xx() && height > out_height &&
1746 fclk > dispc_fclk_rate())
1747 *five_taps = true;
1898 } 1748 }
1899 1749
1900 if (!dss_feat_color_mode_supported(plane, color_mode)) 1750 if (width > (2048 >> *five_taps)) {
1751 DSSERR("failed to set up scaling, fclk too low\n");
1901 return -EINVAL; 1752 return -EINVAL;
1753 }
1902 1754
1903 if (plane == OMAP_DSS_GFX) { 1755 if (*five_taps)
1904 if (width != out_width || height != out_height) 1756 fclk = calc_fclk_five_taps(channel, width, height,
1905 return -EINVAL; 1757 out_width, out_height, color_mode);
1906 } else {
1907 /* video plane */
1908 1758
1909 unsigned long fclk = 0; 1759 DSSDBG("required fclk rate = %lu Hz\n", fclk);
1760 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
1910 1761
1911 if (out_width < width / maxdownscale || 1762 if (!fclk || fclk > dispc_fclk_rate()) {
1912 out_width > width * 8) 1763 DSSERR("failed to set up scaling, "
1913 return -EINVAL; 1764 "required fclk rate = %lu Hz, "
1765 "current fclk rate = %lu Hz\n",
1766 fclk, dispc_fclk_rate());
1767 return -EINVAL;
1768 }
1914 1769
1915 if (out_height < height / maxdownscale || 1770 return 0;
1916 out_height > height * 8) 1771}
1917 return -EINVAL;
1918 1772
1919 if (color_mode == OMAP_DSS_COLOR_YUV2 || 1773int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
1920 color_mode == OMAP_DSS_COLOR_UYVY || 1774 bool ilace, enum omap_channel channel, bool replication,
1921 color_mode == OMAP_DSS_COLOR_NV12) 1775 u32 fifo_low, u32 fifo_high)
1922 cconv = 1; 1776{
1777 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
1778 bool five_taps = false;
1779 bool fieldmode = 0;
1780 int r, cconv = 0;
1781 unsigned offset0, offset1;
1782 s32 row_inc;
1783 s32 pix_inc;
1784 u16 frame_height = oi->height;
1785 unsigned int field_offset = 0;
1923 1786
1924 /* Must use 5-tap filter? */ 1787 DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
1925 five_taps = height > out_height * 2; 1788 "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
1789 "fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr,
1790 oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
1791 oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
1792 oi->mirror, ilace, channel, replication, fifo_low, fifo_high);
1926 1793
1927 if (!five_taps) { 1794 if (oi->paddr == 0)
1928 fclk = calc_fclk(channel, width, height, out_width, 1795 return -EINVAL;
1929 out_height);
1930 1796
1931 /* Try 5-tap filter if 3-tap fclk is too high */ 1797 if (ilace && oi->height == oi->out_height)
1932 if (cpu_is_omap34xx() && height > out_height && 1798 fieldmode = 1;
1933 fclk > dispc_fclk_rate())
1934 five_taps = true;
1935 }
1936 1799
1937 if (width > (2048 >> five_taps)) { 1800 if (ilace) {
1938 DSSERR("failed to set up scaling, fclk too low\n"); 1801 if (fieldmode)
1939 return -EINVAL; 1802 oi->height /= 2;
1940 } 1803 oi->pos_y /= 2;
1804 oi->out_height /= 2;
1941 1805
1942 if (five_taps) 1806 DSSDBG("adjusting for ilace: height %d, pos_y %d, "
1943 fclk = calc_fclk_five_taps(channel, width, height, 1807 "out_height %d\n",
1944 out_width, out_height, color_mode); 1808 oi->height, oi->pos_y, oi->out_height);
1809 }
1945 1810
1946 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1811 if (!dss_feat_color_mode_supported(plane, oi->color_mode))
1947 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); 1812 return -EINVAL;
1948 1813
1949 if (!fclk || fclk > dispc_fclk_rate()) { 1814 r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
1950 DSSERR("failed to set up scaling, " 1815 oi->out_width, oi->out_height, oi->color_mode,
1951 "required fclk rate = %lu Hz, " 1816 &five_taps);
1952 "current fclk rate = %lu Hz\n", 1817 if (r)
1953 fclk, dispc_fclk_rate()); 1818 return r;
1954 return -EINVAL; 1819
1955 } 1820 if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
1956 } 1821 oi->color_mode == OMAP_DSS_COLOR_UYVY ||
1822 oi->color_mode == OMAP_DSS_COLOR_NV12)
1823 cconv = 1;
1957 1824
1958 if (ilace && !fieldmode) { 1825 if (ilace && !fieldmode) {
1959 /* 1826 /*
@@ -1963,69 +1830,76 @@ int dispc_setup_plane(enum omap_plane plane,
1963 * so the integer part must be added to the base address of the 1830 * so the integer part must be added to the base address of the
1964 * bottom field. 1831 * bottom field.
1965 */ 1832 */
1966 if (!height || height == out_height) 1833 if (!oi->height || oi->height == oi->out_height)
1967 field_offset = 0; 1834 field_offset = 0;
1968 else 1835 else
1969 field_offset = height / out_height / 2; 1836 field_offset = oi->height / oi->out_height / 2;
1970 } 1837 }
1971 1838
1972 /* Fields are independent but interleaved in memory. */ 1839 /* Fields are independent but interleaved in memory. */
1973 if (fieldmode) 1840 if (fieldmode)
1974 field_offset = 1; 1841 field_offset = 1;
1975 1842
1976 if (rotation_type == OMAP_DSS_ROT_DMA) 1843 if (oi->rotation_type == OMAP_DSS_ROT_DMA)
1977 calc_dma_rotation_offset(rotation, mirror, 1844 calc_dma_rotation_offset(oi->rotation, oi->mirror,
1978 screen_width, width, frame_height, color_mode, 1845 oi->screen_width, oi->width, frame_height,
1979 fieldmode, field_offset, 1846 oi->color_mode, fieldmode, field_offset,
1980 &offset0, &offset1, &row_inc, &pix_inc); 1847 &offset0, &offset1, &row_inc, &pix_inc);
1981 else 1848 else
1982 calc_vrfb_rotation_offset(rotation, mirror, 1849 calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
1983 screen_width, width, frame_height, color_mode, 1850 oi->screen_width, oi->width, frame_height,
1984 fieldmode, field_offset, 1851 oi->color_mode, fieldmode, field_offset,
1985 &offset0, &offset1, &row_inc, &pix_inc); 1852 &offset0, &offset1, &row_inc, &pix_inc);
1986 1853
1987 DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", 1854 DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
1988 offset0, offset1, row_inc, pix_inc); 1855 offset0, offset1, row_inc, pix_inc);
1989 1856
1990 _dispc_set_color_mode(plane, color_mode); 1857 dispc_ovl_set_color_mode(plane, oi->color_mode);
1991 1858
1992 _dispc_set_plane_ba0(plane, paddr + offset0); 1859 dispc_ovl_set_ba0(plane, oi->paddr + offset0);
1993 _dispc_set_plane_ba1(plane, paddr + offset1); 1860 dispc_ovl_set_ba1(plane, oi->paddr + offset1);
1994 1861
1995 if (OMAP_DSS_COLOR_NV12 == color_mode) { 1862 if (OMAP_DSS_COLOR_NV12 == oi->color_mode) {
1996 _dispc_set_plane_ba0_uv(plane, puv_addr + offset0); 1863 dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
1997 _dispc_set_plane_ba1_uv(plane, puv_addr + offset1); 1864 dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
1998 } 1865 }
1999 1866
2000 1867
2001 _dispc_set_row_inc(plane, row_inc); 1868 dispc_ovl_set_row_inc(plane, row_inc);
2002 _dispc_set_pix_inc(plane, pix_inc); 1869 dispc_ovl_set_pix_inc(plane, pix_inc);
2003 1870
2004 DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height, 1871 DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
2005 out_width, out_height); 1872 oi->height, oi->out_width, oi->out_height);
2006 1873
2007 _dispc_set_plane_pos(plane, pos_x, pos_y); 1874 dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
2008 1875
2009 _dispc_set_pic_size(plane, width, height); 1876 dispc_ovl_set_pic_size(plane, oi->width, oi->height);
2010 1877
2011 if (plane != OMAP_DSS_GFX) { 1878 if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
2012 _dispc_set_scaling(plane, width, height, 1879 dispc_ovl_set_scaling(plane, oi->width, oi->height,
2013 out_width, out_height, 1880 oi->out_width, oi->out_height,
2014 ilace, five_taps, fieldmode, 1881 ilace, five_taps, fieldmode,
2015 color_mode, rotation); 1882 oi->color_mode, oi->rotation);
2016 _dispc_set_vid_size(plane, out_width, out_height); 1883 dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height);
2017 _dispc_set_vid_color_conv(plane, cconv); 1884 dispc_ovl_set_vid_color_conv(plane, cconv);
2018 } 1885 }
2019 1886
2020 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode); 1887 dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
1888 oi->color_mode);
1889
1890 dispc_ovl_set_zorder(plane, oi->zorder);
1891 dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
1892 dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
2021 1893
2022 _dispc_set_pre_mult_alpha(plane, pre_mult_alpha); 1894 dispc_ovl_set_channel_out(plane, channel);
2023 _dispc_setup_global_alpha(plane, global_alpha); 1895
1896 dispc_ovl_enable_replication(plane, replication);
1897 dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high);
2024 1898
2025 return 0; 1899 return 0;
2026} 1900}
2027 1901
2028int dispc_enable_plane(enum omap_plane plane, bool enable) 1902int dispc_ovl_enable(enum omap_plane plane, bool enable)
2029{ 1903{
2030 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); 1904 DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
2031 1905
@@ -2048,7 +1922,7 @@ static void _enable_lcd_out(enum omap_channel channel, bool enable)
2048 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1922 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
2049} 1923}
2050 1924
2051static void dispc_enable_lcd_out(enum omap_channel channel, bool enable) 1925static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
2052{ 1926{
2053 struct completion frame_done_completion; 1927 struct completion frame_done_completion;
2054 bool is_on; 1928 bool is_on;
@@ -2095,14 +1969,19 @@ static void _enable_digit_out(bool enable)
2095 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); 1969 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
2096} 1970}
2097 1971
2098static void dispc_enable_digit_out(bool enable) 1972static void dispc_mgr_enable_digit_out(bool enable)
2099{ 1973{
2100 struct completion frame_done_completion; 1974 struct completion frame_done_completion;
2101 int r; 1975 enum dss_hdmi_venc_clk_source_select src;
1976 int r, i;
1977 u32 irq_mask;
1978 int num_irqs;
2102 1979
2103 if (REG_GET(DISPC_CONTROL, 1, 1) == enable) 1980 if (REG_GET(DISPC_CONTROL, 1, 1) == enable)
2104 return; 1981 return;
2105 1982
1983 src = dss_get_hdmi_venc_clk_source();
1984
2106 if (enable) { 1985 if (enable) {
2107 unsigned long flags; 1986 unsigned long flags;
2108 /* When we enable digit output, we'll get an extra digit 1987 /* When we enable digit output, we'll get an extra digit
@@ -2119,43 +1998,47 @@ static void dispc_enable_digit_out(bool enable)
2119 * wait for the extra sync losts */ 1998 * wait for the extra sync losts */
2120 init_completion(&frame_done_completion); 1999 init_completion(&frame_done_completion);
2121 2000
2001 if (src == DSS_HDMI_M_PCLK && enable == false) {
2002 irq_mask = DISPC_IRQ_FRAMEDONETV;
2003 num_irqs = 1;
2004 } else {
2005 irq_mask = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
2006 /* XXX I understand from TRM that we should only wait for the
2007 * current field to complete. But it seems we have to wait for
2008 * both fields */
2009 num_irqs = 2;
2010 }
2011
2122 r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion, 2012 r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
2123 DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD); 2013 irq_mask);
2124 if (r) 2014 if (r)
2125 DSSERR("failed to register EVSYNC isr\n"); 2015 DSSERR("failed to register %x isr\n", irq_mask);
2126 2016
2127 _enable_digit_out(enable); 2017 _enable_digit_out(enable);
2128 2018
2129 /* XXX I understand from TRM that we should only wait for the 2019 for (i = 0; i < num_irqs; ++i) {
2130 * current field to complete. But it seems we have to wait 2020 if (!wait_for_completion_timeout(&frame_done_completion,
2131 * for both fields */ 2021 msecs_to_jiffies(100)))
2132 if (!wait_for_completion_timeout(&frame_done_completion, 2022 DSSERR("timeout waiting for digit out to %s\n",
2133 msecs_to_jiffies(100))) 2023 enable ? "start" : "stop");
2134 DSSERR("timeout waiting for EVSYNC\n"); 2024 }
2135
2136 if (!wait_for_completion_timeout(&frame_done_completion,
2137 msecs_to_jiffies(100)))
2138 DSSERR("timeout waiting for EVSYNC\n");
2139 2025
2140 r = omap_dispc_unregister_isr(dispc_disable_isr, 2026 r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
2141 &frame_done_completion, 2027 irq_mask);
2142 DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
2143 if (r) 2028 if (r)
2144 DSSERR("failed to unregister EVSYNC isr\n"); 2029 DSSERR("failed to unregister %x isr\n", irq_mask);
2145 2030
2146 if (enable) { 2031 if (enable) {
2147 unsigned long flags; 2032 unsigned long flags;
2148 spin_lock_irqsave(&dispc.irq_lock, flags); 2033 spin_lock_irqsave(&dispc.irq_lock, flags);
2149 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 2034 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST_DIGIT;
2150 if (dss_has_feature(FEAT_MGR_LCD2))
2151 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
2152 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 2035 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
2153 _omap_dispc_set_irqs(); 2036 _omap_dispc_set_irqs();
2154 spin_unlock_irqrestore(&dispc.irq_lock, flags); 2037 spin_unlock_irqrestore(&dispc.irq_lock, flags);
2155 } 2038 }
2156} 2039}
2157 2040
2158bool dispc_is_channel_enabled(enum omap_channel channel) 2041bool dispc_mgr_is_enabled(enum omap_channel channel)
2159{ 2042{
2160 if (channel == OMAP_DSS_CHANNEL_LCD) 2043 if (channel == OMAP_DSS_CHANNEL_LCD)
2161 return !!REG_GET(DISPC_CONTROL, 0, 0); 2044 return !!REG_GET(DISPC_CONTROL, 0, 0);
@@ -2167,13 +2050,12 @@ bool dispc_is_channel_enabled(enum omap_channel channel)
2167 BUG(); 2050 BUG();
2168} 2051}
2169 2052
2170void dispc_enable_channel(enum omap_channel channel, bool enable) 2053void dispc_mgr_enable(enum omap_channel channel, bool enable)
2171{ 2054{
2172 if (channel == OMAP_DSS_CHANNEL_LCD || 2055 if (dispc_mgr_is_lcd(channel))
2173 channel == OMAP_DSS_CHANNEL_LCD2) 2056 dispc_mgr_enable_lcd_out(channel, enable);
2174 dispc_enable_lcd_out(channel, enable);
2175 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 2057 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
2176 dispc_enable_digit_out(enable); 2058 dispc_mgr_enable_digit_out(enable);
2177 else 2059 else
2178 BUG(); 2060 BUG();
2179} 2061}
@@ -2202,7 +2084,7 @@ void dispc_pck_free_enable(bool enable)
2202 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 2084 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
2203} 2085}
2204 2086
2205void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) 2087void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable)
2206{ 2088{
2207 if (channel == OMAP_DSS_CHANNEL_LCD2) 2089 if (channel == OMAP_DSS_CHANNEL_LCD2)
2208 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16); 2090 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
@@ -2211,7 +2093,7 @@ void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
2211} 2093}
2212 2094
2213 2095
2214void dispc_set_lcd_display_type(enum omap_channel channel, 2096void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
2215 enum omap_lcd_display_type type) 2097 enum omap_lcd_display_type type)
2216{ 2098{
2217 int mode; 2099 int mode;
@@ -2242,12 +2124,12 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
2242} 2124}
2243 2125
2244 2126
2245void dispc_set_default_color(enum omap_channel channel, u32 color) 2127void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
2246{ 2128{
2247 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color); 2129 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
2248} 2130}
2249 2131
2250u32 dispc_get_default_color(enum omap_channel channel) 2132u32 dispc_mgr_get_default_color(enum omap_channel channel)
2251{ 2133{
2252 u32 l; 2134 u32 l;
2253 2135
@@ -2260,7 +2142,7 @@ u32 dispc_get_default_color(enum omap_channel channel)
2260 return l; 2142 return l;
2261} 2143}
2262 2144
2263void dispc_set_trans_key(enum omap_channel ch, 2145void dispc_mgr_set_trans_key(enum omap_channel ch,
2264 enum omap_dss_trans_key_type type, 2146 enum omap_dss_trans_key_type type,
2265 u32 trans_key) 2147 u32 trans_key)
2266{ 2148{
@@ -2274,7 +2156,7 @@ void dispc_set_trans_key(enum omap_channel ch,
2274 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); 2156 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
2275} 2157}
2276 2158
2277void dispc_get_trans_key(enum omap_channel ch, 2159void dispc_mgr_get_trans_key(enum omap_channel ch,
2278 enum omap_dss_trans_key_type *type, 2160 enum omap_dss_trans_key_type *type,
2279 u32 *trans_key) 2161 u32 *trans_key)
2280{ 2162{
@@ -2293,7 +2175,7 @@ void dispc_get_trans_key(enum omap_channel ch,
2293 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch)); 2175 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
2294} 2176}
2295 2177
2296void dispc_enable_trans_key(enum omap_channel ch, bool enable) 2178void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
2297{ 2179{
2298 if (ch == OMAP_DSS_CHANNEL_LCD) 2180 if (ch == OMAP_DSS_CHANNEL_LCD)
2299 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2181 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
@@ -2302,39 +2184,36 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
2302 else /* OMAP_DSS_CHANNEL_LCD2 */ 2184 else /* OMAP_DSS_CHANNEL_LCD2 */
2303 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); 2185 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
2304} 2186}
2305void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2187
2188void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
2306{ 2189{
2307 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2190 if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
2308 return; 2191 return;
2309 2192
2310 if (ch == OMAP_DSS_CHANNEL_LCD) 2193 if (ch == OMAP_DSS_CHANNEL_LCD)
2311 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2194 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
2312 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2195 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2313 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2196 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
2314 else /* OMAP_DSS_CHANNEL_LCD2 */
2315 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
2316} 2197}
2317bool dispc_alpha_blending_enabled(enum omap_channel ch) 2198
2199bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
2318{ 2200{
2319 bool enabled; 2201 bool enabled;
2320 2202
2321 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 2203 if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
2322 return false; 2204 return false;
2323 2205
2324 if (ch == OMAP_DSS_CHANNEL_LCD) 2206 if (ch == OMAP_DSS_CHANNEL_LCD)
2325 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2207 enabled = REG_GET(DISPC_CONFIG, 18, 18);
2326 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2208 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2327 enabled = REG_GET(DISPC_CONFIG, 19, 19); 2209 enabled = REG_GET(DISPC_CONFIG, 19, 19);
2328 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2329 enabled = REG_GET(DISPC_CONFIG2, 18, 18);
2330 else 2210 else
2331 BUG(); 2211 BUG();
2332 2212
2333 return enabled; 2213 return enabled;
2334} 2214}
2335 2215
2336 2216bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
2337bool dispc_trans_key_enabled(enum omap_channel ch)
2338{ 2217{
2339 bool enabled; 2218 bool enabled;
2340 2219
@@ -2351,7 +2230,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2351} 2230}
2352 2231
2353 2232
2354void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines) 2233void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2355{ 2234{
2356 int code; 2235 int code;
2357 2236
@@ -2379,46 +2258,41 @@ void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2379 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2258 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2380} 2259}
2381 2260
2382void dispc_set_parallel_interface_mode(enum omap_channel channel, 2261void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
2383 enum omap_parallel_interface_mode mode)
2384{ 2262{
2385 u32 l; 2263 u32 l;
2386 int stallmode; 2264 int gpout0, gpout1;
2387 int gpout0 = 1;
2388 int gpout1;
2389 2265
2390 switch (mode) { 2266 switch (mode) {
2391 case OMAP_DSS_PARALLELMODE_BYPASS: 2267 case DSS_IO_PAD_MODE_RESET:
2392 stallmode = 0; 2268 gpout0 = 0;
2393 gpout1 = 1; 2269 gpout1 = 0;
2394 break; 2270 break;
2395 2271 case DSS_IO_PAD_MODE_RFBI:
2396 case OMAP_DSS_PARALLELMODE_RFBI: 2272 gpout0 = 1;
2397 stallmode = 1;
2398 gpout1 = 0; 2273 gpout1 = 0;
2399 break; 2274 break;
2400 2275 case DSS_IO_PAD_MODE_BYPASS:
2401 case OMAP_DSS_PARALLELMODE_DSI: 2276 gpout0 = 1;
2402 stallmode = 1;
2403 gpout1 = 1; 2277 gpout1 = 1;
2404 break; 2278 break;
2405
2406 default: 2279 default:
2407 BUG(); 2280 BUG();
2408 return; 2281 return;
2409 } 2282 }
2410 2283
2411 if (channel == OMAP_DSS_CHANNEL_LCD2) { 2284 l = dispc_read_reg(DISPC_CONTROL);
2412 l = dispc_read_reg(DISPC_CONTROL2); 2285 l = FLD_MOD(l, gpout0, 15, 15);
2413 l = FLD_MOD(l, stallmode, 11, 11); 2286 l = FLD_MOD(l, gpout1, 16, 16);
2414 dispc_write_reg(DISPC_CONTROL2, l); 2287 dispc_write_reg(DISPC_CONTROL, l);
2415 } else { 2288}
2416 l = dispc_read_reg(DISPC_CONTROL); 2289
2417 l = FLD_MOD(l, stallmode, 11, 11); 2290void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
2418 l = FLD_MOD(l, gpout0, 15, 15); 2291{
2419 l = FLD_MOD(l, gpout1, 16, 16); 2292 if (channel == OMAP_DSS_CHANNEL_LCD2)
2420 dispc_write_reg(DISPC_CONTROL, l); 2293 REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
2421 } 2294 else
2295 REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
2422} 2296}
2423 2297
2424static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, 2298static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
@@ -2452,7 +2326,7 @@ bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
2452 timings->vfp, timings->vbp); 2326 timings->vfp, timings->vbp);
2453} 2327}
2454 2328
2455static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw, 2329static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
2456 int hfp, int hbp, int vsw, int vfp, int vbp) 2330 int hfp, int hbp, int vsw, int vfp, int vbp)
2457{ 2331{
2458 u32 timing_h, timing_v; 2332 u32 timing_h, timing_v;
@@ -2476,7 +2350,7 @@ static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
2476} 2350}
2477 2351
2478/* change name to mode? */ 2352/* change name to mode? */
2479void dispc_set_lcd_timings(enum omap_channel channel, 2353void dispc_mgr_set_lcd_timings(enum omap_channel channel,
2480 struct omap_video_timings *timings) 2354 struct omap_video_timings *timings)
2481{ 2355{
2482 unsigned xtot, ytot; 2356 unsigned xtot, ytot;
@@ -2487,11 +2361,11 @@ void dispc_set_lcd_timings(enum omap_channel channel,
2487 timings->vfp, timings->vbp)) 2361 timings->vfp, timings->vbp))
2488 BUG(); 2362 BUG();
2489 2363
2490 _dispc_set_lcd_timings(channel, timings->hsw, timings->hfp, 2364 _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp,
2491 timings->hbp, timings->vsw, timings->vfp, 2365 timings->hbp, timings->vsw, timings->vfp,
2492 timings->vbp); 2366 timings->vbp);
2493 2367
2494 dispc_set_lcd_size(channel, timings->x_res, timings->y_res); 2368 dispc_mgr_set_lcd_size(channel, timings->x_res, timings->y_res);
2495 2369
2496 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; 2370 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
2497 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; 2371 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
@@ -2509,17 +2383,17 @@ void dispc_set_lcd_timings(enum omap_channel channel,
2509 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2383 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2510} 2384}
2511 2385
2512static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div, 2386static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2513 u16 pck_div) 2387 u16 pck_div)
2514{ 2388{
2515 BUG_ON(lck_div < 1); 2389 BUG_ON(lck_div < 1);
2516 BUG_ON(pck_div < 2); 2390 BUG_ON(pck_div < 1);
2517 2391
2518 dispc_write_reg(DISPC_DIVISORo(channel), 2392 dispc_write_reg(DISPC_DIVISORo(channel),
2519 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2393 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2520} 2394}
2521 2395
2522static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, 2396static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2523 int *pck_div) 2397 int *pck_div)
2524{ 2398{
2525 u32 l; 2399 u32 l;
@@ -2552,7 +2426,7 @@ unsigned long dispc_fclk_rate(void)
2552 return r; 2426 return r;
2553} 2427}
2554 2428
2555unsigned long dispc_lclk_rate(enum omap_channel channel) 2429unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
2556{ 2430{
2557 struct platform_device *dsidev; 2431 struct platform_device *dsidev;
2558 int lcd; 2432 int lcd;
@@ -2582,19 +2456,34 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
2582 return r / lcd; 2456 return r / lcd;
2583} 2457}
2584 2458
2585unsigned long dispc_pclk_rate(enum omap_channel channel) 2459unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2586{ 2460{
2587 int pcd;
2588 unsigned long r; 2461 unsigned long r;
2589 u32 l;
2590 2462
2591 l = dispc_read_reg(DISPC_DIVISORo(channel)); 2463 if (dispc_mgr_is_lcd(channel)) {
2464 int pcd;
2465 u32 l;
2592 2466
2593 pcd = FLD_GET(l, 7, 0); 2467 l = dispc_read_reg(DISPC_DIVISORo(channel));
2594 2468
2595 r = dispc_lclk_rate(channel); 2469 pcd = FLD_GET(l, 7, 0);
2596 2470
2597 return r / pcd; 2471 r = dispc_mgr_lclk_rate(channel);
2472
2473 return r / pcd;
2474 } else {
2475 struct omap_dss_device *dssdev =
2476 dispc_mgr_get_device(channel);
2477
2478 switch (dssdev->type) {
2479 case OMAP_DISPLAY_TYPE_VENC:
2480 return venc_get_pixel_clock();
2481 case OMAP_DISPLAY_TYPE_HDMI:
2482 return hdmi_get_pixel_clock();
2483 default:
2484 BUG();
2485 }
2486 }
2598} 2487}
2599 2488
2600void dispc_dump_clocks(struct seq_file *s) 2489void dispc_dump_clocks(struct seq_file *s)
@@ -2631,12 +2520,12 @@ void dispc_dump_clocks(struct seq_file *s)
2631 dss_get_generic_clk_source_name(lcd_clk_src), 2520 dss_get_generic_clk_source_name(lcd_clk_src),
2632 dss_feat_get_clk_source_name(lcd_clk_src)); 2521 dss_feat_get_clk_source_name(lcd_clk_src));
2633 2522
2634 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); 2523 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2635 2524
2636 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2525 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2637 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd); 2526 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2638 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", 2527 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2639 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd); 2528 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2640 if (dss_has_feature(FEAT_MGR_LCD2)) { 2529 if (dss_has_feature(FEAT_MGR_LCD2)) {
2641 seq_printf(s, "- LCD2 -\n"); 2530 seq_printf(s, "- LCD2 -\n");
2642 2531
@@ -2646,12 +2535,12 @@ void dispc_dump_clocks(struct seq_file *s)
2646 dss_get_generic_clk_source_name(lcd_clk_src), 2535 dss_get_generic_clk_source_name(lcd_clk_src),
2647 dss_feat_get_clk_source_name(lcd_clk_src)); 2536 dss_feat_get_clk_source_name(lcd_clk_src));
2648 2537
2649 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); 2538 dispc_mgr_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2650 2539
2651 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", 2540 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2652 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd); 2541 dispc_mgr_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
2653 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", 2542 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2654 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd); 2543 dispc_mgr_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2655 } 2544 }
2656 2545
2657 dispc_runtime_put(); 2546 dispc_runtime_put();
@@ -2692,6 +2581,10 @@ void dispc_dump_irqs(struct seq_file *s)
2692 PIS(VID1_END_WIN); 2581 PIS(VID1_END_WIN);
2693 PIS(VID2_FIFO_UNDERFLOW); 2582 PIS(VID2_FIFO_UNDERFLOW);
2694 PIS(VID2_END_WIN); 2583 PIS(VID2_END_WIN);
2584 if (dss_feat_get_num_ovls() > 3) {
2585 PIS(VID3_FIFO_UNDERFLOW);
2586 PIS(VID3_END_WIN);
2587 }
2695 PIS(SYNC_LOST); 2588 PIS(SYNC_LOST);
2696 PIS(SYNC_LOST_DIGIT); 2589 PIS(SYNC_LOST_DIGIT);
2697 PIS(WAKEUP); 2590 PIS(WAKEUP);
@@ -2707,11 +2600,26 @@ void dispc_dump_irqs(struct seq_file *s)
2707 2600
2708void dispc_dump_regs(struct seq_file *s) 2601void dispc_dump_regs(struct seq_file *s)
2709{ 2602{
2603 int i, j;
2604 const char *mgr_names[] = {
2605 [OMAP_DSS_CHANNEL_LCD] = "LCD",
2606 [OMAP_DSS_CHANNEL_DIGIT] = "TV",
2607 [OMAP_DSS_CHANNEL_LCD2] = "LCD2",
2608 };
2609 const char *ovl_names[] = {
2610 [OMAP_DSS_GFX] = "GFX",
2611 [OMAP_DSS_VIDEO1] = "VID1",
2612 [OMAP_DSS_VIDEO2] = "VID2",
2613 [OMAP_DSS_VIDEO3] = "VID3",
2614 };
2615 const char **p_names;
2616
2710#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) 2617#define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
2711 2618
2712 if (dispc_runtime_get()) 2619 if (dispc_runtime_get())
2713 return; 2620 return;
2714 2621
2622 /* DISPC common registers */
2715 DUMPREG(DISPC_REVISION); 2623 DUMPREG(DISPC_REVISION);
2716 DUMPREG(DISPC_SYSCONFIG); 2624 DUMPREG(DISPC_SYSCONFIG);
2717 DUMPREG(DISPC_SYSSTATUS); 2625 DUMPREG(DISPC_SYSSTATUS);
@@ -2720,247 +2628,139 @@ void dispc_dump_regs(struct seq_file *s)
2720 DUMPREG(DISPC_CONTROL); 2628 DUMPREG(DISPC_CONTROL);
2721 DUMPREG(DISPC_CONFIG); 2629 DUMPREG(DISPC_CONFIG);
2722 DUMPREG(DISPC_CAPABLE); 2630 DUMPREG(DISPC_CAPABLE);
2723 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD));
2724 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2725 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD));
2726 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_DIGIT));
2727 DUMPREG(DISPC_LINE_STATUS); 2631 DUMPREG(DISPC_LINE_STATUS);
2728 DUMPREG(DISPC_LINE_NUMBER); 2632 DUMPREG(DISPC_LINE_NUMBER);
2729 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD)); 2633 if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER) ||
2730 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD)); 2634 dss_has_feature(FEAT_ALPHA_FREE_ZORDER))
2731 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD));
2732 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD));
2733 if (dss_has_feature(FEAT_GLOBAL_ALPHA))
2734 DUMPREG(DISPC_GLOBAL_ALPHA); 2635 DUMPREG(DISPC_GLOBAL_ALPHA);
2735 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_DIGIT));
2736 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD));
2737 if (dss_has_feature(FEAT_MGR_LCD2)) { 2636 if (dss_has_feature(FEAT_MGR_LCD2)) {
2738 DUMPREG(DISPC_CONTROL2); 2637 DUMPREG(DISPC_CONTROL2);
2739 DUMPREG(DISPC_CONFIG2); 2638 DUMPREG(DISPC_CONFIG2);
2740 DUMPREG(DISPC_DEFAULT_COLOR(OMAP_DSS_CHANNEL_LCD2));
2741 DUMPREG(DISPC_TRANS_COLOR(OMAP_DSS_CHANNEL_LCD2));
2742 DUMPREG(DISPC_TIMING_H(OMAP_DSS_CHANNEL_LCD2));
2743 DUMPREG(DISPC_TIMING_V(OMAP_DSS_CHANNEL_LCD2));
2744 DUMPREG(DISPC_POL_FREQ(OMAP_DSS_CHANNEL_LCD2));
2745 DUMPREG(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD2));
2746 DUMPREG(DISPC_SIZE_MGR(OMAP_DSS_CHANNEL_LCD2));
2747 }
2748
2749 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_GFX));
2750 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_GFX));
2751 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_GFX));
2752 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_GFX));
2753 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_GFX));
2754 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_GFX));
2755 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_GFX));
2756 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_GFX));
2757 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_GFX));
2758 DUMPREG(DISPC_OVL_WINDOW_SKIP(OMAP_DSS_GFX));
2759 DUMPREG(DISPC_OVL_TABLE_BA(OMAP_DSS_GFX));
2760
2761 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD));
2762 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD));
2763 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD));
2764
2765 if (dss_has_feature(FEAT_CPR)) {
2766 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD));
2767 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD));
2768 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD));
2769 } 2639 }
2770 if (dss_has_feature(FEAT_MGR_LCD2)) { 2640
2771 DUMPREG(DISPC_DATA_CYCLE1(OMAP_DSS_CHANNEL_LCD2)); 2641#undef DUMPREG
2772 DUMPREG(DISPC_DATA_CYCLE2(OMAP_DSS_CHANNEL_LCD2)); 2642
2773 DUMPREG(DISPC_DATA_CYCLE3(OMAP_DSS_CHANNEL_LCD2)); 2643#define DISPC_REG(i, name) name(i)
2644#define DUMPREG(i, r) seq_printf(s, "%s(%s)%*s %08x\n", #r, p_names[i], \
2645 48 - strlen(#r) - strlen(p_names[i]), " ", \
2646 dispc_read_reg(DISPC_REG(i, r)))
2647
2648 p_names = mgr_names;
2649
2650 /* DISPC channel specific registers */
2651 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
2652 DUMPREG(i, DISPC_DEFAULT_COLOR);
2653 DUMPREG(i, DISPC_TRANS_COLOR);
2654 DUMPREG(i, DISPC_SIZE_MGR);
2655
2656 if (i == OMAP_DSS_CHANNEL_DIGIT)
2657 continue;
2658
2659 DUMPREG(i, DISPC_DEFAULT_COLOR);
2660 DUMPREG(i, DISPC_TRANS_COLOR);
2661 DUMPREG(i, DISPC_TIMING_H);
2662 DUMPREG(i, DISPC_TIMING_V);
2663 DUMPREG(i, DISPC_POL_FREQ);
2664 DUMPREG(i, DISPC_DIVISORo);
2665 DUMPREG(i, DISPC_SIZE_MGR);
2666
2667 DUMPREG(i, DISPC_DATA_CYCLE1);
2668 DUMPREG(i, DISPC_DATA_CYCLE2);
2669 DUMPREG(i, DISPC_DATA_CYCLE3);
2774 2670
2775 if (dss_has_feature(FEAT_CPR)) { 2671 if (dss_has_feature(FEAT_CPR)) {
2776 DUMPREG(DISPC_CPR_COEF_R(OMAP_DSS_CHANNEL_LCD2)); 2672 DUMPREG(i, DISPC_CPR_COEF_R);
2777 DUMPREG(DISPC_CPR_COEF_G(OMAP_DSS_CHANNEL_LCD2)); 2673 DUMPREG(i, DISPC_CPR_COEF_G);
2778 DUMPREG(DISPC_CPR_COEF_B(OMAP_DSS_CHANNEL_LCD2)); 2674 DUMPREG(i, DISPC_CPR_COEF_B);
2675 }
2676 }
2677
2678 p_names = ovl_names;
2679
2680 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
2681 DUMPREG(i, DISPC_OVL_BA0);
2682 DUMPREG(i, DISPC_OVL_BA1);
2683 DUMPREG(i, DISPC_OVL_POSITION);
2684 DUMPREG(i, DISPC_OVL_SIZE);
2685 DUMPREG(i, DISPC_OVL_ATTRIBUTES);
2686 DUMPREG(i, DISPC_OVL_FIFO_THRESHOLD);
2687 DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS);
2688 DUMPREG(i, DISPC_OVL_ROW_INC);
2689 DUMPREG(i, DISPC_OVL_PIXEL_INC);
2690 if (dss_has_feature(FEAT_PRELOAD))
2691 DUMPREG(i, DISPC_OVL_PRELOAD);
2692
2693 if (i == OMAP_DSS_GFX) {
2694 DUMPREG(i, DISPC_OVL_WINDOW_SKIP);
2695 DUMPREG(i, DISPC_OVL_TABLE_BA);
2696 continue;
2697 }
2698
2699 DUMPREG(i, DISPC_OVL_FIR);
2700 DUMPREG(i, DISPC_OVL_PICTURE_SIZE);
2701 DUMPREG(i, DISPC_OVL_ACCU0);
2702 DUMPREG(i, DISPC_OVL_ACCU1);
2703 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2704 DUMPREG(i, DISPC_OVL_BA0_UV);
2705 DUMPREG(i, DISPC_OVL_BA1_UV);
2706 DUMPREG(i, DISPC_OVL_FIR2);
2707 DUMPREG(i, DISPC_OVL_ACCU2_0);
2708 DUMPREG(i, DISPC_OVL_ACCU2_1);
2779 } 2709 }
2710 if (dss_has_feature(FEAT_ATTR2))
2711 DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
2712 if (dss_has_feature(FEAT_PRELOAD))
2713 DUMPREG(i, DISPC_OVL_PRELOAD);
2780 } 2714 }
2781 2715
2782 if (dss_has_feature(FEAT_PRELOAD)) 2716#undef DISPC_REG
2783 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_GFX)); 2717#undef DUMPREG
2784 2718
2785 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO1)); 2719#define DISPC_REG(plane, name, i) name(plane, i)
2786 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO1)); 2720#define DUMPREG(plane, name, i) \
2787 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO1)); 2721 seq_printf(s, "%s_%d(%s)%*s %08x\n", #name, i, p_names[plane], \
2788 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO1)); 2722 46 - strlen(#name) - strlen(p_names[plane]), " ", \
2789 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO1)); 2723 dispc_read_reg(DISPC_REG(plane, name, i)))
2790 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO1)); 2724
2791 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO1)); 2725 /* Video pipeline coefficient registers */
2792 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO1)); 2726
2793 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO1)); 2727 /* start from OMAP_DSS_VIDEO1 */
2794 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO1)); 2728 for (i = 1; i < dss_feat_get_num_ovls(); i++) {
2795 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO1)); 2729 for (j = 0; j < 8; j++)
2796 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO1)); 2730 DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
2797 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO1)); 2731
2798 2732 for (j = 0; j < 8; j++)
2799 DUMPREG(DISPC_OVL_BA0(OMAP_DSS_VIDEO2)); 2733 DUMPREG(i, DISPC_OVL_FIR_COEF_HV, j);
2800 DUMPREG(DISPC_OVL_BA1(OMAP_DSS_VIDEO2)); 2734
2801 DUMPREG(DISPC_OVL_POSITION(OMAP_DSS_VIDEO2)); 2735 for (j = 0; j < 5; j++)
2802 DUMPREG(DISPC_OVL_SIZE(OMAP_DSS_VIDEO2)); 2736 DUMPREG(i, DISPC_OVL_CONV_COEF, j);
2803 DUMPREG(DISPC_OVL_ATTRIBUTES(OMAP_DSS_VIDEO2)); 2737
2804 DUMPREG(DISPC_OVL_FIFO_THRESHOLD(OMAP_DSS_VIDEO2)); 2738 if (dss_has_feature(FEAT_FIR_COEF_V)) {
2805 DUMPREG(DISPC_OVL_FIFO_SIZE_STATUS(OMAP_DSS_VIDEO2)); 2739 for (j = 0; j < 8; j++)
2806 DUMPREG(DISPC_OVL_ROW_INC(OMAP_DSS_VIDEO2)); 2740 DUMPREG(i, DISPC_OVL_FIR_COEF_V, j);
2807 DUMPREG(DISPC_OVL_PIXEL_INC(OMAP_DSS_VIDEO2)); 2741 }
2808 DUMPREG(DISPC_OVL_FIR(OMAP_DSS_VIDEO2)); 2742
2809 DUMPREG(DISPC_OVL_PICTURE_SIZE(OMAP_DSS_VIDEO2)); 2743 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2810 DUMPREG(DISPC_OVL_ACCU0(OMAP_DSS_VIDEO2)); 2744 for (j = 0; j < 8; j++)
2811 DUMPREG(DISPC_OVL_ACCU1(OMAP_DSS_VIDEO2)); 2745 DUMPREG(i, DISPC_OVL_FIR_COEF_H2, j);
2812 2746
2813 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 0)); 2747 for (j = 0; j < 8; j++)
2814 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 1)); 2748 DUMPREG(i, DISPC_OVL_FIR_COEF_HV2, j);
2815 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 2)); 2749
2816 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 3)); 2750 for (j = 0; j < 8; j++)
2817 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 4)); 2751 DUMPREG(i, DISPC_OVL_FIR_COEF_V2, j);
2818 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 5)); 2752 }
2819 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 6));
2820 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO1, 7));
2821 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 0));
2822 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 1));
2823 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 2));
2824 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 3));
2825 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 4));
2826 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 5));
2827 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 6));
2828 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO1, 7));
2829 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 0));
2830 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 1));
2831 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 2));
2832 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 3));
2833 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO1, 4));
2834 if (dss_has_feature(FEAT_FIR_COEF_V)) {
2835 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 0));
2836 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 1));
2837 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 2));
2838 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 3));
2839 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 4));
2840 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 5));
2841 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 6));
2842 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO1, 7));
2843 }
2844
2845 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2846 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO1));
2847 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO1));
2848 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO1));
2849 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO1));
2850 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO1));
2851
2852 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 0));
2853 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 1));
2854 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 2));
2855 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 3));
2856 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 4));
2857 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 5));
2858 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 6));
2859 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO1, 7));
2860
2861 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 0));
2862 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 1));
2863 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 2));
2864 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 3));
2865 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 4));
2866 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 5));
2867 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 6));
2868 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO1, 7));
2869
2870 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 0));
2871 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 1));
2872 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 2));
2873 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 3));
2874 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 4));
2875 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 5));
2876 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 6));
2877 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO1, 7));
2878 }
2879 if (dss_has_feature(FEAT_ATTR2))
2880 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO1));
2881
2882
2883 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 0));
2884 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 1));
2885 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 2));
2886 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 3));
2887 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 4));
2888 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 5));
2889 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 6));
2890 DUMPREG(DISPC_OVL_FIR_COEF_H(OMAP_DSS_VIDEO2, 7));
2891 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 0));
2892 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 1));
2893 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 2));
2894 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 3));
2895 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 4));
2896 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 5));
2897 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 6));
2898 DUMPREG(DISPC_OVL_FIR_COEF_HV(OMAP_DSS_VIDEO2, 7));
2899 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 0));
2900 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 1));
2901 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 2));
2902 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 3));
2903 DUMPREG(DISPC_OVL_CONV_COEF(OMAP_DSS_VIDEO2, 4));
2904
2905 if (dss_has_feature(FEAT_FIR_COEF_V)) {
2906 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 0));
2907 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 1));
2908 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 2));
2909 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 3));
2910 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 4));
2911 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 5));
2912 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 6));
2913 DUMPREG(DISPC_OVL_FIR_COEF_V(OMAP_DSS_VIDEO2, 7));
2914 }
2915
2916 if (dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) {
2917 DUMPREG(DISPC_OVL_BA0_UV(OMAP_DSS_VIDEO2));
2918 DUMPREG(DISPC_OVL_BA1_UV(OMAP_DSS_VIDEO2));
2919 DUMPREG(DISPC_OVL_FIR2(OMAP_DSS_VIDEO2));
2920 DUMPREG(DISPC_OVL_ACCU2_0(OMAP_DSS_VIDEO2));
2921 DUMPREG(DISPC_OVL_ACCU2_1(OMAP_DSS_VIDEO2));
2922
2923 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 0));
2924 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 1));
2925 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 2));
2926 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 3));
2927 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 4));
2928 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 5));
2929 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 6));
2930 DUMPREG(DISPC_OVL_FIR_COEF_H2(OMAP_DSS_VIDEO2, 7));
2931
2932 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 0));
2933 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 1));
2934 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 2));
2935 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 3));
2936 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 4));
2937 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 5));
2938 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 6));
2939 DUMPREG(DISPC_OVL_FIR_COEF_HV2(OMAP_DSS_VIDEO2, 7));
2940
2941 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 0));
2942 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 1));
2943 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 2));
2944 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 3));
2945 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 4));
2946 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 5));
2947 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 6));
2948 DUMPREG(DISPC_OVL_FIR_COEF_V2(OMAP_DSS_VIDEO2, 7));
2949 }
2950 if (dss_has_feature(FEAT_ATTR2))
2951 DUMPREG(DISPC_OVL_ATTRIBUTES2(OMAP_DSS_VIDEO2));
2952
2953 if (dss_has_feature(FEAT_PRELOAD)) {
2954 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO1));
2955 DUMPREG(DISPC_OVL_PRELOAD(OMAP_DSS_VIDEO2));
2956 } 2753 }
2957 2754
2958 dispc_runtime_put(); 2755 dispc_runtime_put();
2756
2757#undef DISPC_REG
2959#undef DUMPREG 2758#undef DUMPREG
2960} 2759}
2961 2760
2962static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf, 2761static void _dispc_mgr_set_pol_freq(enum omap_channel channel, bool onoff,
2963 bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, u8 acb) 2762 bool rf, bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi,
2763 u8 acb)
2964{ 2764{
2965 u32 l = 0; 2765 u32 l = 0;
2966 2766
@@ -2979,10 +2779,10 @@ static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
2979 dispc_write_reg(DISPC_POL_FREQ(channel), l); 2779 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2980} 2780}
2981 2781
2982void dispc_set_pol_freq(enum omap_channel channel, 2782void dispc_mgr_set_pol_freq(enum omap_channel channel,
2983 enum omap_panel_config config, u8 acbi, u8 acb) 2783 enum omap_panel_config config, u8 acbi, u8 acb)
2984{ 2784{
2985 _dispc_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0, 2785 _dispc_mgr_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
2986 (config & OMAP_DSS_LCD_RF) != 0, 2786 (config & OMAP_DSS_LCD_RF) != 0,
2987 (config & OMAP_DSS_LCD_IEO) != 0, 2787 (config & OMAP_DSS_LCD_IEO) != 0,
2988 (config & OMAP_DSS_LCD_IPC) != 0, 2788 (config & OMAP_DSS_LCD_IPC) != 0,
@@ -2995,11 +2795,17 @@ void dispc_set_pol_freq(enum omap_channel channel,
2995void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 2795void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
2996 struct dispc_clock_info *cinfo) 2796 struct dispc_clock_info *cinfo)
2997{ 2797{
2998 u16 pcd_min = is_tft ? 2 : 3; 2798 u16 pcd_min, pcd_max;
2999 unsigned long best_pck; 2799 unsigned long best_pck;
3000 u16 best_ld, cur_ld; 2800 u16 best_ld, cur_ld;
3001 u16 best_pd, cur_pd; 2801 u16 best_pd, cur_pd;
3002 2802
2803 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
2804 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
2805
2806 if (!is_tft)
2807 pcd_min = 3;
2808
3003 best_pck = 0; 2809 best_pck = 0;
3004 best_ld = 0; 2810 best_ld = 0;
3005 best_pd = 0; 2811 best_pd = 0;
@@ -3007,7 +2813,7 @@ void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
3007 for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { 2813 for (cur_ld = 1; cur_ld <= 255; ++cur_ld) {
3008 unsigned long lck = fck / cur_ld; 2814 unsigned long lck = fck / cur_ld;
3009 2815
3010 for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) { 2816 for (cur_pd = pcd_min; cur_pd <= pcd_max; ++cur_pd) {
3011 unsigned long pck = lck / cur_pd; 2817 unsigned long pck = lck / cur_pd;
3012 long old_delta = abs(best_pck - req_pck); 2818 long old_delta = abs(best_pck - req_pck);
3013 long new_delta = abs(pck - req_pck); 2819 long new_delta = abs(pck - req_pck);
@@ -3042,7 +2848,7 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3042{ 2848{
3043 if (cinfo->lck_div > 255 || cinfo->lck_div == 0) 2849 if (cinfo->lck_div > 255 || cinfo->lck_div == 0)
3044 return -EINVAL; 2850 return -EINVAL;
3045 if (cinfo->pck_div < 2 || cinfo->pck_div > 255) 2851 if (cinfo->pck_div < 1 || cinfo->pck_div > 255)
3046 return -EINVAL; 2852 return -EINVAL;
3047 2853
3048 cinfo->lck = dispc_fclk_rate / cinfo->lck_div; 2854 cinfo->lck = dispc_fclk_rate / cinfo->lck_div;
@@ -3051,18 +2857,18 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3051 return 0; 2857 return 0;
3052} 2858}
3053 2859
3054int dispc_set_clock_div(enum omap_channel channel, 2860int dispc_mgr_set_clock_div(enum omap_channel channel,
3055 struct dispc_clock_info *cinfo) 2861 struct dispc_clock_info *cinfo)
3056{ 2862{
3057 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 2863 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
3058 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 2864 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
3059 2865
3060 dispc_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div); 2866 dispc_mgr_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
3061 2867
3062 return 0; 2868 return 0;
3063} 2869}
3064 2870
3065int dispc_get_clock_div(enum omap_channel channel, 2871int dispc_mgr_get_clock_div(enum omap_channel channel,
3066 struct dispc_clock_info *cinfo) 2872 struct dispc_clock_info *cinfo)
3067{ 2873{
3068 unsigned long fck; 2874 unsigned long fck;
@@ -3207,6 +3013,8 @@ static void print_irq_status(u32 status)
3207 PIS(OCP_ERR); 3013 PIS(OCP_ERR);
3208 PIS(VID1_FIFO_UNDERFLOW); 3014 PIS(VID1_FIFO_UNDERFLOW);
3209 PIS(VID2_FIFO_UNDERFLOW); 3015 PIS(VID2_FIFO_UNDERFLOW);
3016 if (dss_feat_get_num_ovls() > 3)
3017 PIS(VID3_FIFO_UNDERFLOW);
3210 PIS(SYNC_LOST); 3018 PIS(SYNC_LOST);
3211 PIS(SYNC_LOST_DIGIT); 3019 PIS(SYNC_LOST_DIGIT);
3212 if (dss_has_feature(FEAT_MGR_LCD2)) 3020 if (dss_has_feature(FEAT_MGR_LCD2))
@@ -3300,178 +3108,72 @@ static void dispc_error_worker(struct work_struct *work)
3300 int i; 3108 int i;
3301 u32 errors; 3109 u32 errors;
3302 unsigned long flags; 3110 unsigned long flags;
3111 static const unsigned fifo_underflow_bits[] = {
3112 DISPC_IRQ_GFX_FIFO_UNDERFLOW,
3113 DISPC_IRQ_VID1_FIFO_UNDERFLOW,
3114 DISPC_IRQ_VID2_FIFO_UNDERFLOW,
3115 DISPC_IRQ_VID3_FIFO_UNDERFLOW,
3116 };
3117
3118 static const unsigned sync_lost_bits[] = {
3119 DISPC_IRQ_SYNC_LOST,
3120 DISPC_IRQ_SYNC_LOST_DIGIT,
3121 DISPC_IRQ_SYNC_LOST2,
3122 };
3303 3123
3304 spin_lock_irqsave(&dispc.irq_lock, flags); 3124 spin_lock_irqsave(&dispc.irq_lock, flags);
3305 errors = dispc.error_irqs; 3125 errors = dispc.error_irqs;
3306 dispc.error_irqs = 0; 3126 dispc.error_irqs = 0;
3307 spin_unlock_irqrestore(&dispc.irq_lock, flags); 3127 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3308 3128
3309 if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) { 3129 dispc_runtime_get();
3310 DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n");
3311 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3312 struct omap_overlay *ovl;
3313 ovl = omap_dss_get_overlay(i);
3314
3315 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3316 continue;
3317
3318 if (ovl->id == 0) {
3319 dispc_enable_plane(ovl->id, 0);
3320 dispc_go(ovl->manager->id);
3321 mdelay(50);
3322 break;
3323 }
3324 }
3325 }
3326
3327 if (errors & DISPC_IRQ_VID1_FIFO_UNDERFLOW) {
3328 DSSERR("VID1_FIFO_UNDERFLOW, disabling VID1\n");
3329 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3330 struct omap_overlay *ovl;
3331 ovl = omap_dss_get_overlay(i);
3332
3333 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3334 continue;
3335
3336 if (ovl->id == 1) {
3337 dispc_enable_plane(ovl->id, 0);
3338 dispc_go(ovl->manager->id);
3339 mdelay(50);
3340 break;
3341 }
3342 }
3343 }
3344
3345 if (errors & DISPC_IRQ_VID2_FIFO_UNDERFLOW) {
3346 DSSERR("VID2_FIFO_UNDERFLOW, disabling VID2\n");
3347 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3348 struct omap_overlay *ovl;
3349 ovl = omap_dss_get_overlay(i);
3350
3351 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3352 continue;
3353 3130
3354 if (ovl->id == 2) { 3131 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3355 dispc_enable_plane(ovl->id, 0); 3132 struct omap_overlay *ovl;
3356 dispc_go(ovl->manager->id); 3133 unsigned bit;
3357 mdelay(50);
3358 break;
3359 }
3360 }
3361 }
3362
3363 if (errors & DISPC_IRQ_SYNC_LOST) {
3364 struct omap_overlay_manager *manager = NULL;
3365 bool enable = false;
3366 3134
3367 DSSERR("SYNC_LOST, disabling LCD\n"); 3135 ovl = omap_dss_get_overlay(i);
3136 bit = fifo_underflow_bits[i];
3368 3137
3369 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3138 if (bit & errors) {
3370 struct omap_overlay_manager *mgr; 3139 DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
3371 mgr = omap_dss_get_overlay_manager(i); 3140 ovl->name);
3372 3141 dispc_ovl_enable(ovl->id, false);
3373 if (mgr->id == OMAP_DSS_CHANNEL_LCD) { 3142 dispc_mgr_go(ovl->manager->id);
3374 manager = mgr;
3375 enable = mgr->device->state ==
3376 OMAP_DSS_DISPLAY_ACTIVE;
3377 mgr->device->driver->disable(mgr->device);
3378 break;
3379 }
3380 }
3381
3382 if (manager) {
3383 struct omap_dss_device *dssdev = manager->device;
3384 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3385 struct omap_overlay *ovl;
3386 ovl = omap_dss_get_overlay(i);
3387
3388 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3389 continue;
3390
3391 if (ovl->id != 0 && ovl->manager == manager)
3392 dispc_enable_plane(ovl->id, 0);
3393 }
3394
3395 dispc_go(manager->id);
3396 mdelay(50); 3143 mdelay(50);
3397 if (enable)
3398 dssdev->driver->enable(dssdev);
3399 } 3144 }
3400 } 3145 }
3401 3146
3402 if (errors & DISPC_IRQ_SYNC_LOST_DIGIT) { 3147 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3403 struct omap_overlay_manager *manager = NULL; 3148 struct omap_overlay_manager *mgr;
3404 bool enable = false; 3149 unsigned bit;
3405 3150
3406 DSSERR("SYNC_LOST_DIGIT, disabling TV\n"); 3151 mgr = omap_dss_get_overlay_manager(i);
3152 bit = sync_lost_bits[i];
3407 3153
3408 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3154 if (bit & errors) {
3409 struct omap_overlay_manager *mgr; 3155 struct omap_dss_device *dssdev = mgr->device;
3410 mgr = omap_dss_get_overlay_manager(i); 3156 bool enable;
3411 3157
3412 if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) { 3158 DSSERR("SYNC_LOST on channel %s, restarting the output "
3413 manager = mgr; 3159 "with video overlays disabled\n",
3414 enable = mgr->device->state == 3160 mgr->name);
3415 OMAP_DSS_DISPLAY_ACTIVE;
3416 mgr->device->driver->disable(mgr->device);
3417 break;
3418 }
3419 }
3420 3161
3421 if (manager) { 3162 enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
3422 struct omap_dss_device *dssdev = manager->device; 3163 dssdev->driver->disable(dssdev);
3423 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3424 struct omap_overlay *ovl;
3425 ovl = omap_dss_get_overlay(i);
3426
3427 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3428 continue;
3429
3430 if (ovl->id != 0 && ovl->manager == manager)
3431 dispc_enable_plane(ovl->id, 0);
3432 }
3433 3164
3434 dispc_go(manager->id);
3435 mdelay(50);
3436 if (enable)
3437 dssdev->driver->enable(dssdev);
3438 }
3439 }
3440
3441 if (errors & DISPC_IRQ_SYNC_LOST2) {
3442 struct omap_overlay_manager *manager = NULL;
3443 bool enable = false;
3444
3445 DSSERR("SYNC_LOST for LCD2, disabling LCD2\n");
3446
3447 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3448 struct omap_overlay_manager *mgr;
3449 mgr = omap_dss_get_overlay_manager(i);
3450
3451 if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
3452 manager = mgr;
3453 enable = mgr->device->state ==
3454 OMAP_DSS_DISPLAY_ACTIVE;
3455 mgr->device->driver->disable(mgr->device);
3456 break;
3457 }
3458 }
3459
3460 if (manager) {
3461 struct omap_dss_device *dssdev = manager->device;
3462 for (i = 0; i < omap_dss_get_num_overlays(); ++i) { 3165 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3463 struct omap_overlay *ovl; 3166 struct omap_overlay *ovl;
3464 ovl = omap_dss_get_overlay(i); 3167 ovl = omap_dss_get_overlay(i);
3465 3168
3466 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) 3169 if (ovl->id != OMAP_DSS_GFX &&
3467 continue; 3170 ovl->manager == mgr)
3468 3171 dispc_ovl_enable(ovl->id, false);
3469 if (ovl->id != 0 && ovl->manager == manager)
3470 dispc_enable_plane(ovl->id, 0);
3471 } 3172 }
3472 3173
3473 dispc_go(manager->id); 3174 dispc_mgr_go(mgr->id);
3474 mdelay(50); 3175 mdelay(50);
3176
3475 if (enable) 3177 if (enable)
3476 dssdev->driver->enable(dssdev); 3178 dssdev->driver->enable(dssdev);
3477 } 3179 }
@@ -3482,9 +3184,7 @@ static void dispc_error_worker(struct work_struct *work)
3482 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3184 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3483 struct omap_overlay_manager *mgr; 3185 struct omap_overlay_manager *mgr;
3484 mgr = omap_dss_get_overlay_manager(i); 3186 mgr = omap_dss_get_overlay_manager(i);
3485 3187 mgr->device->driver->disable(mgr->device);
3486 if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
3487 mgr->device->driver->disable(mgr->device);
3488 } 3188 }
3489 } 3189 }
3490 3190
@@ -3492,6 +3192,8 @@ static void dispc_error_worker(struct work_struct *work)
3492 dispc.irq_error_mask |= errors; 3192 dispc.irq_error_mask |= errors;
3493 _omap_dispc_set_irqs(); 3193 _omap_dispc_set_irqs();
3494 spin_unlock_irqrestore(&dispc.irq_lock, flags); 3194 spin_unlock_irqrestore(&dispc.irq_lock, flags);
3195
3196 dispc_runtime_put();
3495} 3197}
3496 3198
3497int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout) 3199int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
@@ -3586,6 +3288,8 @@ static void _omap_dispc_initialize_irq(void)
3586 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3288 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3587 if (dss_has_feature(FEAT_MGR_LCD2)) 3289 if (dss_has_feature(FEAT_MGR_LCD2))
3588 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; 3290 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3291 if (dss_feat_get_num_ovls() > 3)
3292 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
3589 3293
3590 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, 3294 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3591 * so clear it */ 3295 * so clear it */
@@ -3635,6 +3339,8 @@ static void _omap_dispc_initial_config(void)
3635 dispc_read_plane_fifo_sizes(); 3339 dispc_read_plane_fifo_sizes();
3636 3340
3637 dispc_configure_burst_sizes(); 3341 dispc_configure_burst_sizes();
3342
3343 dispc_ovl_enable_zorder_planes();
3638} 3344}
3639 3345
3640/* DISPC HW IP initialisation */ 3346/* DISPC HW IP initialisation */
@@ -3734,7 +3440,6 @@ static int omap_dispchw_remove(struct platform_device *pdev)
3734static int dispc_runtime_suspend(struct device *dev) 3440static int dispc_runtime_suspend(struct device *dev)
3735{ 3441{
3736 dispc_save_context(); 3442 dispc_save_context();
3737 clk_disable(dispc.dss_clk);
3738 dss_runtime_put(); 3443 dss_runtime_put();
3739 3444
3740 return 0; 3445 return 0;
@@ -3748,7 +3453,6 @@ static int dispc_runtime_resume(struct device *dev)
3748 if (r < 0) 3453 if (r < 0)
3749 return r; 3454 return r;
3750 3455
3751 clk_enable(dispc.dss_clk);
3752 dispc_restore_context(); 3456 dispc_restore_context();
3753 3457
3754 return 0; 3458 return 0;
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 6c9ee0a0efb3..c06efc38983e 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -291,6 +291,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
291 return 0x00BC; 291 return 0x00BC;
292 case OMAP_DSS_VIDEO2: 292 case OMAP_DSS_VIDEO2:
293 return 0x014C; 293 return 0x014C;
294 case OMAP_DSS_VIDEO3:
295 return 0x0300;
294 default: 296 default:
295 BUG(); 297 BUG();
296 } 298 }
@@ -304,6 +306,8 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
304 case OMAP_DSS_VIDEO1: 306 case OMAP_DSS_VIDEO1:
305 case OMAP_DSS_VIDEO2: 307 case OMAP_DSS_VIDEO2:
306 return 0x0000; 308 return 0x0000;
309 case OMAP_DSS_VIDEO3:
310 return 0x0008;
307 default: 311 default:
308 BUG(); 312 BUG();
309 } 313 }
@@ -316,6 +320,8 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
316 case OMAP_DSS_VIDEO1: 320 case OMAP_DSS_VIDEO1:
317 case OMAP_DSS_VIDEO2: 321 case OMAP_DSS_VIDEO2:
318 return 0x0004; 322 return 0x0004;
323 case OMAP_DSS_VIDEO3:
324 return 0x000C;
319 default: 325 default:
320 BUG(); 326 BUG();
321 } 327 }
@@ -330,6 +336,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
330 return 0x0544; 336 return 0x0544;
331 case OMAP_DSS_VIDEO2: 337 case OMAP_DSS_VIDEO2:
332 return 0x04BC; 338 return 0x04BC;
339 case OMAP_DSS_VIDEO3:
340 return 0x0310;
333 default: 341 default:
334 BUG(); 342 BUG();
335 } 343 }
@@ -344,6 +352,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
344 return 0x0548; 352 return 0x0548;
345 case OMAP_DSS_VIDEO2: 353 case OMAP_DSS_VIDEO2:
346 return 0x04C0; 354 return 0x04C0;
355 case OMAP_DSS_VIDEO3:
356 return 0x0314;
347 default: 357 default:
348 BUG(); 358 BUG();
349 } 359 }
@@ -356,6 +366,8 @@ static inline u16 DISPC_POS_OFFSET(enum omap_plane plane)
356 case OMAP_DSS_VIDEO1: 366 case OMAP_DSS_VIDEO1:
357 case OMAP_DSS_VIDEO2: 367 case OMAP_DSS_VIDEO2:
358 return 0x0008; 368 return 0x0008;
369 case OMAP_DSS_VIDEO3:
370 return 0x009C;
359 default: 371 default:
360 BUG(); 372 BUG();
361 } 373 }
@@ -368,6 +380,8 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
368 case OMAP_DSS_VIDEO1: 380 case OMAP_DSS_VIDEO1:
369 case OMAP_DSS_VIDEO2: 381 case OMAP_DSS_VIDEO2:
370 return 0x000C; 382 return 0x000C;
383 case OMAP_DSS_VIDEO3:
384 return 0x00A8;
371 default: 385 default:
372 BUG(); 386 BUG();
373 } 387 }
@@ -381,6 +395,8 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
381 case OMAP_DSS_VIDEO1: 395 case OMAP_DSS_VIDEO1:
382 case OMAP_DSS_VIDEO2: 396 case OMAP_DSS_VIDEO2:
383 return 0x0010; 397 return 0x0010;
398 case OMAP_DSS_VIDEO3:
399 return 0x0070;
384 default: 400 default:
385 BUG(); 401 BUG();
386 } 402 }
@@ -395,6 +411,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
395 return 0x0568; 411 return 0x0568;
396 case OMAP_DSS_VIDEO2: 412 case OMAP_DSS_VIDEO2:
397 return 0x04DC; 413 return 0x04DC;
414 case OMAP_DSS_VIDEO3:
415 return 0x032C;
398 default: 416 default:
399 BUG(); 417 BUG();
400 } 418 }
@@ -408,6 +426,8 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
408 case OMAP_DSS_VIDEO1: 426 case OMAP_DSS_VIDEO1:
409 case OMAP_DSS_VIDEO2: 427 case OMAP_DSS_VIDEO2:
410 return 0x0014; 428 return 0x0014;
429 case OMAP_DSS_VIDEO3:
430 return 0x008C;
411 default: 431 default:
412 BUG(); 432 BUG();
413 } 433 }
@@ -421,6 +441,8 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
421 case OMAP_DSS_VIDEO1: 441 case OMAP_DSS_VIDEO1:
422 case OMAP_DSS_VIDEO2: 442 case OMAP_DSS_VIDEO2:
423 return 0x0018; 443 return 0x0018;
444 case OMAP_DSS_VIDEO3:
445 return 0x0088;
424 default: 446 default:
425 BUG(); 447 BUG();
426 } 448 }
@@ -434,6 +456,8 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
434 case OMAP_DSS_VIDEO1: 456 case OMAP_DSS_VIDEO1:
435 case OMAP_DSS_VIDEO2: 457 case OMAP_DSS_VIDEO2:
436 return 0x001C; 458 return 0x001C;
459 case OMAP_DSS_VIDEO3:
460 return 0x00A4;
437 default: 461 default:
438 BUG(); 462 BUG();
439 } 463 }
@@ -447,6 +471,8 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
447 case OMAP_DSS_VIDEO1: 471 case OMAP_DSS_VIDEO1:
448 case OMAP_DSS_VIDEO2: 472 case OMAP_DSS_VIDEO2:
449 return 0x0020; 473 return 0x0020;
474 case OMAP_DSS_VIDEO3:
475 return 0x0098;
450 default: 476 default:
451 BUG(); 477 BUG();
452 } 478 }
@@ -459,6 +485,7 @@ static inline u16 DISPC_WINDOW_SKIP_OFFSET(enum omap_plane plane)
459 return 0x0034; 485 return 0x0034;
460 case OMAP_DSS_VIDEO1: 486 case OMAP_DSS_VIDEO1:
461 case OMAP_DSS_VIDEO2: 487 case OMAP_DSS_VIDEO2:
488 case OMAP_DSS_VIDEO3:
462 BUG(); 489 BUG();
463 default: 490 default:
464 BUG(); 491 BUG();
@@ -472,6 +499,7 @@ static inline u16 DISPC_TABLE_BA_OFFSET(enum omap_plane plane)
472 return 0x0038; 499 return 0x0038;
473 case OMAP_DSS_VIDEO1: 500 case OMAP_DSS_VIDEO1:
474 case OMAP_DSS_VIDEO2: 501 case OMAP_DSS_VIDEO2:
502 case OMAP_DSS_VIDEO3:
475 BUG(); 503 BUG();
476 default: 504 default:
477 BUG(); 505 BUG();
@@ -486,6 +514,8 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
486 case OMAP_DSS_VIDEO1: 514 case OMAP_DSS_VIDEO1:
487 case OMAP_DSS_VIDEO2: 515 case OMAP_DSS_VIDEO2:
488 return 0x0024; 516 return 0x0024;
517 case OMAP_DSS_VIDEO3:
518 return 0x0090;
489 default: 519 default:
490 BUG(); 520 BUG();
491 } 521 }
@@ -500,6 +530,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
500 return 0x0580; 530 return 0x0580;
501 case OMAP_DSS_VIDEO2: 531 case OMAP_DSS_VIDEO2:
502 return 0x055C; 532 return 0x055C;
533 case OMAP_DSS_VIDEO3:
534 return 0x0424;
503 default: 535 default:
504 BUG(); 536 BUG();
505 } 537 }
@@ -513,6 +545,8 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
513 case OMAP_DSS_VIDEO1: 545 case OMAP_DSS_VIDEO1:
514 case OMAP_DSS_VIDEO2: 546 case OMAP_DSS_VIDEO2:
515 return 0x0028; 547 return 0x0028;
548 case OMAP_DSS_VIDEO3:
549 return 0x0094;
516 default: 550 default:
517 BUG(); 551 BUG();
518 } 552 }
@@ -527,6 +561,8 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
527 case OMAP_DSS_VIDEO1: 561 case OMAP_DSS_VIDEO1:
528 case OMAP_DSS_VIDEO2: 562 case OMAP_DSS_VIDEO2:
529 return 0x002C; 563 return 0x002C;
564 case OMAP_DSS_VIDEO3:
565 return 0x0000;
530 default: 566 default:
531 BUG(); 567 BUG();
532 } 568 }
@@ -541,6 +577,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
541 return 0x0584; 577 return 0x0584;
542 case OMAP_DSS_VIDEO2: 578 case OMAP_DSS_VIDEO2:
543 return 0x0560; 579 return 0x0560;
580 case OMAP_DSS_VIDEO3:
581 return 0x0428;
544 default: 582 default:
545 BUG(); 583 BUG();
546 } 584 }
@@ -554,6 +592,8 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
554 case OMAP_DSS_VIDEO1: 592 case OMAP_DSS_VIDEO1:
555 case OMAP_DSS_VIDEO2: 593 case OMAP_DSS_VIDEO2:
556 return 0x0030; 594 return 0x0030;
595 case OMAP_DSS_VIDEO3:
596 return 0x0004;
557 default: 597 default:
558 BUG(); 598 BUG();
559 } 599 }
@@ -568,6 +608,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
568 return 0x0588; 608 return 0x0588;
569 case OMAP_DSS_VIDEO2: 609 case OMAP_DSS_VIDEO2:
570 return 0x0564; 610 return 0x0564;
611 case OMAP_DSS_VIDEO3:
612 return 0x042C;
571 default: 613 default:
572 BUG(); 614 BUG();
573 } 615 }
@@ -582,6 +624,8 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
582 case OMAP_DSS_VIDEO1: 624 case OMAP_DSS_VIDEO1:
583 case OMAP_DSS_VIDEO2: 625 case OMAP_DSS_VIDEO2:
584 return 0x0034 + i * 0x8; 626 return 0x0034 + i * 0x8;
627 case OMAP_DSS_VIDEO3:
628 return 0x0010 + i * 0x8;
585 default: 629 default:
586 BUG(); 630 BUG();
587 } 631 }
@@ -597,6 +641,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
597 return 0x058C + i * 0x8; 641 return 0x058C + i * 0x8;
598 case OMAP_DSS_VIDEO2: 642 case OMAP_DSS_VIDEO2:
599 return 0x0568 + i * 0x8; 643 return 0x0568 + i * 0x8;
644 case OMAP_DSS_VIDEO3:
645 return 0x0430 + i * 0x8;
600 default: 646 default:
601 BUG(); 647 BUG();
602 } 648 }
@@ -611,6 +657,8 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
611 case OMAP_DSS_VIDEO1: 657 case OMAP_DSS_VIDEO1:
612 case OMAP_DSS_VIDEO2: 658 case OMAP_DSS_VIDEO2:
613 return 0x0038 + i * 0x8; 659 return 0x0038 + i * 0x8;
660 case OMAP_DSS_VIDEO3:
661 return 0x0014 + i * 0x8;
614 default: 662 default:
615 BUG(); 663 BUG();
616 } 664 }
@@ -626,6 +674,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
626 return 0x0590 + i * 8; 674 return 0x0590 + i * 8;
627 case OMAP_DSS_VIDEO2: 675 case OMAP_DSS_VIDEO2:
628 return 0x056C + i * 0x8; 676 return 0x056C + i * 0x8;
677 case OMAP_DSS_VIDEO3:
678 return 0x0434 + i * 0x8;
629 default: 679 default:
630 BUG(); 680 BUG();
631 } 681 }
@@ -639,6 +689,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
639 BUG(); 689 BUG();
640 case OMAP_DSS_VIDEO1: 690 case OMAP_DSS_VIDEO1:
641 case OMAP_DSS_VIDEO2: 691 case OMAP_DSS_VIDEO2:
692 case OMAP_DSS_VIDEO3:
642 return 0x0074 + i * 0x4; 693 return 0x0074 + i * 0x4;
643 default: 694 default:
644 BUG(); 695 BUG();
@@ -655,6 +706,8 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
655 return 0x0124 + i * 0x4; 706 return 0x0124 + i * 0x4;
656 case OMAP_DSS_VIDEO2: 707 case OMAP_DSS_VIDEO2:
657 return 0x00B4 + i * 0x4; 708 return 0x00B4 + i * 0x4;
709 case OMAP_DSS_VIDEO3:
710 return 0x0050 + i * 0x4;
658 default: 711 default:
659 BUG(); 712 BUG();
660 } 713 }
@@ -670,6 +723,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
670 return 0x05CC + i * 0x4; 723 return 0x05CC + i * 0x4;
671 case OMAP_DSS_VIDEO2: 724 case OMAP_DSS_VIDEO2:
672 return 0x05A8 + i * 0x4; 725 return 0x05A8 + i * 0x4;
726 case OMAP_DSS_VIDEO3:
727 return 0x0470 + i * 0x4;
673 default: 728 default:
674 BUG(); 729 BUG();
675 } 730 }
@@ -684,6 +739,8 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
684 return 0x0174; 739 return 0x0174;
685 case OMAP_DSS_VIDEO2: 740 case OMAP_DSS_VIDEO2:
686 return 0x00E8; 741 return 0x00E8;
742 case OMAP_DSS_VIDEO3:
743 return 0x00A0;
687 default: 744 default:
688 BUG(); 745 BUG();
689 } 746 }
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 94495e45ec5a..be331dc5a61b 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -45,14 +45,13 @@ static ssize_t display_enabled_store(struct device *dev,
45 const char *buf, size_t size) 45 const char *buf, size_t size)
46{ 46{
47 struct omap_dss_device *dssdev = to_dss_device(dev); 47 struct omap_dss_device *dssdev = to_dss_device(dev);
48 int r, enabled; 48 int r;
49 bool enabled;
49 50
50 r = kstrtoint(buf, 0, &enabled); 51 r = strtobool(buf, &enabled);
51 if (r) 52 if (r)
52 return r; 53 return r;
53 54
54 enabled = !!enabled;
55
56 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { 55 if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
57 if (enabled) { 56 if (enabled) {
58 r = dssdev->driver->enable(dssdev); 57 r = dssdev->driver->enable(dssdev);
@@ -79,17 +78,16 @@ static ssize_t display_tear_store(struct device *dev,
79 struct device_attribute *attr, const char *buf, size_t size) 78 struct device_attribute *attr, const char *buf, size_t size)
80{ 79{
81 struct omap_dss_device *dssdev = to_dss_device(dev); 80 struct omap_dss_device *dssdev = to_dss_device(dev);
82 int te, r; 81 int r;
82 bool te;
83 83
84 if (!dssdev->driver->enable_te || !dssdev->driver->get_te) 84 if (!dssdev->driver->enable_te || !dssdev->driver->get_te)
85 return -ENOENT; 85 return -ENOENT;
86 86
87 r = kstrtoint(buf, 0, &te); 87 r = strtobool(buf, &te);
88 if (r) 88 if (r)
89 return r; 89 return r;
90 90
91 te = !!te;
92
93 r = dssdev->driver->enable_te(dssdev, te); 91 r = dssdev->driver->enable_te(dssdev, te);
94 if (r) 92 if (r)
95 return r; 93 return r;
@@ -195,17 +193,16 @@ static ssize_t display_mirror_store(struct device *dev,
195 struct device_attribute *attr, const char *buf, size_t size) 193 struct device_attribute *attr, const char *buf, size_t size)
196{ 194{
197 struct omap_dss_device *dssdev = to_dss_device(dev); 195 struct omap_dss_device *dssdev = to_dss_device(dev);
198 int mirror, r; 196 int r;
197 bool mirror;
199 198
200 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) 199 if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
201 return -ENOENT; 200 return -ENOENT;
202 201
203 r = kstrtoint(buf, 0, &mirror); 202 r = strtobool(buf, &mirror);
204 if (r) 203 if (r)
205 return r; 204 return r;
206 205
207 mirror = !!mirror;
208
209 r = dssdev->driver->set_mirror(dssdev, mirror); 206 r = dssdev->driver->set_mirror(dssdev, mirror);
210 if (r) 207 if (r)
211 return r; 208 return r;
@@ -302,11 +299,15 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
302 return 16; 299 return 16;
303 300
304 case OMAP_DISPLAY_TYPE_DBI: 301 case OMAP_DISPLAY_TYPE_DBI:
305 case OMAP_DISPLAY_TYPE_DSI:
306 if (dssdev->ctrl.pixel_size == 24) 302 if (dssdev->ctrl.pixel_size == 24)
307 return 24; 303 return 24;
308 else 304 else
309 return 16; 305 return 16;
306 case OMAP_DISPLAY_TYPE_DSI:
307 if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16)
308 return 24;
309 else
310 return 16;
310 case OMAP_DISPLAY_TYPE_VENC: 311 case OMAP_DISPLAY_TYPE_VENC:
311 case OMAP_DISPLAY_TYPE_SDI: 312 case OMAP_DISPLAY_TYPE_SDI:
312 case OMAP_DISPLAY_TYPE_HDMI: 313 case OMAP_DISPLAY_TYPE_HDMI:
@@ -342,9 +343,11 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
342 bpp = 24; 343 bpp = 24;
343 break; 344 break;
344 case OMAP_DISPLAY_TYPE_DBI: 345 case OMAP_DISPLAY_TYPE_DBI:
345 case OMAP_DISPLAY_TYPE_DSI:
346 bpp = dssdev->ctrl.pixel_size; 346 bpp = dssdev->ctrl.pixel_size;
347 break; 347 break;
348 case OMAP_DISPLAY_TYPE_DSI:
349 bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
350 break;
348 default: 351 default:
349 BUG(); 352 BUG();
350 } 353 }
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f053b180ecd7..483888a85cfd 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -82,9 +82,11 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
82 82
83 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 83 dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
84 84
85 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 85 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
86 if (r) 86 if (r) {
87 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
87 return r; 88 return r;
89 }
88 90
89 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 91 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
90 *lck_div = dispc_cinfo.lck_div; 92 *lck_div = dispc_cinfo.lck_div;
@@ -109,7 +111,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, bool is_tft,
109 if (r) 111 if (r)
110 return r; 112 return r;
111 113
112 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 114 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
113 if (r) 115 if (r)
114 return r; 116 return r;
115 117
@@ -129,7 +131,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
129 bool is_tft; 131 bool is_tft;
130 int r = 0; 132 int r = 0;
131 133
132 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 134 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
133 dssdev->panel.acbi, dssdev->panel.acb); 135 dssdev->panel.acbi, dssdev->panel.acb);
134 136
135 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 137 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
@@ -153,7 +155,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
153 t->pixel_clock = pck; 155 t->pixel_clock = pck;
154 } 156 }
155 157
156 dispc_set_lcd_timings(dssdev->manager->id, t); 158 dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
157 159
158 return 0; 160 return 0;
159} 161}
@@ -164,11 +166,12 @@ static void dpi_basic_init(struct omap_dss_device *dssdev)
164 166
165 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; 167 is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
166 168
167 dispc_set_parallel_interface_mode(dssdev->manager->id, 169 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
168 OMAP_DSS_PARALLELMODE_BYPASS); 170 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
169 dispc_set_lcd_display_type(dssdev->manager->id, is_tft ? 171
172 dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ?
170 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN); 173 OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
171 dispc_set_tft_data_lines(dssdev->manager->id, 174 dispc_mgr_set_tft_data_lines(dssdev->manager->id,
172 dssdev->phy.dpi.data_lines); 175 dssdev->phy.dpi.data_lines);
173} 176}
174 177
@@ -176,6 +179,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
176{ 179{
177 int r; 180 int r;
178 181
182 if (dssdev->manager == NULL) {
183 DSSERR("failed to enable display: no manager\n");
184 return -ENODEV;
185 }
186
179 r = omap_dss_start_device(dssdev); 187 r = omap_dss_start_device(dssdev);
180 if (r) { 188 if (r) {
181 DSSERR("failed to start device\n"); 189 DSSERR("failed to start device\n");
@@ -277,7 +285,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
277 } 285 }
278 286
279 dpi_set_mode(dssdev); 287 dpi_set_mode(dssdev);
280 dispc_go(dssdev->manager->id); 288 dispc_mgr_go(dssdev->manager->id);
281 289
282 dispc_runtime_put(); 290 dispc_runtime_put();
283 dss_runtime_put(); 291 dss_runtime_put();
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 7adbbeb84334..43c04a9889c4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -39,6 +39,7 @@
39#include <linux/pm_runtime.h> 39#include <linux/pm_runtime.h>
40 40
41#include <video/omapdss.h> 41#include <video/omapdss.h>
42#include <video/mipi_display.h>
42#include <plat/clock.h> 43#include <plat/clock.h>
43 44
44#include "dss.h" 45#include "dss.h"
@@ -131,7 +132,7 @@ struct dsi_reg { u16 idx; };
131#define DSI_IRQ_TA_TIMEOUT (1 << 20) 132#define DSI_IRQ_TA_TIMEOUT (1 << 20)
132#define DSI_IRQ_ERROR_MASK \ 133#define DSI_IRQ_ERROR_MASK \
133 (DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \ 134 (DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
134 DSI_IRQ_TA_TIMEOUT) 135 DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
135#define DSI_IRQ_CHANNEL_MASK 0xf 136#define DSI_IRQ_CHANNEL_MASK 0xf
136 137
137/* Virtual channel interrupts */ 138/* Virtual channel interrupts */
@@ -198,18 +199,6 @@ struct dsi_reg { u16 idx; };
198 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \ 199 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
199 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5) 200 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
200 201
201#define DSI_DT_DCS_SHORT_WRITE_0 0x05
202#define DSI_DT_DCS_SHORT_WRITE_1 0x15
203#define DSI_DT_DCS_READ 0x06
204#define DSI_DT_SET_MAX_RET_PKG_SIZE 0x37
205#define DSI_DT_NULL_PACKET 0x09
206#define DSI_DT_DCS_LONG_WRITE 0x39
207
208#define DSI_DT_RX_ACK_WITH_ERR 0x02
209#define DSI_DT_RX_DCS_LONG_READ 0x1c
210#define DSI_DT_RX_SHORT_READ_1 0x21
211#define DSI_DT_RX_SHORT_READ_2 0x22
212
213typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); 202typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
214 203
215#define DSI_MAX_NR_ISRS 2 204#define DSI_MAX_NR_ISRS 2
@@ -228,9 +217,9 @@ enum fifo_size {
228 DSI_FIFO_SIZE_128 = 4, 217 DSI_FIFO_SIZE_128 = 4,
229}; 218};
230 219
231enum dsi_vc_mode { 220enum dsi_vc_source {
232 DSI_VC_MODE_L4 = 0, 221 DSI_VC_SOURCE_L4 = 0,
233 DSI_VC_MODE_VP, 222 DSI_VC_SOURCE_VP,
234}; 223};
235 224
236enum dsi_lane { 225enum dsi_lane {
@@ -274,7 +263,8 @@ struct dsi_data {
274 struct clk *dss_clk; 263 struct clk *dss_clk;
275 struct clk *sys_clk; 264 struct clk *sys_clk;
276 265
277 void (*dsi_mux_pads)(bool enable); 266 int (*enable_pads)(int dsi_id, unsigned lane_mask);
267 void (*disable_pads)(int dsi_id, unsigned lane_mask);
278 268
279 struct dsi_clock_info current_cinfo; 269 struct dsi_clock_info current_cinfo;
280 270
@@ -282,7 +272,7 @@ struct dsi_data {
282 struct regulator *vdds_dsi_reg; 272 struct regulator *vdds_dsi_reg;
283 273
284 struct { 274 struct {
285 enum dsi_vc_mode mode; 275 enum dsi_vc_source source;
286 struct omap_dss_device *dssdev; 276 struct omap_dss_device *dssdev;
287 enum fifo_size fifo_size; 277 enum fifo_size fifo_size;
288 int vc_id; 278 int vc_id;
@@ -368,14 +358,9 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
368 return dsi_pdev_map[module]; 358 return dsi_pdev_map[module];
369} 359}
370 360
371static int dsi_get_dsidev_id(struct platform_device *dsidev) 361static inline int dsi_get_dsidev_id(struct platform_device *dsidev)
372{ 362{
373 /* TEMP: Pass 0 as the dsi module index till the time the dsi platform 363 return dsidev->id;
374 * device names aren't changed to the form "omapdss_dsi.0",
375 * "omapdss_dsi.1" and so on */
376 BUG_ON(dsidev->id != -1);
377
378 return 0;
379} 364}
380 365
381static inline void dsi_write_reg(struct platform_device *dsidev, 366static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -437,6 +422,21 @@ static inline int wait_for_bit_change(struct platform_device *dsidev,
437 return value; 422 return value;
438} 423}
439 424
425u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
426{
427 switch (fmt) {
428 case OMAP_DSS_DSI_FMT_RGB888:
429 case OMAP_DSS_DSI_FMT_RGB666:
430 return 24;
431 case OMAP_DSS_DSI_FMT_RGB666_PACKED:
432 return 18;
433 case OMAP_DSS_DSI_FMT_RGB565:
434 return 16;
435 default:
436 BUG();
437 }
438}
439
440#ifdef DEBUG 440#ifdef DEBUG
441static void dsi_perf_mark_setup(struct platform_device *dsidev) 441static void dsi_perf_mark_setup(struct platform_device *dsidev)
442{ 442{
@@ -453,6 +453,7 @@ static void dsi_perf_mark_start(struct platform_device *dsidev)
453static void dsi_perf_show(struct platform_device *dsidev, const char *name) 453static void dsi_perf_show(struct platform_device *dsidev, const char *name)
454{ 454{
455 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 455 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
456 struct omap_dss_device *dssdev = dsi->update_region.device;
456 ktime_t t, setup_time, trans_time; 457 ktime_t t, setup_time, trans_time;
457 u32 total_bytes; 458 u32 total_bytes;
458 u32 setup_us, trans_us, total_us; 459 u32 setup_us, trans_us, total_us;
@@ -476,7 +477,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
476 477
477 total_bytes = dsi->update_region.w * 478 total_bytes = dsi->update_region.w *
478 dsi->update_region.h * 479 dsi->update_region.h *
479 dsi->update_region.device->ctrl.pixel_size / 8; 480 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
480 481
481 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " 482 printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
482 "%u bytes, %u kbytes/sec\n", 483 "%u bytes, %u kbytes/sec\n",
@@ -1287,7 +1288,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
1287 * with DSS_SYS_CLK source also */ 1288 * with DSS_SYS_CLK source also */
1288 cinfo->highfreq = 0; 1289 cinfo->highfreq = 0;
1289 } else { 1290 } else {
1290 cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); 1291 cinfo->clkin = dispc_mgr_pclk_rate(dssdev->manager->id);
1291 1292
1292 if (cinfo->clkin < 32000000) 1293 if (cinfo->clkin < 32000000)
1293 cinfo->highfreq = 0; 1294 cinfo->highfreq = 0;
@@ -2360,6 +2361,24 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
2360 return 0; 2361 return 0;
2361} 2362}
2362 2363
2364static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
2365{
2366 unsigned lanes = 0;
2367
2368 if (dssdev->phy.dsi.clk_lane != 0)
2369 lanes |= 1 << (dssdev->phy.dsi.clk_lane - 1);
2370 if (dssdev->phy.dsi.data1_lane != 0)
2371 lanes |= 1 << (dssdev->phy.dsi.data1_lane - 1);
2372 if (dssdev->phy.dsi.data2_lane != 0)
2373 lanes |= 1 << (dssdev->phy.dsi.data2_lane - 1);
2374 if (dssdev->phy.dsi.data3_lane != 0)
2375 lanes |= 1 << (dssdev->phy.dsi.data3_lane - 1);
2376 if (dssdev->phy.dsi.data4_lane != 0)
2377 lanes |= 1 << (dssdev->phy.dsi.data4_lane - 1);
2378
2379 return lanes;
2380}
2381
2363static int dsi_cio_init(struct omap_dss_device *dssdev) 2382static int dsi_cio_init(struct omap_dss_device *dssdev)
2364{ 2383{
2365 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 2384 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -2370,8 +2389,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2370 2389
2371 DSSDBGF(); 2390 DSSDBGF();
2372 2391
2373 if (dsi->dsi_mux_pads) 2392 r = dsi->enable_pads(dsidev->id, dsi_get_lane_mask(dssdev));
2374 dsi->dsi_mux_pads(true); 2393 if (r)
2394 return r;
2375 2395
2376 dsi_enable_scp_clk(dsidev); 2396 dsi_enable_scp_clk(dsidev);
2377 2397
@@ -2452,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2452 2472
2453 dsi_cio_timings(dsidev); 2473 dsi_cio_timings(dsidev);
2454 2474
2475 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
2476 /* DDR_CLK_ALWAYS_ON */
2477 REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
2478 dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
2479 }
2480
2455 dsi->ulps_enabled = false; 2481 dsi->ulps_enabled = false;
2456 2482
2457 DSSDBG("CIO init done\n"); 2483 DSSDBG("CIO init done\n");
@@ -2467,19 +2493,21 @@ err_cio_pwr:
2467 dsi_cio_disable_lane_override(dsidev); 2493 dsi_cio_disable_lane_override(dsidev);
2468err_scp_clk_dom: 2494err_scp_clk_dom:
2469 dsi_disable_scp_clk(dsidev); 2495 dsi_disable_scp_clk(dsidev);
2470 if (dsi->dsi_mux_pads) 2496 dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev));
2471 dsi->dsi_mux_pads(false);
2472 return r; 2497 return r;
2473} 2498}
2474 2499
2475static void dsi_cio_uninit(struct platform_device *dsidev) 2500static void dsi_cio_uninit(struct omap_dss_device *dssdev)
2476{ 2501{
2502 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2477 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2503 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2478 2504
2505 /* DDR_CLK_ALWAYS_ON */
2506 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
2507
2479 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); 2508 dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
2480 dsi_disable_scp_clk(dsidev); 2509 dsi_disable_scp_clk(dsidev);
2481 if (dsi->dsi_mux_pads) 2510 dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev));
2482 dsi->dsi_mux_pads(false);
2483} 2511}
2484 2512
2485static void dsi_config_tx_fifo(struct platform_device *dsidev, 2513static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -2669,10 +2697,10 @@ static int dsi_sync_vc(struct platform_device *dsidev, int channel)
2669 if (!dsi_vc_is_enabled(dsidev, channel)) 2697 if (!dsi_vc_is_enabled(dsidev, channel))
2670 return 0; 2698 return 0;
2671 2699
2672 switch (dsi->vc[channel].mode) { 2700 switch (dsi->vc[channel].source) {
2673 case DSI_VC_MODE_VP: 2701 case DSI_VC_SOURCE_VP:
2674 return dsi_sync_vc_vp(dsidev, channel); 2702 return dsi_sync_vc_vp(dsidev, channel);
2675 case DSI_VC_MODE_L4: 2703 case DSI_VC_SOURCE_L4:
2676 return dsi_sync_vc_l4(dsidev, channel); 2704 return dsi_sync_vc_l4(dsidev, channel);
2677 default: 2705 default:
2678 BUG(); 2706 BUG();
@@ -2726,43 +2754,12 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
2726 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r); 2754 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
2727} 2755}
2728 2756
2729static int dsi_vc_config_l4(struct platform_device *dsidev, int channel) 2757static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
2758 enum dsi_vc_source source)
2730{ 2759{
2731 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2760 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2732 2761
2733 if (dsi->vc[channel].mode == DSI_VC_MODE_L4) 2762 if (dsi->vc[channel].source == source)
2734 return 0;
2735
2736 DSSDBGF("%d", channel);
2737
2738 dsi_sync_vc(dsidev, channel);
2739
2740 dsi_vc_enable(dsidev, channel, 0);
2741
2742 /* VC_BUSY */
2743 if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
2744 DSSERR("vc(%d) busy when trying to config for L4\n", channel);
2745 return -EIO;
2746 }
2747
2748 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
2749
2750 /* DCS_CMD_ENABLE */
2751 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
2752 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30);
2753
2754 dsi_vc_enable(dsidev, channel, 1);
2755
2756 dsi->vc[channel].mode = DSI_VC_MODE_L4;
2757
2758 return 0;
2759}
2760
2761static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
2762{
2763 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2764
2765 if (dsi->vc[channel].mode == DSI_VC_MODE_VP)
2766 return 0; 2763 return 0;
2767 2764
2768 DSSDBGF("%d", channel); 2765 DSSDBGF("%d", channel);
@@ -2777,21 +2774,22 @@ static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
2777 return -EIO; 2774 return -EIO;
2778 } 2775 }
2779 2776
2780 /* SOURCE, 1 = video port */ 2777 /* SOURCE, 0 = L4, 1 = video port */
2781 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1); 2778 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), source, 1, 1);
2782 2779
2783 /* DCS_CMD_ENABLE */ 2780 /* DCS_CMD_ENABLE */
2784 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) 2781 if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
2785 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30); 2782 bool enable = source == DSI_VC_SOURCE_VP;
2783 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 30, 30);
2784 }
2786 2785
2787 dsi_vc_enable(dsidev, channel, 1); 2786 dsi_vc_enable(dsidev, channel, 1);
2788 2787
2789 dsi->vc[channel].mode = DSI_VC_MODE_VP; 2788 dsi->vc[channel].source = source;
2790 2789
2791 return 0; 2790 return 0;
2792} 2791}
2793 2792
2794
2795void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, 2793void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
2796 bool enable) 2794 bool enable)
2797{ 2795{
@@ -2810,6 +2808,10 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
2810 dsi_if_enable(dsidev, 1); 2808 dsi_if_enable(dsidev, 1);
2811 2809
2812 dsi_force_tx_stop_mode_io(dsidev); 2810 dsi_force_tx_stop_mode_io(dsidev);
2811
2812 /* start the DDR clock by sending a NULL packet */
2813 if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable)
2814 dsi_vc_send_null(dssdev, channel);
2813} 2815}
2814EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); 2816EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
2815 2817
@@ -2873,16 +2875,16 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
2873 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); 2875 val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
2874 DSSERR("\trawval %#08x\n", val); 2876 DSSERR("\trawval %#08x\n", val);
2875 dt = FLD_GET(val, 5, 0); 2877 dt = FLD_GET(val, 5, 0);
2876 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 2878 if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
2877 u16 err = FLD_GET(val, 23, 8); 2879 u16 err = FLD_GET(val, 23, 8);
2878 dsi_show_rx_ack_with_err(err); 2880 dsi_show_rx_ack_with_err(err);
2879 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 2881 } else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE) {
2880 DSSERR("\tDCS short response, 1 byte: %#x\n", 2882 DSSERR("\tDCS short response, 1 byte: %#x\n",
2881 FLD_GET(val, 23, 8)); 2883 FLD_GET(val, 23, 8));
2882 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 2884 } else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE) {
2883 DSSERR("\tDCS short response, 2 byte: %#x\n", 2885 DSSERR("\tDCS short response, 2 byte: %#x\n",
2884 FLD_GET(val, 23, 8)); 2886 FLD_GET(val, 23, 8));
2885 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 2887 } else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
2886 DSSERR("\tDCS long response, len %d\n", 2888 DSSERR("\tDCS long response, len %d\n",
2887 FLD_GET(val, 23, 8)); 2889 FLD_GET(val, 23, 8));
2888 dsi_vc_flush_long_data(dsidev, channel); 2890 dsi_vc_flush_long_data(dsidev, channel);
@@ -3007,7 +3009,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
3007 return -EINVAL; 3009 return -EINVAL;
3008 } 3010 }
3009 3011
3010 dsi_vc_config_l4(dsidev, channel); 3012 dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_L4);
3011 3013
3012 dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc); 3014 dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc);
3013 3015
@@ -3066,7 +3068,7 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
3066 channel, 3068 channel,
3067 data_type, data & 0xff, (data >> 8) & 0xff); 3069 data_type, data & 0xff, (data >> 8) & 0xff);
3068 3070
3069 dsi_vc_config_l4(dsidev, channel); 3071 dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_L4);
3070 3072
3071 if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) { 3073 if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) {
3072 DSSERR("ERROR FIFO FULL, aborting transfer\n"); 3074 DSSERR("ERROR FIFO FULL, aborting transfer\n");
@@ -3085,44 +3087,66 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
3085int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) 3087int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
3086{ 3088{
3087 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3089 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3088 u8 nullpkg[] = {0, 0, 0, 0};
3089 3090
3090 return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg, 3091 return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL,
3091 4, 0); 3092 0, 0);
3092} 3093}
3093EXPORT_SYMBOL(dsi_vc_send_null); 3094EXPORT_SYMBOL(dsi_vc_send_null);
3094 3095
3095int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, 3096static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
3096 u8 *data, int len) 3097 int channel, u8 *data, int len, enum dss_dsi_content_type type)
3097{ 3098{
3098 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3099 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3099 int r; 3100 int r;
3100 3101
3101 BUG_ON(len == 0); 3102 if (len == 0) {
3102 3103 BUG_ON(type == DSS_DSI_CONTENT_DCS);
3103 if (len == 1) { 3104 r = dsi_vc_send_short(dsidev, channel,
3104 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0, 3105 MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM, 0, 0);
3105 data[0], 0); 3106 } else if (len == 1) {
3107 r = dsi_vc_send_short(dsidev, channel,
3108 type == DSS_DSI_CONTENT_GENERIC ?
3109 MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
3110 MIPI_DSI_DCS_SHORT_WRITE, data[0], 0);
3106 } else if (len == 2) { 3111 } else if (len == 2) {
3107 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1, 3112 r = dsi_vc_send_short(dsidev, channel,
3113 type == DSS_DSI_CONTENT_GENERIC ?
3114 MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
3115 MIPI_DSI_DCS_SHORT_WRITE_PARAM,
3108 data[0] | (data[1] << 8), 0); 3116 data[0] | (data[1] << 8), 0);
3109 } else { 3117 } else {
3110 /* 0x39 = DCS Long Write */ 3118 r = dsi_vc_send_long(dsidev, channel,
3111 r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE, 3119 type == DSS_DSI_CONTENT_GENERIC ?
3112 data, len, 0); 3120 MIPI_DSI_GENERIC_LONG_WRITE :
3121 MIPI_DSI_DCS_LONG_WRITE, data, len, 0);
3113 } 3122 }
3114 3123
3115 return r; 3124 return r;
3116} 3125}
3126
3127int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
3128 u8 *data, int len)
3129{
3130 return dsi_vc_write_nosync_common(dssdev, channel, data, len,
3131 DSS_DSI_CONTENT_DCS);
3132}
3117EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); 3133EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
3118 3134
3119int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, 3135int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
3120 int len) 3136 u8 *data, int len)
3137{
3138 return dsi_vc_write_nosync_common(dssdev, channel, data, len,
3139 DSS_DSI_CONTENT_GENERIC);
3140}
3141EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
3142
3143static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
3144 u8 *data, int len, enum dss_dsi_content_type type)
3121{ 3145{
3122 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3146 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3123 int r; 3147 int r;
3124 3148
3125 r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len); 3149 r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type);
3126 if (r) 3150 if (r)
3127 goto err; 3151 goto err;
3128 3152
@@ -3140,18 +3164,39 @@ int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
3140 3164
3141 return 0; 3165 return 0;
3142err: 3166err:
3143 DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n", 3167 DSSERR("dsi_vc_write_common(ch %d, cmd 0x%02x, len %d) failed\n",
3144 channel, data[0], len); 3168 channel, data[0], len);
3145 return r; 3169 return r;
3146} 3170}
3171
3172int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
3173 int len)
3174{
3175 return dsi_vc_write_common(dssdev, channel, data, len,
3176 DSS_DSI_CONTENT_DCS);
3177}
3147EXPORT_SYMBOL(dsi_vc_dcs_write); 3178EXPORT_SYMBOL(dsi_vc_dcs_write);
3148 3179
3180int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
3181 int len)
3182{
3183 return dsi_vc_write_common(dssdev, channel, data, len,
3184 DSS_DSI_CONTENT_GENERIC);
3185}
3186EXPORT_SYMBOL(dsi_vc_generic_write);
3187
3149int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd) 3188int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
3150{ 3189{
3151 return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1); 3190 return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
3152} 3191}
3153EXPORT_SYMBOL(dsi_vc_dcs_write_0); 3192EXPORT_SYMBOL(dsi_vc_dcs_write_0);
3154 3193
3194int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel)
3195{
3196 return dsi_vc_generic_write(dssdev, channel, NULL, 0);
3197}
3198EXPORT_SYMBOL(dsi_vc_generic_write_0);
3199
3155int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, 3200int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3156 u8 param) 3201 u8 param)
3157{ 3202{
@@ -3162,25 +3207,87 @@ int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3162} 3207}
3163EXPORT_SYMBOL(dsi_vc_dcs_write_1); 3208EXPORT_SYMBOL(dsi_vc_dcs_write_1);
3164 3209
3165int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, 3210int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel,
3166 u8 *buf, int buflen) 3211 u8 param)
3212{
3213 return dsi_vc_generic_write(dssdev, channel, &param, 1);
3214}
3215EXPORT_SYMBOL(dsi_vc_generic_write_1);
3216
3217int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
3218 u8 param1, u8 param2)
3219{
3220 u8 buf[2];
3221 buf[0] = param1;
3222 buf[1] = param2;
3223 return dsi_vc_generic_write(dssdev, channel, buf, 2);
3224}
3225EXPORT_SYMBOL(dsi_vc_generic_write_2);
3226
3227static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
3228 int channel, u8 dcs_cmd)
3167{ 3229{
3168 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3230 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3169 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3231 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3170 u32 val;
3171 u8 dt;
3172 int r; 3232 int r;
3173 3233
3174 if (dsi->debug_read) 3234 if (dsi->debug_read)
3175 DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); 3235 DSSDBG("dsi_vc_dcs_send_read_request(ch%d, dcs_cmd %x)\n",
3236 channel, dcs_cmd);
3176 3237
3177 r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0); 3238 r = dsi_vc_send_short(dsidev, channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
3178 if (r) 3239 if (r) {
3179 goto err; 3240 DSSERR("dsi_vc_dcs_send_read_request(ch %d, cmd 0x%02x)"
3241 " failed\n", channel, dcs_cmd);
3242 return r;
3243 }
3180 3244
3181 r = dsi_vc_send_bta_sync(dssdev, channel); 3245 return 0;
3182 if (r) 3246}
3183 goto err; 3247
3248static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev,
3249 int channel, u8 *reqdata, int reqlen)
3250{
3251 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3252 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3253 u16 data;
3254 u8 data_type;
3255 int r;
3256
3257 if (dsi->debug_read)
3258 DSSDBG("dsi_vc_generic_send_read_request(ch %d, reqlen %d)\n",
3259 channel, reqlen);
3260
3261 if (reqlen == 0) {
3262 data_type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
3263 data = 0;
3264 } else if (reqlen == 1) {
3265 data_type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
3266 data = reqdata[0];
3267 } else if (reqlen == 2) {
3268 data_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
3269 data = reqdata[0] | (reqdata[1] << 8);
3270 } else {
3271 BUG();
3272 }
3273
3274 r = dsi_vc_send_short(dsidev, channel, data_type, data, 0);
3275 if (r) {
3276 DSSERR("dsi_vc_generic_send_read_request(ch %d, reqlen %d)"
3277 " failed\n", channel, reqlen);
3278 return r;
3279 }
3280
3281 return 0;
3282}
3283
3284static int dsi_vc_read_rx_fifo(struct platform_device *dsidev, int channel,
3285 u8 *buf, int buflen, enum dss_dsi_content_type type)
3286{
3287 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3288 u32 val;
3289 u8 dt;
3290 int r;
3184 3291
3185 /* RX_FIFO_NOT_EMPTY */ 3292 /* RX_FIFO_NOT_EMPTY */
3186 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) { 3293 if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
@@ -3193,16 +3300,20 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3193 if (dsi->debug_read) 3300 if (dsi->debug_read)
3194 DSSDBG("\theader: %08x\n", val); 3301 DSSDBG("\theader: %08x\n", val);
3195 dt = FLD_GET(val, 5, 0); 3302 dt = FLD_GET(val, 5, 0);
3196 if (dt == DSI_DT_RX_ACK_WITH_ERR) { 3303 if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
3197 u16 err = FLD_GET(val, 23, 8); 3304 u16 err = FLD_GET(val, 23, 8);
3198 dsi_show_rx_ack_with_err(err); 3305 dsi_show_rx_ack_with_err(err);
3199 r = -EIO; 3306 r = -EIO;
3200 goto err; 3307 goto err;
3201 3308
3202 } else if (dt == DSI_DT_RX_SHORT_READ_1) { 3309 } else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
3310 MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE :
3311 MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE)) {
3203 u8 data = FLD_GET(val, 15, 8); 3312 u8 data = FLD_GET(val, 15, 8);
3204 if (dsi->debug_read) 3313 if (dsi->debug_read)
3205 DSSDBG("\tDCS short response, 1 byte: %02x\n", data); 3314 DSSDBG("\t%s short response, 1 byte: %02x\n",
3315 type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
3316 "DCS", data);
3206 3317
3207 if (buflen < 1) { 3318 if (buflen < 1) {
3208 r = -EIO; 3319 r = -EIO;
@@ -3212,10 +3323,14 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3212 buf[0] = data; 3323 buf[0] = data;
3213 3324
3214 return 1; 3325 return 1;
3215 } else if (dt == DSI_DT_RX_SHORT_READ_2) { 3326 } else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
3327 MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE :
3328 MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE)) {
3216 u16 data = FLD_GET(val, 23, 8); 3329 u16 data = FLD_GET(val, 23, 8);
3217 if (dsi->debug_read) 3330 if (dsi->debug_read)
3218 DSSDBG("\tDCS short response, 2 byte: %04x\n", data); 3331 DSSDBG("\t%s short response, 2 byte: %04x\n",
3332 type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
3333 "DCS", data);
3219 3334
3220 if (buflen < 2) { 3335 if (buflen < 2) {
3221 r = -EIO; 3336 r = -EIO;
@@ -3226,11 +3341,15 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3226 buf[1] = (data >> 8) & 0xff; 3341 buf[1] = (data >> 8) & 0xff;
3227 3342
3228 return 2; 3343 return 2;
3229 } else if (dt == DSI_DT_RX_DCS_LONG_READ) { 3344 } else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
3345 MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE :
3346 MIPI_DSI_RX_DCS_LONG_READ_RESPONSE)) {
3230 int w; 3347 int w;
3231 int len = FLD_GET(val, 23, 8); 3348 int len = FLD_GET(val, 23, 8);
3232 if (dsi->debug_read) 3349 if (dsi->debug_read)
3233 DSSDBG("\tDCS long response, len %d\n", len); 3350 DSSDBG("\t%s long response, len %d\n",
3351 type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
3352 "DCS", len);
3234 3353
3235 if (len > buflen) { 3354 if (len > buflen) {
3236 r = -EIO; 3355 r = -EIO;
@@ -3266,58 +3385,126 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3266 3385
3267 BUG(); 3386 BUG();
3268err: 3387err:
3269 DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", 3388 DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel,
3270 channel, dcs_cmd); 3389 type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS");
3390
3271 return r; 3391 return r;
3392}
3272 3393
3394int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
3395 u8 *buf, int buflen)
3396{
3397 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3398 int r;
3399
3400 r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd);
3401 if (r)
3402 goto err;
3403
3404 r = dsi_vc_send_bta_sync(dssdev, channel);
3405 if (r)
3406 goto err;
3407
3408 r = dsi_vc_read_rx_fifo(dsidev, channel, buf, buflen,
3409 DSS_DSI_CONTENT_DCS);
3410 if (r < 0)
3411 goto err;
3412
3413 if (r != buflen) {
3414 r = -EIO;
3415 goto err;
3416 }
3417
3418 return 0;
3419err:
3420 DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd);
3421 return r;
3273} 3422}
3274EXPORT_SYMBOL(dsi_vc_dcs_read); 3423EXPORT_SYMBOL(dsi_vc_dcs_read);
3275 3424
3276int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, 3425static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
3277 u8 *data) 3426 u8 *reqdata, int reqlen, u8 *buf, int buflen)
3278{ 3427{
3428 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3279 int r; 3429 int r;
3280 3430
3281 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1); 3431 r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen);
3432 if (r)
3433 return r;
3434
3435 r = dsi_vc_send_bta_sync(dssdev, channel);
3436 if (r)
3437 return r;
3282 3438
3439 r = dsi_vc_read_rx_fifo(dsidev, channel, buf, buflen,
3440 DSS_DSI_CONTENT_GENERIC);
3283 if (r < 0) 3441 if (r < 0)
3284 return r; 3442 return r;
3285 3443
3286 if (r != 1) 3444 if (r != buflen) {
3287 return -EIO; 3445 r = -EIO;
3446 return r;
3447 }
3288 3448
3289 return 0; 3449 return 0;
3290} 3450}
3291EXPORT_SYMBOL(dsi_vc_dcs_read_1);
3292 3451
3293int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, 3452int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
3294 u8 *data1, u8 *data2) 3453 int buflen)
3295{ 3454{
3296 u8 buf[2];
3297 int r; 3455 int r;
3298 3456
3299 r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2); 3457 r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen);
3458 if (r) {
3459 DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel);
3460 return r;
3461 }
3300 3462
3301 if (r < 0) 3463 return 0;
3464}
3465EXPORT_SYMBOL(dsi_vc_generic_read_0);
3466
3467int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
3468 u8 *buf, int buflen)
3469{
3470 int r;
3471
3472 r = dsi_vc_generic_read(dssdev, channel, &param, 1, buf, buflen);
3473 if (r) {
3474 DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel);
3302 return r; 3475 return r;
3476 }
3303 3477
3304 if (r != 2) 3478 return 0;
3305 return -EIO; 3479}
3480EXPORT_SYMBOL(dsi_vc_generic_read_1);
3306 3481
3307 *data1 = buf[0]; 3482int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
3308 *data2 = buf[1]; 3483 u8 param1, u8 param2, u8 *buf, int buflen)
3484{
3485 int r;
3486 u8 reqdata[2];
3487
3488 reqdata[0] = param1;
3489 reqdata[1] = param2;
3490
3491 r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen);
3492 if (r) {
3493 DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel);
3494 return r;
3495 }
3309 3496
3310 return 0; 3497 return 0;
3311} 3498}
3312EXPORT_SYMBOL(dsi_vc_dcs_read_2); 3499EXPORT_SYMBOL(dsi_vc_generic_read_2);
3313 3500
3314int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, 3501int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
3315 u16 len) 3502 u16 len)
3316{ 3503{
3317 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3504 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3318 3505
3319 return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE, 3506 return dsi_vc_send_short(dsidev, channel,
3320 len, 0); 3507 MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
3321} 3508}
3322EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); 3509EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
3323 3510
@@ -3508,6 +3695,75 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
3508 ticks, x4 ? " x4" : "", x16 ? " x16" : "", 3695 ticks, x4 ? " x4" : "", x16 ? " x16" : "",
3509 (total_ticks * 1000) / (fck / 1000 / 1000)); 3696 (total_ticks * 1000) / (fck / 1000 / 1000));
3510} 3697}
3698
3699static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
3700{
3701 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3702 int num_line_buffers;
3703
3704 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
3705 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
3706 unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
3707 struct omap_video_timings *timings = &dssdev->panel.timings;
3708 /*
3709 * Don't use line buffers if width is greater than the video
3710 * port's line buffer size
3711 */
3712 if (line_buf_size <= timings->x_res * bpp / 8)
3713 num_line_buffers = 0;
3714 else
3715 num_line_buffers = 2;
3716 } else {
3717 /* Use maximum number of line buffers in command mode */
3718 num_line_buffers = 2;
3719 }
3720
3721 /* LINE_BUFFER */
3722 REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12);
3723}
3724
3725static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
3726{
3727 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3728 int de_pol = dssdev->panel.dsi_vm_data.vp_de_pol;
3729 int hsync_pol = dssdev->panel.dsi_vm_data.vp_hsync_pol;
3730 int vsync_pol = dssdev->panel.dsi_vm_data.vp_vsync_pol;
3731 bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
3732 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
3733 u32 r;
3734
3735 r = dsi_read_reg(dsidev, DSI_CTRL);
3736 r = FLD_MOD(r, de_pol, 9, 9); /* VP_DE_POL */
3737 r = FLD_MOD(r, hsync_pol, 10, 10); /* VP_HSYNC_POL */
3738 r = FLD_MOD(r, vsync_pol, 11, 11); /* VP_VSYNC_POL */
3739 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */
3740 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */
3741 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */
3742 r = FLD_MOD(r, hsync_end, 18, 18); /* VP_HSYNC_END */
3743 dsi_write_reg(dsidev, DSI_CTRL, r);
3744}
3745
3746static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
3747{
3748 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3749 int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
3750 int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
3751 int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
3752 int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
3753 u32 r;
3754
3755 /*
3756 * 0 = TX FIFO packets sent or LPS in corresponding blanking periods
3757 * 1 = Long blanking packets are sent in corresponding blanking periods
3758 */
3759 r = dsi_read_reg(dsidev, DSI_CTRL);
3760 r = FLD_MOD(r, blanking_mode, 20, 20); /* BLANKING_MODE */
3761 r = FLD_MOD(r, hfp_blanking_mode, 21, 21); /* HFP_BLANKING */
3762 r = FLD_MOD(r, hbp_blanking_mode, 22, 22); /* HBP_BLANKING */
3763 r = FLD_MOD(r, hsa_blanking_mode, 23, 23); /* HSA_BLANKING */
3764 dsi_write_reg(dsidev, DSI_CTRL, r);
3765}
3766
3511static int dsi_proto_config(struct omap_dss_device *dssdev) 3767static int dsi_proto_config(struct omap_dss_device *dssdev)
3512{ 3768{
3513 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3769 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3530,7 +3786,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
3530 dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); 3786 dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
3531 dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); 3787 dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
3532 3788
3533 switch (dssdev->ctrl.pixel_size) { 3789 switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) {
3534 case 16: 3790 case 16:
3535 buswidth = 0; 3791 buswidth = 0;
3536 break; 3792 break;
@@ -3551,7 +3807,6 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
3551 r = FLD_MOD(r, 1, 4, 4); /* VP_CLK_RATIO, always 1, see errata*/ 3807 r = FLD_MOD(r, 1, 4, 4); /* VP_CLK_RATIO, always 1, see errata*/
3552 r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */ 3808 r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
3553 r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */ 3809 r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
3554 r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */
3555 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ 3810 r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
3556 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ 3811 r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
3557 if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) { 3812 if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
@@ -3562,6 +3817,13 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
3562 3817
3563 dsi_write_reg(dsidev, DSI_CTRL, r); 3818 dsi_write_reg(dsidev, DSI_CTRL, r);
3564 3819
3820 dsi_config_vp_num_line_buffers(dssdev);
3821
3822 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
3823 dsi_config_vp_sync_events(dssdev);
3824 dsi_config_blanking_modes(dssdev);
3825 }
3826
3565 dsi_vc_initial_config(dsidev, 0); 3827 dsi_vc_initial_config(dsidev, 0);
3566 dsi_vc_initial_config(dsidev, 1); 3828 dsi_vc_initial_config(dsidev, 1);
3567 dsi_vc_initial_config(dsidev, 2); 3829 dsi_vc_initial_config(dsidev, 2);
@@ -3580,6 +3842,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
3580 unsigned ddr_clk_pre, ddr_clk_post; 3842 unsigned ddr_clk_pre, ddr_clk_post;
3581 unsigned enter_hs_mode_lat, exit_hs_mode_lat; 3843 unsigned enter_hs_mode_lat, exit_hs_mode_lat;
3582 unsigned ths_eot; 3844 unsigned ths_eot;
3845 int ndl = dsi_get_num_data_lanes_dssdev(dssdev);
3583 u32 r; 3846 u32 r;
3584 3847
3585 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); 3848 r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
@@ -3602,7 +3865,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
3602 /* min 60ns + 52*UI */ 3865 /* min 60ns + 52*UI */
3603 tclk_post = ns2ddr(dsidev, 60) + 26; 3866 tclk_post = ns2ddr(dsidev, 60) + 26;
3604 3867
3605 ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev)); 3868 ths_eot = DIV_ROUND_UP(4, ndl);
3606 3869
3607 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, 3870 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
3608 4); 3871 4);
@@ -3632,162 +3895,114 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
3632 3895
3633 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", 3896 DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
3634 enter_hs_mode_lat, exit_hs_mode_lat); 3897 enter_hs_mode_lat, exit_hs_mode_lat);
3635}
3636
3637
3638#define DSI_DECL_VARS \
3639 int __dsi_cb = 0; u32 __dsi_cv = 0;
3640 3898
3641#define DSI_FLUSH(dsidev, ch) \ 3899 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
3642 if (__dsi_cb > 0) { \ 3900 /* TODO: Implement a video mode check_timings function */
3643 /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ 3901 int hsa = dssdev->panel.dsi_vm_data.hsa;
3644 dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ 3902 int hfp = dssdev->panel.dsi_vm_data.hfp;
3645 __dsi_cb = __dsi_cv = 0; \ 3903 int hbp = dssdev->panel.dsi_vm_data.hbp;
3904 int vsa = dssdev->panel.dsi_vm_data.vsa;
3905 int vfp = dssdev->panel.dsi_vm_data.vfp;
3906 int vbp = dssdev->panel.dsi_vm_data.vbp;
3907 int window_sync = dssdev->panel.dsi_vm_data.window_sync;
3908 bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
3909 struct omap_video_timings *timings = &dssdev->panel.timings;
3910 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
3911 int tl, t_he, width_bytes;
3912
3913 t_he = hsync_end ?
3914 ((hsa == 0 && ndl == 3) ? 1 : DIV_ROUND_UP(4, ndl)) : 0;
3915
3916 width_bytes = DIV_ROUND_UP(timings->x_res * bpp, 8);
3917
3918 /* TL = t_HS + HSA + t_HE + HFP + ceil((WC + 6) / NDL) + HBP */
3919 tl = DIV_ROUND_UP(4, ndl) + (hsync_end ? hsa : 0) + t_he + hfp +
3920 DIV_ROUND_UP(width_bytes + 6, ndl) + hbp;
3921
3922 DSSDBG("HBP: %d, HFP: %d, HSA: %d, TL: %d TXBYTECLKHS\n", hbp,
3923 hfp, hsync_end ? hsa : 0, tl);
3924 DSSDBG("VBP: %d, VFP: %d, VSA: %d, VACT: %d lines\n", vbp, vfp,
3925 vsa, timings->y_res);
3926
3927 r = dsi_read_reg(dsidev, DSI_VM_TIMING1);
3928 r = FLD_MOD(r, hbp, 11, 0); /* HBP */
3929 r = FLD_MOD(r, hfp, 23, 12); /* HFP */
3930 r = FLD_MOD(r, hsync_end ? hsa : 0, 31, 24); /* HSA */
3931 dsi_write_reg(dsidev, DSI_VM_TIMING1, r);
3932
3933 r = dsi_read_reg(dsidev, DSI_VM_TIMING2);
3934 r = FLD_MOD(r, vbp, 7, 0); /* VBP */
3935 r = FLD_MOD(r, vfp, 15, 8); /* VFP */
3936 r = FLD_MOD(r, vsa, 23, 16); /* VSA */
3937 r = FLD_MOD(r, window_sync, 27, 24); /* WINDOW_SYNC */
3938 dsi_write_reg(dsidev, DSI_VM_TIMING2, r);
3939
3940 r = dsi_read_reg(dsidev, DSI_VM_TIMING3);
3941 r = FLD_MOD(r, timings->y_res, 14, 0); /* VACT */
3942 r = FLD_MOD(r, tl, 31, 16); /* TL */
3943 dsi_write_reg(dsidev, DSI_VM_TIMING3, r);
3646 } 3944 }
3945}
3647 3946
3648#define DSI_PUSH(dsidev, ch, data) \ 3947int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
3649 do { \
3650 __dsi_cv |= (data) << (__dsi_cb * 8); \
3651 /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
3652 if (++__dsi_cb > 3) \
3653 DSI_FLUSH(dsidev, ch); \
3654 } while (0)
3655
3656static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
3657 int x, int y, int w, int h)
3658{ 3948{
3659 /* Note: supports only 24bit colors in 32bit container */
3660 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3949 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3661 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3950 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
3662 int first = 1; 3951 u8 data_type;
3663 int fifo_stalls = 0; 3952 u16 word_count;
3664 int max_dsi_packet_size;
3665 int max_data_per_packet;
3666 int max_pixels_per_packet;
3667 int pixels_left;
3668 int bytespp = dssdev->ctrl.pixel_size / 8;
3669 int scr_width;
3670 u32 __iomem *data;
3671 int start_offset;
3672 int horiz_inc;
3673 int current_x;
3674 struct omap_overlay *ovl;
3675
3676 debug_irq = 0;
3677
3678 DSSDBG("dsi_update_screen_l4 (%d,%d %dx%d)\n",
3679 x, y, w, h);
3680 3953
3681 ovl = dssdev->manager->overlays[0]; 3954 switch (dssdev->panel.dsi_pix_fmt) {
3682 3955 case OMAP_DSS_DSI_FMT_RGB888:
3683 if (ovl->info.color_mode != OMAP_DSS_COLOR_RGB24U) 3956 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
3684 return -EINVAL; 3957 break;
3685 3958 case OMAP_DSS_DSI_FMT_RGB666:
3686 if (dssdev->ctrl.pixel_size != 24) 3959 data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
3687 return -EINVAL; 3960 break;
3688 3961 case OMAP_DSS_DSI_FMT_RGB666_PACKED:
3689 scr_width = ovl->info.screen_width; 3962 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
3690 data = ovl->info.vaddr; 3963 break;
3691 3964 case OMAP_DSS_DSI_FMT_RGB565:
3692 start_offset = scr_width * y + x; 3965 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
3693 horiz_inc = scr_width - w; 3966 break;
3694 current_x = x; 3967 default:
3695 3968 BUG();
3696 /* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp) bytes 3969 };
3697 * in fifo */
3698
3699 /* When using CPU, max long packet size is TX buffer size */
3700 max_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4;
3701
3702 /* we seem to get better perf if we divide the tx fifo to half,
3703 and while the other half is being sent, we fill the other half
3704 max_dsi_packet_size /= 2; */
3705
3706 max_data_per_packet = max_dsi_packet_size - 4 - 1;
3707
3708 max_pixels_per_packet = max_data_per_packet / bytespp;
3709
3710 DSSDBG("max_pixels_per_packet %d\n", max_pixels_per_packet);
3711
3712 pixels_left = w * h;
3713 3970
3714 DSSDBG("total pixels %d\n", pixels_left); 3971 dsi_if_enable(dsidev, false);
3972 dsi_vc_enable(dsidev, channel, false);
3715 3973
3716 data += start_offset; 3974 /* MODE, 1 = video mode */
3975 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
3717 3976
3718 while (pixels_left > 0) { 3977 word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
3719 /* 0x2c = write_memory_start */
3720 /* 0x3c = write_memory_continue */
3721 u8 dcs_cmd = first ? 0x2c : 0x3c;
3722 int pixels;
3723 DSI_DECL_VARS;
3724 first = 0;
3725 3978
3726#if 1 3979 dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0);
3727 /* using fifo not empty */
3728 /* TX_FIFO_NOT_EMPTY */
3729 while (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(0)), 5, 5)) {
3730 fifo_stalls++;
3731 if (fifo_stalls > 0xfffff) {
3732 DSSERR("fifo stalls overflow, pixels left %d\n",
3733 pixels_left);
3734 dsi_if_enable(dsidev, 0);
3735 return -EIO;
3736 }
3737 udelay(1);
3738 }
3739#elif 1
3740 /* using fifo emptiness */
3741 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
3742 max_dsi_packet_size) {
3743 fifo_stalls++;
3744 if (fifo_stalls > 0xfffff) {
3745 DSSERR("fifo stalls overflow, pixels left %d\n",
3746 pixels_left);
3747 dsi_if_enable(dsidev, 0);
3748 return -EIO;
3749 }
3750 }
3751#else
3752 while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS,
3753 7, 0) + 1) * 4 == 0) {
3754 fifo_stalls++;
3755 if (fifo_stalls > 0xfffff) {
3756 DSSERR("fifo stalls overflow, pixels left %d\n",
3757 pixels_left);
3758 dsi_if_enable(dsidev, 0);
3759 return -EIO;
3760 }
3761 }
3762#endif
3763 pixels = min(max_pixels_per_packet, pixels_left);
3764 3980
3765 pixels_left -= pixels; 3981 dsi_vc_enable(dsidev, channel, true);
3982 dsi_if_enable(dsidev, true);
3766 3983
3767 dsi_vc_write_long_header(dsidev, 0, DSI_DT_DCS_LONG_WRITE, 3984 dssdev->manager->enable(dssdev->manager);
3768 1 + pixels * bytespp, 0);
3769 3985
3770 DSI_PUSH(dsidev, 0, dcs_cmd); 3986 return 0;
3987}
3988EXPORT_SYMBOL(dsi_video_mode_enable);
3771 3989
3772 while (pixels-- > 0) { 3990void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
3773 u32 pix = __raw_readl(data++); 3991{
3992 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3774 3993
3775 DSI_PUSH(dsidev, 0, (pix >> 16) & 0xff); 3994 dsi_if_enable(dsidev, false);
3776 DSI_PUSH(dsidev, 0, (pix >> 8) & 0xff); 3995 dsi_vc_enable(dsidev, channel, false);
3777 DSI_PUSH(dsidev, 0, (pix >> 0) & 0xff);
3778 3996
3779 current_x++; 3997 /* MODE, 0 = command mode */
3780 if (current_x == x+w) { 3998 REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
3781 current_x = x;
3782 data += horiz_inc;
3783 }
3784 }
3785 3999
3786 DSI_FLUSH(dsidev, 0); 4000 dsi_vc_enable(dsidev, channel, true);
3787 } 4001 dsi_if_enable(dsidev, true);
3788 4002
3789 return 0; 4003 dssdev->manager->disable(dssdev->manager);
3790} 4004}
4005EXPORT_SYMBOL(dsi_video_mode_disable);
3791 4006
3792static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, 4007static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3793 u16 x, u16 y, u16 w, u16 h) 4008 u16 x, u16 y, u16 w, u16 h)
@@ -3808,9 +4023,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3808 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", 4023 DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
3809 x, y, w, h); 4024 x, y, w, h);
3810 4025
3811 dsi_vc_config_vp(dsidev, channel); 4026 dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
3812 4027
3813 bytespp = dssdev->ctrl.pixel_size / 8; 4028 bytespp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
3814 bytespl = w * bytespp; 4029 bytespl = w * bytespp;
3815 bytespf = bytespl * h; 4030 bytespf = bytespl * h;
3816 4031
@@ -3831,7 +4046,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
3831 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ 4046 l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
3832 dsi_write_reg(dsidev, DSI_VC_TE(channel), l); 4047 dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
3833 4048
3834 dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE, 4049 dsi_vc_write_long_header(dsidev, channel, MIPI_DSI_DCS_LONG_WRITE,
3835 packet_len, 0); 4050 packet_len, 0);
3836 4051
3837 if (dsi->te_enabled) 4052 if (dsi->te_enabled)
@@ -3956,11 +4171,9 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
3956 4171
3957 dsi_perf_mark_setup(dsidev); 4172 dsi_perf_mark_setup(dsidev);
3958 4173
3959 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 4174 dss_setup_partial_planes(dssdev, x, y, w, h,
3960 dss_setup_partial_planes(dssdev, x, y, w, h, 4175 enlarge_update_area);
3961 enlarge_update_area); 4176 dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
3962 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
3963 }
3964 4177
3965 return 0; 4178 return 0;
3966} 4179}
@@ -3982,27 +4195,16 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
3982 * see rather obscure HW error happening, as DSS halts. */ 4195 * see rather obscure HW error happening, as DSS halts. */
3983 BUG_ON(x % 2 == 1); 4196 BUG_ON(x % 2 == 1);
3984 4197
3985 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 4198 dsi->framedone_callback = callback;
3986 dsi->framedone_callback = callback; 4199 dsi->framedone_data = data;
3987 dsi->framedone_data = data;
3988
3989 dsi->update_region.x = x;
3990 dsi->update_region.y = y;
3991 dsi->update_region.w = w;
3992 dsi->update_region.h = h;
3993 dsi->update_region.device = dssdev;
3994
3995 dsi_update_screen_dispc(dssdev, x, y, w, h);
3996 } else {
3997 int r;
3998 4200
3999 r = dsi_update_screen_l4(dssdev, x, y, w, h); 4201 dsi->update_region.x = x;
4000 if (r) 4202 dsi->update_region.y = y;
4001 return r; 4203 dsi->update_region.w = w;
4204 dsi->update_region.h = h;
4205 dsi->update_region.device = dssdev;
4002 4206
4003 dsi_perf_show(dsidev, "L4"); 4207 dsi_update_screen_dispc(dssdev, x, y, w, h);
4004 callback(0, data);
4005 }
4006 4208
4007 return 0; 4209 return 0;
4008} 4210}
@@ -4013,28 +4215,9 @@ EXPORT_SYMBOL(omap_dsi_update);
4013static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4215static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4014{ 4216{
4015 int r; 4217 int r;
4016 u32 irq;
4017
4018 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4019 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4020 4218
4021 r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev, 4219 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4022 irq); 4220 u32 irq;
4023 if (r) {
4024 DSSERR("can't get FRAMEDONE irq\n");
4025 return r;
4026 }
4027
4028 dispc_set_lcd_display_type(dssdev->manager->id,
4029 OMAP_DSS_LCD_DISPLAY_TFT);
4030
4031 dispc_set_parallel_interface_mode(dssdev->manager->id,
4032 OMAP_DSS_PARALLELMODE_DSI);
4033 dispc_enable_fifohandcheck(dssdev->manager->id, 1);
4034
4035 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
4036
4037 {
4038 struct omap_video_timings timings = { 4221 struct omap_video_timings timings = {
4039 .hsw = 1, 4222 .hsw = 1,
4040 .hfp = 1, 4223 .hfp = 1,
@@ -4044,21 +4227,46 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4044 .vbp = 0, 4227 .vbp = 0,
4045 }; 4228 };
4046 4229
4047 dispc_set_lcd_timings(dssdev->manager->id, &timings); 4230 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4231 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4232
4233 r = omap_dispc_register_isr(dsi_framedone_irq_callback,
4234 (void *) dssdev, irq);
4235 if (r) {
4236 DSSERR("can't get FRAMEDONE irq\n");
4237 return r;
4238 }
4239
4240 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
4241 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
4242
4243 dispc_mgr_set_lcd_timings(dssdev->manager->id, &timings);
4244 } else {
4245 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
4246 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
4247
4248 dispc_mgr_set_lcd_timings(dssdev->manager->id,
4249 &dssdev->panel.timings);
4048 } 4250 }
4049 4251
4252 dispc_mgr_set_lcd_display_type(dssdev->manager->id,
4253 OMAP_DSS_LCD_DISPLAY_TFT);
4254 dispc_mgr_set_tft_data_lines(dssdev->manager->id,
4255 dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
4050 return 0; 4256 return 0;
4051} 4257}
4052 4258
4053static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4259static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
4054{ 4260{
4055 u32 irq; 4261 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4262 u32 irq;
4056 4263
4057 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? 4264 irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
4058 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; 4265 DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
4059 4266
4060 omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev, 4267 omap_dispc_unregister_isr(dsi_framedone_irq_callback,
4061 irq); 4268 (void *) dssdev, irq);
4269 }
4062} 4270}
4063 4271
4064static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4272static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -4106,7 +4314,7 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4106 return r; 4314 return r;
4107 } 4315 }
4108 4316
4109 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 4317 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
4110 if (r) { 4318 if (r) {
4111 DSSERR("Failed to set dispc clocks\n"); 4319 DSSERR("Failed to set dispc clocks\n");
4112 return r; 4320 return r;
@@ -4166,10 +4374,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4166 4374
4167 return 0; 4375 return 0;
4168err3: 4376err3:
4169 dsi_cio_uninit(dsidev); 4377 dsi_cio_uninit(dssdev);
4170err2: 4378err2:
4171 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4379 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4172 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); 4380 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
4381 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
4382
4173err1: 4383err1:
4174 dsi_pll_uninit(dsidev, true); 4384 dsi_pll_uninit(dsidev, true);
4175err0: 4385err0:
@@ -4195,7 +4405,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4195 4405
4196 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 4406 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
4197 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); 4407 dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK);
4198 dsi_cio_uninit(dsidev); 4408 dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
4409 dsi_cio_uninit(dssdev);
4199 dsi_pll_uninit(dsidev, disconnect_lanes); 4410 dsi_pll_uninit(dsidev, disconnect_lanes);
4200} 4411}
4201 4412
@@ -4211,6 +4422,12 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4211 4422
4212 mutex_lock(&dsi->lock); 4423 mutex_lock(&dsi->lock);
4213 4424
4425 if (dssdev->manager == NULL) {
4426 DSSERR("failed to enable display: no manager\n");
4427 r = -ENODEV;
4428 goto err_start_dev;
4429 }
4430
4214 r = omap_dss_start_device(dssdev); 4431 r = omap_dss_start_device(dssdev);
4215 if (r) { 4432 if (r) {
4216 DSSERR("failed to start device\n"); 4433 DSSERR("failed to start device\n");
@@ -4307,9 +4524,10 @@ int dsi_init_display(struct omap_dss_device *dssdev)
4307 4524
4308 DSSDBG("DSI init\n"); 4525 DSSDBG("DSI init\n");
4309 4526
4310 /* XXX these should be figured out dynamically */ 4527 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
4311 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 4528 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
4312 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 4529 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
4530 }
4313 4531
4314 if (dsi->vdds_dsi_reg == NULL) { 4532 if (dsi->vdds_dsi_reg == NULL) {
4315 struct regulator *vdds_dsi; 4533 struct regulator *vdds_dsi;
@@ -4435,10 +4653,7 @@ static int dsi_get_clocks(struct platform_device *dsidev)
4435 4653
4436 dsi->dss_clk = clk; 4654 dsi->dss_clk = clk;
4437 4655
4438 if (cpu_is_omap34xx() || cpu_is_omap3630()) 4656 clk = clk_get(&dsidev->dev, "sys_clk");
4439 clk = clk_get(&dsidev->dev, "dss2_alwon_fck");
4440 else
4441 clk = clk_get(&dsidev->dev, "sys_clk");
4442 if (IS_ERR(clk)) { 4657 if (IS_ERR(clk)) {
4443 DSSERR("can't get sys_clk\n"); 4658 DSSERR("can't get sys_clk\n");
4444 clk_put(dsi->dss_clk); 4659 clk_put(dsi->dss_clk);
@@ -4462,7 +4677,7 @@ static void dsi_put_clocks(struct platform_device *dsidev)
4462} 4677}
4463 4678
4464/* DSI1 HW IP initialisation */ 4679/* DSI1 HW IP initialisation */
4465static int omap_dsi1hw_probe(struct platform_device *dsidev) 4680static int omap_dsihw_probe(struct platform_device *dsidev)
4466{ 4681{
4467 struct omap_display_platform_data *dss_plat_data; 4682 struct omap_display_platform_data *dss_plat_data;
4468 struct omap_dss_board_info *board_info; 4683 struct omap_dss_board_info *board_info;
@@ -4483,7 +4698,8 @@ static int omap_dsi1hw_probe(struct platform_device *dsidev)
4483 4698
4484 dss_plat_data = dsidev->dev.platform_data; 4699 dss_plat_data = dsidev->dev.platform_data;
4485 board_info = dss_plat_data->board_data; 4700 board_info = dss_plat_data->board_data;
4486 dsi->dsi_mux_pads = board_info->dsi_mux_pads; 4701 dsi->enable_pads = board_info->dsi_enable_pads;
4702 dsi->disable_pads = board_info->dsi_disable_pads;
4487 4703
4488 spin_lock_init(&dsi->irq_lock); 4704 spin_lock_init(&dsi->irq_lock);
4489 spin_lock_init(&dsi->errors_lock); 4705 spin_lock_init(&dsi->errors_lock);
@@ -4539,7 +4755,7 @@ static int omap_dsi1hw_probe(struct platform_device *dsidev)
4539 4755
4540 /* DSI VCs initialization */ 4756 /* DSI VCs initialization */
4541 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { 4757 for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
4542 dsi->vc[i].mode = DSI_VC_MODE_L4; 4758 dsi->vc[i].source = DSI_VC_SOURCE_L4;
4543 dsi->vc[i].dssdev = NULL; 4759 dsi->vc[i].dssdev = NULL;
4544 dsi->vc[i].vc_id = 0; 4760 dsi->vc[i].vc_id = 0;
4545 } 4761 }
@@ -4572,7 +4788,7 @@ err_alloc:
4572 return r; 4788 return r;
4573} 4789}
4574 4790
4575static int omap_dsi1hw_remove(struct platform_device *dsidev) 4791static int omap_dsihw_remove(struct platform_device *dsidev)
4576{ 4792{
4577 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4793 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4578 4794
@@ -4602,10 +4818,6 @@ static int omap_dsi1hw_remove(struct platform_device *dsidev)
4602 4818
4603static int dsi_runtime_suspend(struct device *dev) 4819static int dsi_runtime_suspend(struct device *dev)
4604{ 4820{
4605 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4606
4607 clk_disable(dsi->dss_clk);
4608
4609 dispc_runtime_put(); 4821 dispc_runtime_put();
4610 dss_runtime_put(); 4822 dss_runtime_put();
4611 4823
@@ -4614,7 +4826,6 @@ static int dsi_runtime_suspend(struct device *dev)
4614 4826
4615static int dsi_runtime_resume(struct device *dev) 4827static int dsi_runtime_resume(struct device *dev)
4616{ 4828{
4617 struct dsi_data *dsi = dsi_get_dsidrv_data(to_platform_device(dev));
4618 int r; 4829 int r;
4619 4830
4620 r = dss_runtime_get(); 4831 r = dss_runtime_get();
@@ -4625,8 +4836,6 @@ static int dsi_runtime_resume(struct device *dev)
4625 if (r) 4836 if (r)
4626 goto err_get_dispc; 4837 goto err_get_dispc;
4627 4838
4628 clk_enable(dsi->dss_clk);
4629
4630 return 0; 4839 return 0;
4631 4840
4632err_get_dispc: 4841err_get_dispc:
@@ -4640,11 +4849,11 @@ static const struct dev_pm_ops dsi_pm_ops = {
4640 .runtime_resume = dsi_runtime_resume, 4849 .runtime_resume = dsi_runtime_resume,
4641}; 4850};
4642 4851
4643static struct platform_driver omap_dsi1hw_driver = { 4852static struct platform_driver omap_dsihw_driver = {
4644 .probe = omap_dsi1hw_probe, 4853 .probe = omap_dsihw_probe,
4645 .remove = omap_dsi1hw_remove, 4854 .remove = omap_dsihw_remove,
4646 .driver = { 4855 .driver = {
4647 .name = "omapdss_dsi1", 4856 .name = "omapdss_dsi",
4648 .owner = THIS_MODULE, 4857 .owner = THIS_MODULE,
4649 .pm = &dsi_pm_ops, 4858 .pm = &dsi_pm_ops,
4650 }, 4859 },
@@ -4652,10 +4861,10 @@ static struct platform_driver omap_dsi1hw_driver = {
4652 4861
4653int dsi_init_platform_driver(void) 4862int dsi_init_platform_driver(void)
4654{ 4863{
4655 return platform_driver_register(&omap_dsi1hw_driver); 4864 return platform_driver_register(&omap_dsihw_driver);
4656} 4865}
4657 4866
4658void dsi_uninit_platform_driver(void) 4867void dsi_uninit_platform_driver(void)
4659{ 4868{
4660 return platform_driver_unregister(&omap_dsi1hw_driver); 4869 return platform_driver_unregister(&omap_dsihw_driver);
4661} 4870}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 0f9c3a6457a5..3e09726d32c7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -639,6 +639,17 @@ void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
639 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ 639 REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */
640} 640}
641 641
642enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
643{
644 enum omap_display_type displays;
645
646 displays = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
647 if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
648 return DSS_VENC_TV_CLK;
649
650 return REG_GET(DSS_CONTROL, 15, 15);
651}
652
642static int dss_get_clocks(void) 653static int dss_get_clocks(void)
643{ 654{
644 struct clk *clk; 655 struct clk *clk;
@@ -691,11 +702,6 @@ static void dss_put_clocks(void)
691 clk_put(dss.dss_clk); 702 clk_put(dss.dss_clk);
692} 703}
693 704
694struct clk *dss_get_ick(void)
695{
696 return clk_get(&dss.pdev->dev, "ick");
697}
698
699int dss_runtime_get(void) 705int dss_runtime_get(void)
700{ 706{
701 int r; 707 int r;
@@ -824,13 +830,11 @@ static int omap_dsshw_remove(struct platform_device *pdev)
824static int dss_runtime_suspend(struct device *dev) 830static int dss_runtime_suspend(struct device *dev)
825{ 831{
826 dss_save_context(); 832 dss_save_context();
827 clk_disable(dss.dss_clk);
828 return 0; 833 return 0;
829} 834}
830 835
831static int dss_runtime_resume(struct device *dev) 836static int dss_runtime_resume(struct device *dev)
832{ 837{
833 clk_enable(dss.dss_clk);
834 dss_restore_context(); 838 dss_restore_context();
835 return 0; 839 return 0;
836} 840}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 9c94b1152c20..6308fc59fc9e 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,10 +97,10 @@ extern unsigned int dss_debug;
97#define FLD_MOD(orig, val, start, end) \ 97#define FLD_MOD(orig, val, start, end) \
98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 98 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
99 99
100enum omap_parallel_interface_mode { 100enum dss_io_pad_mode {
101 OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */ 101 DSS_IO_PAD_MODE_RESET,
102 OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */ 102 DSS_IO_PAD_MODE_RFBI,
103 OMAP_DSS_PARALLELMODE_DSI, 103 DSS_IO_PAD_MODE_BYPASS,
104}; 104};
105 105
106enum dss_hdmi_venc_clk_source_select { 106enum dss_hdmi_venc_clk_source_select {
@@ -108,6 +108,11 @@ enum dss_hdmi_venc_clk_source_select {
108 DSS_HDMI_M_PCLK = 1, 108 DSS_HDMI_M_PCLK = 1,
109}; 109};
110 110
111enum dss_dsi_content_type {
112 DSS_DSI_CONTENT_DCS,
113 DSS_DSI_CONTENT_GENERIC,
114};
115
111struct dss_clock_info { 116struct dss_clock_info {
112 /* rates that we get with dividers below */ 117 /* rates that we get with dividers below */
113 unsigned long fck; 118 unsigned long fck;
@@ -150,16 +155,6 @@ struct dsi_clock_info {
150 bool use_sys_clk; 155 bool use_sys_clk;
151}; 156};
152 157
153/* HDMI PLL structure */
154struct hdmi_pll_info {
155 u16 regn;
156 u16 regm;
157 u32 regmf;
158 u16 regm2;
159 u16 regsd;
160 u16 dcofreq;
161};
162
163struct seq_file; 158struct seq_file;
164struct platform_device; 159struct platform_device;
165 160
@@ -209,9 +204,8 @@ void dss_uninit_platform_driver(void);
209int dss_runtime_get(void); 204int dss_runtime_get(void);
210void dss_runtime_put(void); 205void dss_runtime_put(void);
211 206
212struct clk *dss_get_ick(void);
213
214void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 207void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
208enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
215const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 209const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
216void dss_dump_clocks(struct seq_file *s); 210void dss_dump_clocks(struct seq_file *s);
217 211
@@ -279,6 +273,8 @@ void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir,
279 273
280int dsi_init_display(struct omap_dss_device *display); 274int dsi_init_display(struct omap_dss_device *display);
281void dsi_irq_handler(void); 275void dsi_irq_handler(void);
276u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
277
282unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 278unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
283int dsi_pll_set_clock_div(struct platform_device *dsidev, 279int dsi_pll_set_clock_div(struct platform_device *dsidev,
284 struct dsi_clock_info *cinfo); 280 struct dsi_clock_info *cinfo);
@@ -309,6 +305,11 @@ static inline int dsi_runtime_get(struct platform_device *dsidev)
309static inline void dsi_runtime_put(struct platform_device *dsidev) 305static inline void dsi_runtime_put(struct platform_device *dsidev)
310{ 306{
311} 307}
308static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
309{
310 WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
311 return 0;
312}
312static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) 313static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
313{ 314{
314 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__); 315 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
@@ -385,90 +386,71 @@ void dispc_disable_sidle(void);
385void dispc_lcd_enable_signal_polarity(bool act_high); 386void dispc_lcd_enable_signal_polarity(bool act_high);
386void dispc_lcd_enable_signal(bool enable); 387void dispc_lcd_enable_signal(bool enable);
387void dispc_pck_free_enable(bool enable); 388void dispc_pck_free_enable(bool enable);
388void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable);
389
390void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
391void dispc_set_digit_size(u16 width, u16 height); 389void dispc_set_digit_size(u16 width, u16 height);
392u32 dispc_get_plane_fifo_size(enum omap_plane plane);
393void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
394void dispc_enable_fifomerge(bool enable); 390void dispc_enable_fifomerge(bool enable);
395u32 dispc_get_burst_size(enum omap_plane plane);
396void dispc_enable_cpr(enum omap_channel channel, bool enable);
397void dispc_set_cpr_coef(enum omap_channel channel,
398 struct omap_dss_cpr_coefs *coefs);
399
400void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
401void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
402void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
403void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
404void dispc_set_channel_out(enum omap_plane plane,
405 enum omap_channel channel_out);
406
407void dispc_enable_gamma_table(bool enable); 391void dispc_enable_gamma_table(bool enable);
408int dispc_setup_plane(enum omap_plane plane,
409 u32 paddr, u16 screen_width,
410 u16 pos_x, u16 pos_y,
411 u16 width, u16 height,
412 u16 out_width, u16 out_height,
413 enum omap_color_mode color_mode,
414 bool ilace,
415 enum omap_dss_rotation_type rotation_type,
416 u8 rotation, bool mirror,
417 u8 global_alpha, u8 pre_mult_alpha,
418 enum omap_channel channel,
419 u32 puv_addr);
420
421bool dispc_go_busy(enum omap_channel channel);
422void dispc_go(enum omap_channel channel);
423void dispc_enable_channel(enum omap_channel channel, bool enable);
424bool dispc_is_channel_enabled(enum omap_channel channel);
425int dispc_enable_plane(enum omap_plane plane, bool enable);
426void dispc_enable_replication(enum omap_plane plane, bool enable);
427
428void dispc_set_parallel_interface_mode(enum omap_channel channel,
429 enum omap_parallel_interface_mode mode);
430void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
431void dispc_set_lcd_display_type(enum omap_channel channel,
432 enum omap_lcd_display_type type);
433void dispc_set_loadmode(enum omap_dss_load_mode mode); 392void dispc_set_loadmode(enum omap_dss_load_mode mode);
434 393
435void dispc_set_default_color(enum omap_channel channel, u32 color);
436u32 dispc_get_default_color(enum omap_channel channel);
437void dispc_set_trans_key(enum omap_channel ch,
438 enum omap_dss_trans_key_type type,
439 u32 trans_key);
440void dispc_get_trans_key(enum omap_channel ch,
441 enum omap_dss_trans_key_type *type,
442 u32 *trans_key);
443void dispc_enable_trans_key(enum omap_channel ch, bool enable);
444void dispc_enable_alpha_blending(enum omap_channel ch, bool enable);
445bool dispc_trans_key_enabled(enum omap_channel ch);
446bool dispc_alpha_blending_enabled(enum omap_channel ch);
447
448bool dispc_lcd_timings_ok(struct omap_video_timings *timings); 394bool dispc_lcd_timings_ok(struct omap_video_timings *timings);
449void dispc_set_lcd_timings(enum omap_channel channel,
450 struct omap_video_timings *timings);
451unsigned long dispc_fclk_rate(void); 395unsigned long dispc_fclk_rate(void);
452unsigned long dispc_lclk_rate(enum omap_channel channel);
453unsigned long dispc_pclk_rate(enum omap_channel channel);
454void dispc_set_pol_freq(enum omap_channel channel,
455 enum omap_panel_config config, u8 acbi, u8 acb);
456void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 396void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
457 struct dispc_clock_info *cinfo); 397 struct dispc_clock_info *cinfo);
458int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 398int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
459 struct dispc_clock_info *cinfo); 399 struct dispc_clock_info *cinfo);
460int dispc_set_clock_div(enum omap_channel channel, 400
401
402u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
403u32 dispc_ovl_get_burst_size(enum omap_plane plane);
404int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
405 bool ilace, enum omap_channel channel, bool replication,
406 u32 fifo_low, u32 fifo_high);
407int dispc_ovl_enable(enum omap_plane plane, bool enable);
408
409
410void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
411void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
412void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
413void dispc_mgr_set_cpr_coef(enum omap_channel channel,
414 struct omap_dss_cpr_coefs *coefs);
415bool dispc_mgr_go_busy(enum omap_channel channel);
416void dispc_mgr_go(enum omap_channel channel);
417void dispc_mgr_enable(enum omap_channel channel, bool enable);
418bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
419void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
420void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
421void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
422void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
423 enum omap_lcd_display_type type);
424void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
425u32 dispc_mgr_get_default_color(enum omap_channel channel);
426void dispc_mgr_set_trans_key(enum omap_channel ch,
427 enum omap_dss_trans_key_type type,
428 u32 trans_key);
429void dispc_mgr_get_trans_key(enum omap_channel ch,
430 enum omap_dss_trans_key_type *type,
431 u32 *trans_key);
432void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
433void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
434bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
435bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
436void dispc_mgr_set_lcd_timings(enum omap_channel channel,
437 struct omap_video_timings *timings);
438void dispc_mgr_set_pol_freq(enum omap_channel channel,
439 enum omap_panel_config config, u8 acbi, u8 acb);
440unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
441unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
442int dispc_mgr_set_clock_div(enum omap_channel channel,
461 struct dispc_clock_info *cinfo); 443 struct dispc_clock_info *cinfo);
462int dispc_get_clock_div(enum omap_channel channel, 444int dispc_mgr_get_clock_div(enum omap_channel channel,
463 struct dispc_clock_info *cinfo); 445 struct dispc_clock_info *cinfo);
464 446
465
466/* VENC */ 447/* VENC */
467#ifdef CONFIG_OMAP2_DSS_VENC 448#ifdef CONFIG_OMAP2_DSS_VENC
468int venc_init_platform_driver(void); 449int venc_init_platform_driver(void);
469void venc_uninit_platform_driver(void); 450void venc_uninit_platform_driver(void);
470void venc_dump_regs(struct seq_file *s); 451void venc_dump_regs(struct seq_file *s);
471int venc_init_display(struct omap_dss_device *display); 452int venc_init_display(struct omap_dss_device *display);
453unsigned long venc_get_pixel_clock(void);
472#else 454#else
473static inline int venc_init_platform_driver(void) 455static inline int venc_init_platform_driver(void)
474{ 456{
@@ -477,6 +459,11 @@ static inline int venc_init_platform_driver(void)
477static inline void venc_uninit_platform_driver(void) 459static inline void venc_uninit_platform_driver(void)
478{ 460{
479} 461}
462static inline unsigned long venc_get_pixel_clock(void)
463{
464 WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
465 return 0;
466}
480#endif 467#endif
481 468
482/* HDMI */ 469/* HDMI */
@@ -484,6 +471,8 @@ static inline void venc_uninit_platform_driver(void)
484int hdmi_init_platform_driver(void); 471int hdmi_init_platform_driver(void);
485void hdmi_uninit_platform_driver(void); 472void hdmi_uninit_platform_driver(void);
486int hdmi_init_display(struct omap_dss_device *dssdev); 473int hdmi_init_display(struct omap_dss_device *dssdev);
474unsigned long hdmi_get_pixel_clock(void);
475void hdmi_dump_regs(struct seq_file *s);
487#else 476#else
488static inline int hdmi_init_display(struct omap_dss_device *dssdev) 477static inline int hdmi_init_display(struct omap_dss_device *dssdev)
489{ 478{
@@ -496,12 +485,19 @@ static inline int hdmi_init_platform_driver(void)
496static inline void hdmi_uninit_platform_driver(void) 485static inline void hdmi_uninit_platform_driver(void)
497{ 486{
498} 487}
488static inline unsigned long hdmi_get_pixel_clock(void)
489{
490 WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
491 return 0;
492}
499#endif 493#endif
500int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); 494int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
501void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); 495void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
502void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); 496void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
503int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 497int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
504 struct omap_video_timings *timings); 498 struct omap_video_timings *timings);
499int omapdss_hdmi_read_edid(u8 *buf, int len);
500bool omapdss_hdmi_detect(void);
505int hdmi_panel_init(void); 501int hdmi_panel_init(void);
506void hdmi_panel_exit(void); 502void hdmi_panel_exit(void);
507 503
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index b415c4ee621d..b402699168a5 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
47 const int num_ovls; 47 const int num_ovls;
48 const enum omap_display_type *supported_displays; 48 const enum omap_display_type *supported_displays;
49 const enum omap_color_mode *supported_color_modes; 49 const enum omap_color_mode *supported_color_modes;
50 const enum omap_overlay_caps *overlay_caps;
50 const char * const *clksrc_names; 51 const char * const *clksrc_names;
51 const struct dss_param_range *dss_params; 52 const struct dss_param_range *dss_params;
52 53
@@ -209,6 +210,68 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
209 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | 210 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
210 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | 211 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
211 OMAP_DSS_COLOR_RGBX32, 212 OMAP_DSS_COLOR_RGBX32,
213
214 /* OMAP_DSS_VIDEO3 */
215 OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
216 OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
217 OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
218 OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
219 OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
220 OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
221 OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
222 OMAP_DSS_COLOR_RGBX32,
223};
224
225static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
226 /* OMAP_DSS_GFX */
227 0,
228
229 /* OMAP_DSS_VIDEO1 */
230 OMAP_DSS_OVL_CAP_SCALE,
231
232 /* OMAP_DSS_VIDEO2 */
233 OMAP_DSS_OVL_CAP_SCALE,
234};
235
236static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
237 /* OMAP_DSS_GFX */
238 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
239
240 /* OMAP_DSS_VIDEO1 */
241 OMAP_DSS_OVL_CAP_SCALE,
242
243 /* OMAP_DSS_VIDEO2 */
244 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
245};
246
247static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
248 /* OMAP_DSS_GFX */
249 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
250
251 /* OMAP_DSS_VIDEO1 */
252 OMAP_DSS_OVL_CAP_SCALE,
253
254 /* OMAP_DSS_VIDEO2 */
255 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
256 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
257};
258
259static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
260 /* OMAP_DSS_GFX */
261 OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
262 OMAP_DSS_OVL_CAP_ZORDER,
263
264 /* OMAP_DSS_VIDEO1 */
265 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
266 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
267
268 /* OMAP_DSS_VIDEO2 */
269 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
270 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
271
272 /* OMAP_DSS_VIDEO3 */
273 OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
274 OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
212}; 275};
213 276
214static const char * const omap2_dss_clk_source_names[] = { 277static const char * const omap2_dss_clk_source_names[] = {
@@ -233,32 +296,38 @@ static const char * const omap4_dss_clk_source_names[] = {
233 296
234static const struct dss_param_range omap2_dss_param_range[] = { 297static const struct dss_param_range omap2_dss_param_range[] = {
235 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 298 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
299 [FEAT_PARAM_DSS_PCD] = { 2, 255 },
236 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 }, 300 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
237 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 }, 301 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
238 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 }, 302 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
239 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 }, 303 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
240 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 }, 304 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
241 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 }, 305 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
306 [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
242}; 307};
243 308
244static const struct dss_param_range omap3_dss_param_range[] = { 309static const struct dss_param_range omap3_dss_param_range[] = {
245 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 310 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
311 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
246 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 }, 312 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
247 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 }, 313 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
248 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 }, 314 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
249 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 }, 315 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
250 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 }, 316 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
251 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 317 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
318 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
252}; 319};
253 320
254static const struct dss_param_range omap4_dss_param_range[] = { 321static const struct dss_param_range omap4_dss_param_range[] = {
255 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, 322 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
323 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
256 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, 324 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
257 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, 325 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
258 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, 326 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
259 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, 327 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
260 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, 328 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
261 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 329 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
330 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
262}; 331};
263 332
264/* OMAP2 DSS Features */ 333/* OMAP2 DSS Features */
@@ -275,6 +344,7 @@ static const struct omap_dss_features omap2_dss_features = {
275 .num_ovls = 3, 344 .num_ovls = 3,
276 .supported_displays = omap2_dss_supported_displays, 345 .supported_displays = omap2_dss_supported_displays,
277 .supported_color_modes = omap2_dss_supported_color_modes, 346 .supported_color_modes = omap2_dss_supported_color_modes,
347 .overlay_caps = omap2_dss_overlay_caps,
278 .clksrc_names = omap2_dss_clk_source_names, 348 .clksrc_names = omap2_dss_clk_source_names,
279 .dss_params = omap2_dss_param_range, 349 .dss_params = omap2_dss_param_range,
280 .buffer_size_unit = 1, 350 .buffer_size_unit = 1,
@@ -287,18 +357,19 @@ static const struct omap_dss_features omap3430_dss_features = {
287 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 357 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
288 358
289 .has_feature = 359 .has_feature =
290 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 360 FEAT_LCDENABLEPOL |
291 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 361 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
292 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | 362 FEAT_FUNCGATED | FEAT_ROWREPEATENABLE |
293 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | 363 FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF |
294 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | 364 FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC |
295 FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | 365 FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD |
296 FEAT_FIR_COEF_V, 366 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
297 367
298 .num_mgrs = 2, 368 .num_mgrs = 2,
299 .num_ovls = 3, 369 .num_ovls = 3,
300 .supported_displays = omap3430_dss_supported_displays, 370 .supported_displays = omap3430_dss_supported_displays,
301 .supported_color_modes = omap3_dss_supported_color_modes, 371 .supported_color_modes = omap3_dss_supported_color_modes,
372 .overlay_caps = omap3430_dss_overlay_caps,
302 .clksrc_names = omap3_dss_clk_source_names, 373 .clksrc_names = omap3_dss_clk_source_names,
303 .dss_params = omap3_dss_param_range, 374 .dss_params = omap3_dss_param_range,
304 .buffer_size_unit = 1, 375 .buffer_size_unit = 1,
@@ -310,18 +381,19 @@ static const struct omap_dss_features omap3630_dss_features = {
310 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), 381 .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
311 382
312 .has_feature = 383 .has_feature =
313 FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | 384 FEAT_LCDENABLEPOL |
314 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | 385 FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
315 FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | 386 FEAT_FUNCGATED |
316 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | 387 FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT |
317 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | 388 FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG |
318 FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | 389 FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD |
319 FEAT_FIR_COEF_V, 390 FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER,
320 391
321 .num_mgrs = 2, 392 .num_mgrs = 2,
322 .num_ovls = 3, 393 .num_ovls = 3,
323 .supported_displays = omap3630_dss_supported_displays, 394 .supported_displays = omap3630_dss_supported_displays,
324 .supported_color_modes = omap3_dss_supported_color_modes, 395 .supported_color_modes = omap3_dss_supported_color_modes,
396 .overlay_caps = omap3630_dss_overlay_caps,
325 .clksrc_names = omap3_dss_clk_source_names, 397 .clksrc_names = omap3_dss_clk_source_names,
326 .dss_params = omap3_dss_param_range, 398 .dss_params = omap3_dss_param_range,
327 .buffer_size_unit = 1, 399 .buffer_size_unit = 1,
@@ -335,17 +407,18 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
335 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 407 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
336 408
337 .has_feature = 409 .has_feature =
338 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 410 FEAT_MGR_LCD2 |
339 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
340 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 411 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
341 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 412 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
342 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | 413 FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 |
343 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V, 414 FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V |
415 FEAT_ALPHA_FREE_ZORDER,
344 416
345 .num_mgrs = 3, 417 .num_mgrs = 3,
346 .num_ovls = 3, 418 .num_ovls = 4,
347 .supported_displays = omap4_dss_supported_displays, 419 .supported_displays = omap4_dss_supported_displays,
348 .supported_color_modes = omap4_dss_supported_color_modes, 420 .supported_color_modes = omap4_dss_supported_color_modes,
421 .overlay_caps = omap4_dss_overlay_caps,
349 .clksrc_names = omap4_dss_clk_source_names, 422 .clksrc_names = omap4_dss_clk_source_names,
350 .dss_params = omap4_dss_param_range, 423 .dss_params = omap4_dss_param_range,
351 .buffer_size_unit = 16, 424 .buffer_size_unit = 16,
@@ -358,24 +431,50 @@ static const struct omap_dss_features omap4_dss_features = {
358 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), 431 .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields),
359 432
360 .has_feature = 433 .has_feature =
361 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 434 FEAT_MGR_LCD2 |
362 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
363 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 435 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
364 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | 436 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
365 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | 437 FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE |
366 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | 438 FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR |
367 FEAT_PRELOAD | FEAT_FIR_COEF_V, 439 FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER,
368 440
369 .num_mgrs = 3, 441 .num_mgrs = 3,
370 .num_ovls = 3, 442 .num_ovls = 4,
371 .supported_displays = omap4_dss_supported_displays, 443 .supported_displays = omap4_dss_supported_displays,
372 .supported_color_modes = omap4_dss_supported_color_modes, 444 .supported_color_modes = omap4_dss_supported_color_modes,
445 .overlay_caps = omap4_dss_overlay_caps,
373 .clksrc_names = omap4_dss_clk_source_names, 446 .clksrc_names = omap4_dss_clk_source_names,
374 .dss_params = omap4_dss_param_range, 447 .dss_params = omap4_dss_param_range,
375 .buffer_size_unit = 16, 448 .buffer_size_unit = 16,
376 .burst_size_unit = 16, 449 .burst_size_unit = 16,
377}; 450};
378 451
452#if defined(CONFIG_OMAP4_DSS_HDMI)
453/* HDMI OMAP4 Functions*/
454static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
455
456 .video_configure = ti_hdmi_4xxx_basic_configure,
457 .phy_enable = ti_hdmi_4xxx_phy_enable,
458 .phy_disable = ti_hdmi_4xxx_phy_disable,
459 .read_edid = ti_hdmi_4xxx_read_edid,
460 .detect = ti_hdmi_4xxx_detect,
461 .pll_enable = ti_hdmi_4xxx_pll_enable,
462 .pll_disable = ti_hdmi_4xxx_pll_disable,
463 .video_enable = ti_hdmi_4xxx_wp_video_start,
464 .dump_wrapper = ti_hdmi_4xxx_wp_dump,
465 .dump_core = ti_hdmi_4xxx_core_dump,
466 .dump_pll = ti_hdmi_4xxx_pll_dump,
467 .dump_phy = ti_hdmi_4xxx_phy_dump,
468
469};
470
471void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data)
472{
473 if (cpu_is_omap44xx())
474 ip_data->ops = &omap4_hdmi_functions;
475}
476#endif
477
379/* Functions returning values related to a DSS feature */ 478/* Functions returning values related to a DSS feature */
380int dss_feat_get_num_mgrs(void) 479int dss_feat_get_num_mgrs(void)
381{ 480{
@@ -407,6 +506,11 @@ enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
407 return omap_current_dss_features->supported_color_modes[plane]; 506 return omap_current_dss_features->supported_color_modes[plane];
408} 507}
409 508
509enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane)
510{
511 return omap_current_dss_features->overlay_caps[plane];
512}
513
410bool dss_feat_color_mode_supported(enum omap_plane plane, 514bool dss_feat_color_mode_supported(enum omap_plane plane,
411 enum omap_color_mode color_mode) 515 enum omap_color_mode color_mode)
412{ 516{
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b7398cbcda5f..6a6c05dd45ce 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -20,16 +20,17 @@
20#ifndef __OMAP2_DSS_FEATURES_H 20#ifndef __OMAP2_DSS_FEATURES_H
21#define __OMAP2_DSS_FEATURES_H 21#define __OMAP2_DSS_FEATURES_H
22 22
23#if defined(CONFIG_OMAP4_DSS_HDMI)
24#include "ti_hdmi.h"
25#endif
26
23#define MAX_DSS_MANAGERS 3 27#define MAX_DSS_MANAGERS 3
24#define MAX_DSS_OVERLAYS 3 28#define MAX_DSS_OVERLAYS 4
25#define MAX_DSS_LCD_MANAGERS 2 29#define MAX_DSS_LCD_MANAGERS 2
26#define MAX_NUM_DSI 2 30#define MAX_NUM_DSI 2
27 31
28/* DSS has feature id */ 32/* DSS has feature id */
29enum dss_feat_id { 33enum dss_feat_id {
30 FEAT_GLOBAL_ALPHA = 1 << 0,
31 FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
32 FEAT_PRE_MULT_ALPHA = 1 << 2,
33 FEAT_LCDENABLEPOL = 1 << 3, 34 FEAT_LCDENABLEPOL = 1 << 3,
34 FEAT_LCDENABLESIGNAL = 1 << 4, 35 FEAT_LCDENABLESIGNAL = 1 << 4,
35 FEAT_PCKFREEENABLE = 1 << 5, 36 FEAT_PCKFREEENABLE = 1 << 5,
@@ -55,6 +56,8 @@ enum dss_feat_id {
55 FEAT_CPR = 1 << 23, 56 FEAT_CPR = 1 << 23,
56 FEAT_PRELOAD = 1 << 24, 57 FEAT_PRELOAD = 1 << 24,
57 FEAT_FIR_COEF_V = 1 << 25, 58 FEAT_FIR_COEF_V = 1 << 25,
59 FEAT_ALPHA_FIXED_ZORDER = 1 << 26,
60 FEAT_ALPHA_FREE_ZORDER = 1 << 27,
58}; 61};
59 62
60/* DSS register field id */ 63/* DSS register field id */
@@ -75,12 +78,14 @@ enum dss_feat_reg_field {
75 78
76enum dss_range_param { 79enum dss_range_param {
77 FEAT_PARAM_DSS_FCK, 80 FEAT_PARAM_DSS_FCK,
81 FEAT_PARAM_DSS_PCD,
78 FEAT_PARAM_DSIPLL_REGN, 82 FEAT_PARAM_DSIPLL_REGN,
79 FEAT_PARAM_DSIPLL_REGM, 83 FEAT_PARAM_DSIPLL_REGM,
80 FEAT_PARAM_DSIPLL_REGM_DISPC, 84 FEAT_PARAM_DSIPLL_REGM_DISPC,
81 FEAT_PARAM_DSIPLL_REGM_DSI, 85 FEAT_PARAM_DSIPLL_REGM_DSI,
82 FEAT_PARAM_DSIPLL_FINT, 86 FEAT_PARAM_DSIPLL_FINT,
83 FEAT_PARAM_DSIPLL_LPDIV, 87 FEAT_PARAM_DSIPLL_LPDIV,
88 FEAT_PARAM_DOWNSCALE,
84}; 89};
85 90
86/* DSS Feature Functions */ 91/* DSS Feature Functions */
@@ -90,6 +95,7 @@ unsigned long dss_feat_get_param_min(enum dss_range_param param);
90unsigned long dss_feat_get_param_max(enum dss_range_param param); 95unsigned long dss_feat_get_param_max(enum dss_range_param param);
91enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); 96enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
92enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); 97enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
98enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
93bool dss_feat_color_mode_supported(enum omap_plane plane, 99bool dss_feat_color_mode_supported(enum omap_plane plane,
94 enum omap_color_mode color_mode); 100 enum omap_color_mode color_mode);
95const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); 101const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id);
@@ -100,4 +106,7 @@ u32 dss_feat_get_burst_size_unit(void); /* in bytes */
100bool dss_has_feature(enum dss_feat_id id); 106bool dss_has_feature(enum dss_feat_id id);
101void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); 107void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);
102void dss_features_init(void); 108void dss_features_init(void);
109#if defined(CONFIG_OMAP4_DSS_HDMI)
110void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data);
111#endif
103#endif 112#endif
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 256f27a9064a..3262f0f1fa35 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -37,26 +37,41 @@
37 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 37 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include "ti_hdmi_4xxx_ip.h"
40#endif 41#endif
41 42
43#include "ti_hdmi.h"
42#include "dss.h" 44#include "dss.h"
43#include "hdmi.h"
44#include "dss_features.h" 45#include "dss_features.h"
45 46
47#define HDMI_WP 0x0
48#define HDMI_CORE_SYS 0x400
49#define HDMI_CORE_AV 0x900
50#define HDMI_PLLCTRL 0x200
51#define HDMI_PHY 0x300
52
53/* HDMI EDID Length move this */
54#define HDMI_EDID_MAX_LENGTH 256
55#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
56#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
57#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
58#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
59#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
60
61#define OMAP_HDMI_TIMINGS_NB 34
62
63#define HDMI_DEFAULT_REGN 16
64#define HDMI_DEFAULT_REGM2 1
65
46static struct { 66static struct {
47 struct mutex lock; 67 struct mutex lock;
48 struct omap_display_platform_data *pdata; 68 struct omap_display_platform_data *pdata;
49 struct platform_device *pdev; 69 struct platform_device *pdev;
50 void __iomem *base_wp; /* HDMI wrapper */ 70 struct hdmi_ip_data ip_data;
51 int code; 71 int code;
52 int mode; 72 int mode;
53 u8 edid[HDMI_EDID_MAX_LENGTH];
54 u8 edid_set;
55 bool custom_set;
56 struct hdmi_config cfg;
57 73
58 struct clk *sys_clk; 74 struct clk *sys_clk;
59 struct clk *hdmi_clk;
60} hdmi; 75} hdmi;
61 76
62/* 77/*
@@ -144,30 +159,6 @@ static const int code_vesa[85] = {
144 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 159 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145 -1, 27, 28, -1, 33}; 160 -1, 27, 28, -1, 33};
146 161
147static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
148
149static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
150{
151 __raw_writel(val, hdmi.base_wp + idx.idx);
152}
153
154static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
155{
156 return __raw_readl(hdmi.base_wp + idx.idx);
157}
158
159static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
160 int b2, int b1, u32 val)
161{
162 u32 t = 0;
163 while (val != REG_GET(idx, b2, b1)) {
164 udelay(1);
165 if (t++ > 10000)
166 return !val;
167 }
168 return val;
169}
170
171static int hdmi_runtime_get(void) 162static int hdmi_runtime_get(void)
172{ 163{
173 int r; 164 int r;
@@ -193,304 +184,7 @@ int hdmi_init_display(struct omap_dss_device *dssdev)
193{ 184{
194 DSSDBG("init_display\n"); 185 DSSDBG("init_display\n");
195 186
196 return 0; 187 dss_init_hdmi_ip_ops(&hdmi.ip_data);
197}
198
199static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq,
200 struct hdmi_pll_info *fmt, u16 sd)
201{
202 u32 r;
203
204 /* PLL start always use manual mode */
205 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
206
207 r = hdmi_read_reg(PLLCTRL_CFG1);
208 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
209 r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */
210
211 hdmi_write_reg(PLLCTRL_CFG1, r);
212
213 r = hdmi_read_reg(PLLCTRL_CFG2);
214
215 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
216 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
217 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
218
219 if (dcofreq) {
220 /* divider programming for frequency beyond 1000Mhz */
221 REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
222 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
223 } else {
224 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
225 }
226
227 hdmi_write_reg(PLLCTRL_CFG2, r);
228
229 r = hdmi_read_reg(PLLCTRL_CFG4);
230 r = FLD_MOD(r, fmt->regm2, 24, 18);
231 r = FLD_MOD(r, fmt->regmf, 17, 0);
232
233 hdmi_write_reg(PLLCTRL_CFG4, r);
234
235 /* go now */
236 REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
237
238 /* wait for bit change */
239 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
240 DSSERR("PLL GO bit not set\n");
241 return -ETIMEDOUT;
242 }
243
244 /* Wait till the lock bit is set in PLL status */
245 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
246 DSSWARN("cannot lock PLL\n");
247 DSSWARN("CFG1 0x%x\n",
248 hdmi_read_reg(PLLCTRL_CFG1));
249 DSSWARN("CFG2 0x%x\n",
250 hdmi_read_reg(PLLCTRL_CFG2));
251 DSSWARN("CFG4 0x%x\n",
252 hdmi_read_reg(PLLCTRL_CFG4));
253 return -ETIMEDOUT;
254 }
255
256 DSSDBG("PLL locked!\n");
257
258 return 0;
259}
260
261/* PHY_PWR_CMD */
262static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val)
263{
264 /* Command for power control of HDMI PHY */
265 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
266
267 /* Status of the power control of HDMI PHY */
268 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
269 DSSERR("Failed to set PHY power mode to %d\n", val);
270 return -ETIMEDOUT;
271 }
272
273 return 0;
274}
275
276/* PLL_PWR_CMD */
277static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val)
278{
279 /* Command for power control of HDMI PLL */
280 REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
281
282 /* wait till PHY_PWR_STATUS is set */
283 if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
284 DSSERR("Failed to set PHY_PWR_STATUS\n");
285 return -ETIMEDOUT;
286 }
287
288 return 0;
289}
290
291static int hdmi_pll_reset(void)
292{
293 /* SYSRESET controlled by power FSM */
294 REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
295
296 /* READ 0x0 reset is in progress */
297 if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
298 DSSERR("Failed to sysreset PLL\n");
299 return -ETIMEDOUT;
300 }
301
302 return 0;
303}
304
305static int hdmi_phy_init(void)
306{
307 u16 r = 0;
308
309 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON);
310 if (r)
311 return r;
312
313 r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON);
314 if (r)
315 return r;
316
317 /*
318 * Read address 0 in order to get the SCP reset done completed
319 * Dummy access performed to make sure reset is done
320 */
321 hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
322
323 /*
324 * Write to phy address 0 to configure the clock
325 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
326 */
327 REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
328
329 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
330 hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
331
332 /* Setup max LDO voltage */
333 REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
334
335 /* Write to phy address 3 to change the polarity control */
336 REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
337
338 return 0;
339}
340
341static int hdmi_pll_program(struct hdmi_pll_info *fmt)
342{
343 u16 r = 0;
344 enum hdmi_clk_refsel refsel;
345
346 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
347 if (r)
348 return r;
349
350 r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
351 if (r)
352 return r;
353
354 r = hdmi_pll_reset();
355 if (r)
356 return r;
357
358 refsel = HDMI_REFSEL_SYSCLK;
359
360 r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
361 if (r)
362 return r;
363
364 return 0;
365}
366
367static void hdmi_phy_off(void)
368{
369 hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF);
370}
371
372static int hdmi_core_ddc_edid(u8 *pedid, int ext)
373{
374 u32 i, j;
375 char checksum = 0;
376 u32 offset = 0;
377
378 /* Turn on CLK for DDC */
379 REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
380
381 /*
382 * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
383 * right shifted values( The behavior is not consistent and seen only
384 * with some TV's)
385 */
386 usleep_range(800, 1000);
387
388 if (!ext) {
389 /* Clk SCL Devices */
390 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
391
392 /* HDMI_CORE_DDC_STATUS_IN_PROG */
393 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
394 4, 4, 0) != 0) {
395 DSSERR("Failed to program DDC\n");
396 return -ETIMEDOUT;
397 }
398
399 /* Clear FIFO */
400 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
401
402 /* HDMI_CORE_DDC_STATUS_IN_PROG */
403 if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
404 4, 4, 0) != 0) {
405 DSSERR("Failed to program DDC\n");
406 return -ETIMEDOUT;
407 }
408
409 } else {
410 if (ext % 2 != 0)
411 offset = 0x80;
412 }
413
414 /* Load Segment Address Register */
415 REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
416
417 /* Load Slave Address Register */
418 REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
419
420 /* Load Offset Address Register */
421 REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
422
423 /* Load Byte Count */
424 REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
425 REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
426
427 /* Set DDC_CMD */
428 if (ext)
429 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
430 else
431 REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
432
433 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
434 if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
435 DSSWARN("I2C Bus Low?\n");
436 return -EIO;
437 }
438 /* HDMI_CORE_DDC_STATUS_NO_ACK */
439 if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
440 DSSWARN("I2C No Ack\n");
441 return -EIO;
442 }
443
444 i = ext * 128;
445 j = 0;
446 while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
447 (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
448 j < 128) {
449
450 if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
451 /* FIFO not empty */
452 pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0);
453 j++;
454 }
455 }
456
457 for (j = 0; j < 128; j++)
458 checksum += pedid[j];
459
460 if (checksum != 0) {
461 DSSERR("E-EDID checksum failed!!\n");
462 return -EIO;
463 }
464
465 return 0;
466}
467
468static int read_edid(u8 *pedid, u16 max_length)
469{
470 int r = 0, n = 0, i = 0;
471 int max_ext_blocks = (max_length / 128) - 1;
472
473 r = hdmi_core_ddc_edid(pedid, 0);
474 if (r) {
475 return r;
476 } else {
477 n = pedid[0x7e];
478
479 /*
480 * README: need to comply with max_length set by the caller.
481 * Better implementation should be to allocate necessary
482 * memory to store EDID according to nb_block field found
483 * in first block
484 */
485 if (n > max_ext_blocks)
486 n = max_ext_blocks;
487
488 for (i = 1; i <= n; i++) {
489 r = hdmi_core_ddc_edid(pedid, i);
490 if (r)
491 return r;
492 }
493 }
494 return 0; 188 return 0;
495} 189}
496 190
@@ -518,7 +212,7 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
518{ 212{
519 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; 213 int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
520 int timing_vsync = 0, timing_hsync = 0; 214 int timing_vsync = 0, timing_hsync = 0;
521 struct omap_video_timings temp; 215 struct hdmi_video_timings temp;
522 struct hdmi_cm cm = {-1}; 216 struct hdmi_cm cm = {-1};
523 DSSDBG("hdmi_get_code\n"); 217 DSSDBG("hdmi_get_code\n");
524 218
@@ -556,500 +250,6 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
556 return cm; 250 return cm;
557} 251}
558 252
559static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
560 struct omap_video_timings *timings)
561{
562 /* X and Y resolution */
563 timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
564 edid[current_descriptor_addrs + 2]);
565 timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
566 edid[current_descriptor_addrs + 5]);
567
568 timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
569 edid[current_descriptor_addrs]);
570
571 timings->pixel_clock = 10 * timings->pixel_clock;
572
573 /* HORIZONTAL FRONT PORCH */
574 timings->hfp = edid[current_descriptor_addrs + 8] |
575 ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
576 /* HORIZONTAL SYNC WIDTH */
577 timings->hsw = edid[current_descriptor_addrs + 9] |
578 ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
579 /* HORIZONTAL BACK PORCH */
580 timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
581 edid[current_descriptor_addrs + 3]) -
582 (timings->hfp + timings->hsw);
583 /* VERTICAL FRONT PORCH */
584 timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
585 ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
586 /* VERTICAL SYNC WIDTH */
587 timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
588 ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
589 /* VERTICAL BACK PORCH */
590 timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
591 edid[current_descriptor_addrs + 6]) -
592 (timings->vfp + timings->vsw);
593
594}
595
596/* Description : This function gets the resolution information from EDID */
597static void get_edid_timing_data(u8 *edid)
598{
599 u8 count;
600 u16 current_descriptor_addrs;
601 struct hdmi_cm cm;
602 struct omap_video_timings edid_timings;
603
604 /* search block 0, there are 4 DTDs arranged in priority order */
605 for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
606 current_descriptor_addrs =
607 EDID_DESCRIPTOR_BLOCK0_ADDRESS +
608 count * EDID_TIMING_DESCRIPTOR_SIZE;
609 get_horz_vert_timing_info(current_descriptor_addrs,
610 edid, &edid_timings);
611 cm = hdmi_get_code(&edid_timings);
612 DSSDBG("Block0[%d] value matches code = %d , mode = %d\n",
613 count, cm.code, cm.mode);
614 if (cm.code == -1) {
615 continue;
616 } else {
617 hdmi.code = cm.code;
618 hdmi.mode = cm.mode;
619 DSSDBG("code = %d , mode = %d\n",
620 hdmi.code, hdmi.mode);
621 return;
622 }
623 }
624 if (edid[0x7e] != 0x00) {
625 for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
626 count++) {
627 current_descriptor_addrs =
628 EDID_DESCRIPTOR_BLOCK1_ADDRESS +
629 count * EDID_TIMING_DESCRIPTOR_SIZE;
630 get_horz_vert_timing_info(current_descriptor_addrs,
631 edid, &edid_timings);
632 cm = hdmi_get_code(&edid_timings);
633 DSSDBG("Block1[%d] value matches code = %d, mode = %d",
634 count, cm.code, cm.mode);
635 if (cm.code == -1) {
636 continue;
637 } else {
638 hdmi.code = cm.code;
639 hdmi.mode = cm.mode;
640 DSSDBG("code = %d , mode = %d\n",
641 hdmi.code, hdmi.mode);
642 return;
643 }
644 }
645 }
646
647 DSSINFO("no valid timing found , falling back to VGA\n");
648 hdmi.code = 4; /* setting default value of 640 480 VGA */
649 hdmi.mode = HDMI_DVI;
650}
651
652static void hdmi_read_edid(struct omap_video_timings *dp)
653{
654 int ret = 0, code;
655
656 memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH);
657
658 if (!hdmi.edid_set)
659 ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH);
660
661 if (!ret) {
662 if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) {
663 /* search for timings of default resolution */
664 get_edid_timing_data(hdmi.edid);
665 hdmi.edid_set = true;
666 }
667 } else {
668 DSSWARN("failed to read E-EDID\n");
669 }
670
671 if (!hdmi.edid_set) {
672 DSSINFO("fallback to VGA\n");
673 hdmi.code = 4; /* setting default value of 640 480 VGA */
674 hdmi.mode = HDMI_DVI;
675 }
676
677 code = get_timings_index();
678
679 *dp = cea_vesa_timings[code].timings;
680}
681
682static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
683 struct hdmi_core_infoframe_avi *avi_cfg,
684 struct hdmi_core_packet_enable_repeat *repeat_cfg)
685{
686 DSSDBG("Enter hdmi_core_init\n");
687
688 /* video core */
689 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
690 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
691 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
692 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
693 video_cfg->hdmi_dvi = HDMI_DVI;
694 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
695
696 /* info frame */
697 avi_cfg->db1_format = 0;
698 avi_cfg->db1_active_info = 0;
699 avi_cfg->db1_bar_info_dv = 0;
700 avi_cfg->db1_scan_info = 0;
701 avi_cfg->db2_colorimetry = 0;
702 avi_cfg->db2_aspect_ratio = 0;
703 avi_cfg->db2_active_fmt_ar = 0;
704 avi_cfg->db3_itc = 0;
705 avi_cfg->db3_ec = 0;
706 avi_cfg->db3_q_range = 0;
707 avi_cfg->db3_nup_scaling = 0;
708 avi_cfg->db4_videocode = 0;
709 avi_cfg->db5_pixel_repeat = 0;
710 avi_cfg->db6_7_line_eoftop = 0 ;
711 avi_cfg->db8_9_line_sofbottom = 0;
712 avi_cfg->db10_11_pixel_eofleft = 0;
713 avi_cfg->db12_13_pixel_sofright = 0;
714
715 /* packet enable and repeat */
716 repeat_cfg->audio_pkt = 0;
717 repeat_cfg->audio_pkt_repeat = 0;
718 repeat_cfg->avi_infoframe = 0;
719 repeat_cfg->avi_infoframe_repeat = 0;
720 repeat_cfg->gen_cntrl_pkt = 0;
721 repeat_cfg->gen_cntrl_pkt_repeat = 0;
722 repeat_cfg->generic_pkt = 0;
723 repeat_cfg->generic_pkt_repeat = 0;
724}
725
726static void hdmi_core_powerdown_disable(void)
727{
728 DSSDBG("Enter hdmi_core_powerdown_disable\n");
729 REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
730}
731
732static void hdmi_core_swreset_release(void)
733{
734 DSSDBG("Enter hdmi_core_swreset_release\n");
735 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
736}
737
738static void hdmi_core_swreset_assert(void)
739{
740 DSSDBG("Enter hdmi_core_swreset_assert\n");
741 REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
742}
743
744/* DSS_HDMI_CORE_VIDEO_CONFIG */
745static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
746{
747 u32 r = 0;
748
749 /* sys_ctrl1 default configuration not tunable */
750 r = hdmi_read_reg(HDMI_CORE_CTRL1);
751 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
752 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
753 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
754 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
755 hdmi_write_reg(HDMI_CORE_CTRL1, r);
756
757 REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
758
759 /* Vid_Mode */
760 r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
761
762 /* dither truncation configuration */
763 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
764 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
765 r = FLD_MOD(r, 1, 5, 5);
766 } else {
767 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
768 r = FLD_MOD(r, 0, 5, 5);
769 }
770 hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
771
772 /* HDMI_Ctrl */
773 r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
774 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
775 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
776 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
777 hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
778
779 /* TMDS_CTRL */
780 REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
781 cfg->tclk_sel_clkmult, 6, 5);
782}
783
784static void hdmi_core_aux_infoframe_avi_config(
785 struct hdmi_core_infoframe_avi info_avi)
786{
787 u32 val;
788 char sum = 0, checksum = 0;
789
790 sum += 0x82 + 0x002 + 0x00D;
791 hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
792 hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
793 hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
794
795 val = (info_avi.db1_format << 5) |
796 (info_avi.db1_active_info << 4) |
797 (info_avi.db1_bar_info_dv << 2) |
798 (info_avi.db1_scan_info);
799 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
800 sum += val;
801
802 val = (info_avi.db2_colorimetry << 6) |
803 (info_avi.db2_aspect_ratio << 4) |
804 (info_avi.db2_active_fmt_ar);
805 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
806 sum += val;
807
808 val = (info_avi.db3_itc << 7) |
809 (info_avi.db3_ec << 4) |
810 (info_avi.db3_q_range << 2) |
811 (info_avi.db3_nup_scaling);
812 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
813 sum += val;
814
815 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
816 sum += info_avi.db4_videocode;
817
818 val = info_avi.db5_pixel_repeat;
819 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
820 sum += val;
821
822 val = info_avi.db6_7_line_eoftop & 0x00FF;
823 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
824 sum += val;
825
826 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
827 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
828 sum += val;
829
830 val = info_avi.db8_9_line_sofbottom & 0x00FF;
831 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
832 sum += val;
833
834 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
835 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
836 sum += val;
837
838 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
839 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
840 sum += val;
841
842 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
843 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
844 sum += val;
845
846 val = info_avi.db12_13_pixel_sofright & 0x00FF;
847 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
848 sum += val;
849
850 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
851 hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
852 sum += val;
853
854 checksum = 0x100 - sum;
855 hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
856}
857
858static void hdmi_core_av_packet_config(
859 struct hdmi_core_packet_enable_repeat repeat_cfg)
860{
861 /* enable/repeat the infoframe */
862 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
863 (repeat_cfg.audio_pkt << 5) |
864 (repeat_cfg.audio_pkt_repeat << 4) |
865 (repeat_cfg.avi_infoframe << 1) |
866 (repeat_cfg.avi_infoframe_repeat));
867
868 /* enable/repeat the packet */
869 hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
870 (repeat_cfg.gen_cntrl_pkt << 3) |
871 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
872 (repeat_cfg.generic_pkt << 1) |
873 (repeat_cfg.generic_pkt_repeat));
874}
875
876static void hdmi_wp_init(struct omap_video_timings *timings,
877 struct hdmi_video_format *video_fmt,
878 struct hdmi_video_interface *video_int)
879{
880 DSSDBG("Enter hdmi_wp_init\n");
881
882 timings->hbp = 0;
883 timings->hfp = 0;
884 timings->hsw = 0;
885 timings->vbp = 0;
886 timings->vfp = 0;
887 timings->vsw = 0;
888
889 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
890 video_fmt->y_res = 0;
891 video_fmt->x_res = 0;
892
893 video_int->vsp = 0;
894 video_int->hsp = 0;
895
896 video_int->interlacing = 0;
897 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
898
899}
900
901static void hdmi_wp_video_start(bool start)
902{
903 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31);
904}
905
906static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
907 struct omap_video_timings *timings, struct hdmi_config *param)
908{
909 DSSDBG("Enter hdmi_wp_video_init_format\n");
910
911 video_fmt->y_res = param->timings.timings.y_res;
912 video_fmt->x_res = param->timings.timings.x_res;
913
914 timings->hbp = param->timings.timings.hbp;
915 timings->hfp = param->timings.timings.hfp;
916 timings->hsw = param->timings.timings.hsw;
917 timings->vbp = param->timings.timings.vbp;
918 timings->vfp = param->timings.timings.vfp;
919 timings->vsw = param->timings.timings.vsw;
920}
921
922static void hdmi_wp_video_config_format(
923 struct hdmi_video_format *video_fmt)
924{
925 u32 l = 0;
926
927 REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
928
929 l |= FLD_VAL(video_fmt->y_res, 31, 16);
930 l |= FLD_VAL(video_fmt->x_res, 15, 0);
931 hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
932}
933
934static void hdmi_wp_video_config_interface(
935 struct hdmi_video_interface *video_int)
936{
937 u32 r;
938 DSSDBG("Enter hdmi_wp_video_config_interface\n");
939
940 r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
941 r = FLD_MOD(r, video_int->vsp, 7, 7);
942 r = FLD_MOD(r, video_int->hsp, 6, 6);
943 r = FLD_MOD(r, video_int->interlacing, 3, 3);
944 r = FLD_MOD(r, video_int->tm, 1, 0);
945 hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
946}
947
948static void hdmi_wp_video_config_timing(
949 struct omap_video_timings *timings)
950{
951 u32 timing_h = 0;
952 u32 timing_v = 0;
953
954 DSSDBG("Enter hdmi_wp_video_config_timing\n");
955
956 timing_h |= FLD_VAL(timings->hbp, 31, 20);
957 timing_h |= FLD_VAL(timings->hfp, 19, 8);
958 timing_h |= FLD_VAL(timings->hsw, 7, 0);
959 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
960
961 timing_v |= FLD_VAL(timings->vbp, 31, 20);
962 timing_v |= FLD_VAL(timings->vfp, 19, 8);
963 timing_v |= FLD_VAL(timings->vsw, 7, 0);
964 hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
965}
966
967static void hdmi_basic_configure(struct hdmi_config *cfg)
968{
969 /* HDMI */
970 struct omap_video_timings video_timing;
971 struct hdmi_video_format video_format;
972 struct hdmi_video_interface video_interface;
973 /* HDMI core */
974 struct hdmi_core_infoframe_avi avi_cfg;
975 struct hdmi_core_video_config v_core_cfg;
976 struct hdmi_core_packet_enable_repeat repeat_cfg;
977
978 hdmi_wp_init(&video_timing, &video_format,
979 &video_interface);
980
981 hdmi_core_init(&v_core_cfg,
982 &avi_cfg,
983 &repeat_cfg);
984
985 hdmi_wp_video_init_format(&video_format,
986 &video_timing, cfg);
987
988 hdmi_wp_video_config_timing(&video_timing);
989
990 /* video config */
991 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
992
993 hdmi_wp_video_config_format(&video_format);
994
995 video_interface.vsp = cfg->timings.vsync_pol;
996 video_interface.hsp = cfg->timings.hsync_pol;
997 video_interface.interlacing = cfg->interlace;
998 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
999
1000 hdmi_wp_video_config_interface(&video_interface);
1001
1002 /*
1003 * configure core video part
1004 * set software reset in the core
1005 */
1006 hdmi_core_swreset_assert();
1007
1008 /* power down off */
1009 hdmi_core_powerdown_disable();
1010
1011 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
1012 v_core_cfg.hdmi_dvi = cfg->cm.mode;
1013
1014 hdmi_core_video_config(&v_core_cfg);
1015
1016 /* release software reset in the core */
1017 hdmi_core_swreset_release();
1018
1019 /*
1020 * configure packet
1021 * info frame video see doc CEA861-D page 65
1022 */
1023 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
1024 avi_cfg.db1_active_info =
1025 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
1026 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
1027 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
1028 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
1029 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
1030 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
1031 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
1032 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
1033 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
1034 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
1035 avi_cfg.db4_videocode = cfg->cm.code;
1036 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
1037 avi_cfg.db6_7_line_eoftop = 0;
1038 avi_cfg.db8_9_line_sofbottom = 0;
1039 avi_cfg.db10_11_pixel_eofleft = 0;
1040 avi_cfg.db12_13_pixel_sofright = 0;
1041
1042 hdmi_core_aux_infoframe_avi_config(avi_cfg);
1043
1044 /* enable/repeat the infoframe */
1045 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
1046 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
1047 /* wakeup */
1048 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
1049 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
1050 hdmi_core_av_packet_config(repeat_cfg);
1051}
1052
1053static void update_hdmi_timings(struct hdmi_config *cfg, 253static void update_hdmi_timings(struct hdmi_config *cfg,
1054 struct omap_video_timings *timings, int code) 254 struct omap_video_timings *timings, int code)
1055{ 255{
@@ -1066,6 +266,12 @@ static void update_hdmi_timings(struct hdmi_config *cfg,
1066 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; 266 cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol;
1067} 267}
1068 268
269unsigned long hdmi_get_pixel_clock(void)
270{
271 /* HDMI Pixel Clock in Mhz */
272 return hdmi.ip_data.cfg.timings.timings.pixel_clock * 10000;
273}
274
1069static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 275static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1070 struct hdmi_pll_info *pi) 276 struct hdmi_pll_info *pi)
1071{ 277{
@@ -1077,15 +283,23 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1077 * Input clock is predivided by N + 1 283 * Input clock is predivided by N + 1
1078 * out put of which is reference clk 284 * out put of which is reference clk
1079 */ 285 */
1080 pi->regn = dssdev->clocks.hdmi.regn; 286 if (dssdev->clocks.hdmi.regn == 0)
1081 refclk = clkin / (pi->regn + 1); 287 pi->regn = HDMI_DEFAULT_REGN;
288 else
289 pi->regn = dssdev->clocks.hdmi.regn;
290
291 refclk = clkin / pi->regn;
1082 292
1083 /* 293 /*
1084 * multiplier is pixel_clk/ref_clk 294 * multiplier is pixel_clk/ref_clk
1085 * Multiplying by 100 to avoid fractional part removal 295 * Multiplying by 100 to avoid fractional part removal
1086 */ 296 */
1087 pi->regm = (phy * 100 / (refclk)) / 100; 297 pi->regm = (phy * 100 / (refclk)) / 100;
1088 pi->regm2 = dssdev->clocks.hdmi.regm2; 298
299 if (dssdev->clocks.hdmi.regm2 == 0)
300 pi->regm2 = HDMI_DEFAULT_REGM2;
301 else
302 pi->regm2 = dssdev->clocks.hdmi.regm2;
1089 303
1090 /* 304 /*
1091 * fractional multiplier is remainder of the difference between 305 * fractional multiplier is remainder of the difference between
@@ -1100,7 +314,10 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1100 * is greater than 1000MHz 314 * is greater than 1000MHz
1101 */ 315 */
1102 pi->dcofreq = phy > 1000 * 100; 316 pi->dcofreq = phy > 1000 * 100;
1103 pi->regsd = ((pi->regm * clkin / 10) / ((pi->regn + 1) * 250) + 5) / 10; 317 pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
318
319 /* Set the reference clock to sysclk reference */
320 pi->refsel = HDMI_REFSEL_SYSCLK;
1104 321
1105 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); 322 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
1106 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 323 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
@@ -1109,7 +326,6 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
1109static int hdmi_power_on(struct omap_dss_device *dssdev) 326static int hdmi_power_on(struct omap_dss_device *dssdev)
1110{ 327{
1111 int r, code = 0; 328 int r, code = 0;
1112 struct hdmi_pll_info pll_data;
1113 struct omap_video_timings *p; 329 struct omap_video_timings *p;
1114 unsigned long phy; 330 unsigned long phy;
1115 331
@@ -1117,7 +333,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1117 if (r) 333 if (r)
1118 return r; 334 return r;
1119 335
1120 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); 336 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
1121 337
1122 p = &dssdev->panel.timings; 338 p = &dssdev->panel.timings;
1123 339
@@ -1125,36 +341,31 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1125 dssdev->panel.timings.x_res, 341 dssdev->panel.timings.x_res,
1126 dssdev->panel.timings.y_res); 342 dssdev->panel.timings.y_res);
1127 343
1128 if (!hdmi.custom_set) {
1129 DSSDBG("Read EDID as no EDID is not set on poweron\n");
1130 hdmi_read_edid(p);
1131 }
1132 code = get_timings_index(); 344 code = get_timings_index();
1133 dssdev->panel.timings = cea_vesa_timings[code].timings; 345 update_hdmi_timings(&hdmi.ip_data.cfg, p, code);
1134 update_hdmi_timings(&hdmi.cfg, p, code);
1135 346
1136 phy = p->pixel_clock; 347 phy = p->pixel_clock;
1137 348
1138 hdmi_compute_pll(dssdev, phy, &pll_data); 349 hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
1139 350
1140 hdmi_wp_video_start(0); 351 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
1141 352
1142 /* config the PLL and PHY first */ 353 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
1143 r = hdmi_pll_program(&pll_data); 354 r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
1144 if (r) { 355 if (r) {
1145 DSSDBG("Failed to lock PLL\n"); 356 DSSDBG("Failed to lock PLL\n");
1146 goto err; 357 goto err;
1147 } 358 }
1148 359
1149 r = hdmi_phy_init(); 360 r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
1150 if (r) { 361 if (r) {
1151 DSSDBG("Failed to start PHY\n"); 362 DSSDBG("Failed to start PHY\n");
1152 goto err; 363 goto err;
1153 } 364 }
1154 365
1155 hdmi.cfg.cm.mode = hdmi.mode; 366 hdmi.ip_data.cfg.cm.mode = hdmi.mode;
1156 hdmi.cfg.cm.code = hdmi.code; 367 hdmi.ip_data.cfg.cm.code = hdmi.code;
1157 hdmi_basic_configure(&hdmi.cfg); 368 hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
1158 369
1159 /* Make selection of HDMI in DSS */ 370 /* Make selection of HDMI in DSS */
1160 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 371 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
@@ -1174,9 +385,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
1174 dispc_set_digit_size(dssdev->panel.timings.x_res, 385 dispc_set_digit_size(dssdev->panel.timings.x_res,
1175 dssdev->panel.timings.y_res); 386 dssdev->panel.timings.y_res);
1176 387
1177 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1); 388 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
1178 389
1179 hdmi_wp_video_start(1); 390 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
1180 391
1181 return 0; 392 return 0;
1182err: 393err:
@@ -1186,14 +397,12 @@ err:
1186 397
1187static void hdmi_power_off(struct omap_dss_device *dssdev) 398static void hdmi_power_off(struct omap_dss_device *dssdev)
1188{ 399{
1189 dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); 400 dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
1190 401
1191 hdmi_wp_video_start(0); 402 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
1192 hdmi_phy_off(); 403 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
1193 hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); 404 hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
1194 hdmi_runtime_put(); 405 hdmi_runtime_put();
1195
1196 hdmi.edid_set = 0;
1197} 406}
1198 407
1199int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 408int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -1203,7 +412,6 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
1203 412
1204 cm = hdmi_get_code(timings); 413 cm = hdmi_get_code(timings);
1205 if (cm.code == -1) { 414 if (cm.code == -1) {
1206 DSSERR("Invalid timing entered\n");
1207 return -EINVAL; 415 return -EINVAL;
1208 } 416 }
1209 417
@@ -1215,12 +423,69 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
1215{ 423{
1216 struct hdmi_cm cm; 424 struct hdmi_cm cm;
1217 425
1218 hdmi.custom_set = 1;
1219 cm = hdmi_get_code(&dssdev->panel.timings); 426 cm = hdmi_get_code(&dssdev->panel.timings);
1220 hdmi.code = cm.code; 427 hdmi.code = cm.code;
1221 hdmi.mode = cm.mode; 428 hdmi.mode = cm.mode;
1222 omapdss_hdmi_display_enable(dssdev); 429
1223 hdmi.custom_set = 0; 430 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
431 int r;
432
433 hdmi_power_off(dssdev);
434
435 r = hdmi_power_on(dssdev);
436 if (r)
437 DSSERR("failed to power on device\n");
438 }
439}
440
441void hdmi_dump_regs(struct seq_file *s)
442{
443 mutex_lock(&hdmi.lock);
444
445 if (hdmi_runtime_get())
446 return;
447
448 hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s);
449 hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s);
450 hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s);
451 hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s);
452
453 hdmi_runtime_put();
454 mutex_unlock(&hdmi.lock);
455}
456
457int omapdss_hdmi_read_edid(u8 *buf, int len)
458{
459 int r;
460
461 mutex_lock(&hdmi.lock);
462
463 r = hdmi_runtime_get();
464 BUG_ON(r);
465
466 r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len);
467
468 hdmi_runtime_put();
469 mutex_unlock(&hdmi.lock);
470
471 return r;
472}
473
474bool omapdss_hdmi_detect(void)
475{
476 int r;
477
478 mutex_lock(&hdmi.lock);
479
480 r = hdmi_runtime_get();
481 BUG_ON(r);
482
483 r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
484
485 hdmi_runtime_put();
486 mutex_unlock(&hdmi.lock);
487
488 return r == 1;
1224} 489}
1225 490
1226int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 491int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
@@ -1231,6 +496,12 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
1231 496
1232 mutex_lock(&hdmi.lock); 497 mutex_lock(&hdmi.lock);
1233 498
499 if (dssdev->manager == NULL) {
500 DSSERR("failed to enable display: no manager\n");
501 r = -ENODEV;
502 goto err0;
503 }
504
1234 r = omap_dss_start_device(dssdev); 505 r = omap_dss_start_device(dssdev);
1235 if (r) { 506 if (r) {
1236 DSSERR("failed to start device\n"); 507 DSSERR("failed to start device\n");
@@ -1282,219 +553,9 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
1282 553
1283#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 554#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
1284 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 555 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 556
1432 checksum = 0x100 - sum; 557static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data,
1433 hdmi_write_reg(HDMI_CORE_AV_AUDIO_CHSUM, checksum); 558 struct snd_pcm_substream *substream,
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, 559 struct snd_pcm_hw_params *params,
1499 struct snd_soc_dai *dai) 560 struct snd_soc_dai *dai)
1500{ 561{
@@ -1548,7 +609,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1548 return -EINVAL; 609 return -EINVAL;
1549 } 610 }
1550 611
1551 err = hdmi_config_audio_acr(params_rate(params), &n, &cts); 612 err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts);
1552 if (err < 0) 613 if (err < 0)
1553 return err; 614 return err;
1554 615
@@ -1564,8 +625,8 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1564 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; 625 audio_dma.mode = HDMI_AUDIO_TRANSF_DMA;
1565 audio_dma.fifo_threshold = 0x20; /* in number of samples */ 626 audio_dma.fifo_threshold = 0x20; /* in number of samples */
1566 627
1567 hdmi_wp_audio_config_dma(&audio_dma); 628 hdmi_wp_audio_config_dma(ip_data, &audio_dma);
1568 hdmi_wp_audio_config_format(&audio_format); 629 hdmi_wp_audio_config_format(ip_data, &audio_format);
1569 630
1570 /* 631 /*
1571 * I2S config 632 * I2S config
@@ -1609,7 +670,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1609 /* Use parallel audio interface */ 670 /* Use parallel audio interface */
1610 core_cfg.en_parallel_aud_input = true; 671 core_cfg.en_parallel_aud_input = true;
1611 672
1612 hdmi_core_audio_config(&core_cfg); 673 hdmi_core_audio_config(ip_data, &core_cfg);
1613 674
1614 /* 675 /*
1615 * Configure packet 676 * Configure packet
@@ -1623,36 +684,10 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
1623 aud_if_cfg.db5_downmix_inh = false; 684 aud_if_cfg.db5_downmix_inh = false;
1624 aud_if_cfg.db5_lsv = 0; 685 aud_if_cfg.db5_lsv = 0;
1625 686
1626 hdmi_core_audio_infoframe_config(&aud_if_cfg); 687 hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg);
1627 return 0; 688 return 0;
1628} 689}
1629 690
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, 691static int hdmi_audio_startup(struct snd_pcm_substream *substream,
1657 struct snd_soc_dai *dai) 692 struct snd_soc_dai *dai)
1658{ 693{
@@ -1698,15 +733,6 @@ static int hdmi_get_clocks(struct platform_device *pdev)
1698 733
1699 hdmi.sys_clk = clk; 734 hdmi.sys_clk = clk;
1700 735
1701 clk = clk_get(&pdev->dev, "dss_48mhz_clk");
1702 if (IS_ERR(clk)) {
1703 DSSERR("can't get hdmi_clk\n");
1704 clk_put(hdmi.sys_clk);
1705 return PTR_ERR(clk);
1706 }
1707
1708 hdmi.hdmi_clk = clk;
1709
1710 return 0; 736 return 0;
1711} 737}
1712 738
@@ -1714,8 +740,6 @@ static void hdmi_put_clocks(void)
1714{ 740{
1715 if (hdmi.sys_clk) 741 if (hdmi.sys_clk)
1716 clk_put(hdmi.sys_clk); 742 clk_put(hdmi.sys_clk);
1717 if (hdmi.hdmi_clk)
1718 clk_put(hdmi.hdmi_clk);
1719} 743}
1720 744
1721/* HDMI HW IP initialisation */ 745/* HDMI HW IP initialisation */
@@ -1736,20 +760,26 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
1736 } 760 }
1737 761
1738 /* Base address taken from platform */ 762 /* Base address taken from platform */
1739 hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem)); 763 hdmi.ip_data.base_wp = ioremap(hdmi_mem->start,
1740 if (!hdmi.base_wp) { 764 resource_size(hdmi_mem));
765 if (!hdmi.ip_data.base_wp) {
1741 DSSERR("can't ioremap WP\n"); 766 DSSERR("can't ioremap WP\n");
1742 return -ENOMEM; 767 return -ENOMEM;
1743 } 768 }
1744 769
1745 r = hdmi_get_clocks(pdev); 770 r = hdmi_get_clocks(pdev);
1746 if (r) { 771 if (r) {
1747 iounmap(hdmi.base_wp); 772 iounmap(hdmi.ip_data.base_wp);
1748 return r; 773 return r;
1749 } 774 }
1750 775
1751 pm_runtime_enable(&pdev->dev); 776 pm_runtime_enable(&pdev->dev);
1752 777
778 hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS;
779 hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
780 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
781 hdmi.ip_data.phy_offset = HDMI_PHY;
782
1753 hdmi_panel_init(); 783 hdmi_panel_init();
1754 784
1755#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 785#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
@@ -1779,14 +809,13 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev)
1779 809
1780 hdmi_put_clocks(); 810 hdmi_put_clocks();
1781 811
1782 iounmap(hdmi.base_wp); 812 iounmap(hdmi.ip_data.base_wp);
1783 813
1784 return 0; 814 return 0;
1785} 815}
1786 816
1787static int hdmi_runtime_suspend(struct device *dev) 817static int hdmi_runtime_suspend(struct device *dev)
1788{ 818{
1789 clk_disable(hdmi.hdmi_clk);
1790 clk_disable(hdmi.sys_clk); 819 clk_disable(hdmi.sys_clk);
1791 820
1792 dispc_runtime_put(); 821 dispc_runtime_put();
@@ -1809,7 +838,6 @@ static int hdmi_runtime_resume(struct device *dev)
1809 838
1810 839
1811 clk_enable(hdmi.sys_clk); 840 clk_enable(hdmi.sys_clk);
1812 clk_enable(hdmi.hdmi_clk);
1813 841
1814 return 0; 842 return 0;
1815 843
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 7d4f2bd7c506..533d5dc634d2 100644
--- a/drivers/video/omap2/dss/hdmi_omap4_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * hdmi_omap4_panel.c 2 * hdmi_panel.c
3 * 3 *
4 * HDMI library support functions for TI OMAP4 processors. 4 * HDMI library support functions for TI OMAP4 processors.
5 * 5 *
@@ -25,6 +25,7 @@
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <video/omapdss.h> 27#include <video/omapdss.h>
28#include <linux/slab.h>
28 29
29#include "dss.h" 30#include "dss.h"
30 31
@@ -40,13 +41,7 @@ static int hdmi_panel_probe(struct omap_dss_device *dssdev)
40 dssdev->panel.config = OMAP_DSS_LCD_TFT | 41 dssdev->panel.config = OMAP_DSS_LCD_TFT |
41 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; 42 OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
42 43
43 /* 44 dssdev->panel.timings = (struct omap_video_timings){640, 480, 25175, 96, 16, 48, 2 , 11, 31};
44 * Initialize the timings to 640 * 480
45 * This is only for framebuffer update not for TV timing setting
46 * Setting TV timing will be done only on enable
47 */
48 dssdev->panel.timings.x_res = 640;
49 dssdev->panel.timings.y_res = 480;
50 45
51 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", 46 DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
52 dssdev->panel.timings.x_res, 47 dssdev->panel.timings.x_res,
@@ -161,12 +156,7 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
161 mutex_lock(&hdmi.hdmi_lock); 156 mutex_lock(&hdmi.hdmi_lock);
162 157
163 dssdev->panel.timings = *timings; 158 dssdev->panel.timings = *timings;
164 159 omapdss_hdmi_display_set_timing(dssdev);
165 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
166 /* turn the hdmi off and on to get new timings to use */
167 omapdss_hdmi_display_disable(dssdev);
168 omapdss_hdmi_display_set_timing(dssdev);
169 }
170 160
171 mutex_unlock(&hdmi.hdmi_lock); 161 mutex_unlock(&hdmi.hdmi_lock);
172} 162}
@@ -181,12 +171,54 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
181 mutex_lock(&hdmi.hdmi_lock); 171 mutex_lock(&hdmi.hdmi_lock);
182 172
183 r = omapdss_hdmi_display_check_timing(dssdev, timings); 173 r = omapdss_hdmi_display_check_timing(dssdev, timings);
184 if (r) { 174
185 DSSERR("Timing cannot be applied\n"); 175 mutex_unlock(&hdmi.hdmi_lock);
186 goto err; 176 return r;
177}
178
179static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
180{
181 int r;
182
183 mutex_lock(&hdmi.hdmi_lock);
184
185 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
186 r = omapdss_hdmi_display_enable(dssdev);
187 if (r)
188 goto err;
189 }
190
191 r = omapdss_hdmi_read_edid(buf, len);
192
193 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
194 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
195 omapdss_hdmi_display_disable(dssdev);
196err:
197 mutex_unlock(&hdmi.hdmi_lock);
198
199 return r;
200}
201
202static bool hdmi_detect(struct omap_dss_device *dssdev)
203{
204 int r;
205
206 mutex_lock(&hdmi.hdmi_lock);
207
208 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
209 r = omapdss_hdmi_display_enable(dssdev);
210 if (r)
211 goto err;
187 } 212 }
213
214 r = omapdss_hdmi_detect();
215
216 if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
217 dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
218 omapdss_hdmi_display_disable(dssdev);
188err: 219err:
189 mutex_unlock(&hdmi.hdmi_lock); 220 mutex_unlock(&hdmi.hdmi_lock);
221
190 return r; 222 return r;
191} 223}
192 224
@@ -200,6 +232,8 @@ static struct omap_dss_driver hdmi_driver = {
200 .get_timings = hdmi_get_timings, 232 .get_timings = hdmi_get_timings,
201 .set_timings = hdmi_set_timings, 233 .set_timings = hdmi_set_timings,
202 .check_timings = hdmi_check_timings, 234 .check_timings = hdmi_check_timings,
235 .read_edid = hdmi_read_edid,
236 .detect = hdmi_detect,
203 .driver = { 237 .driver = {
204 .name = "hdmi_panel", 238 .name = "hdmi_panel",
205 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 13d72d5c714b..6e63845cc7d7 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -106,7 +106,7 @@ put_device:
106static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, 106static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
107 char *buf) 107 char *buf)
108{ 108{
109 return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.default_color); 109 return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.default_color);
110} 110}
111 111
112static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, 112static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
@@ -116,8 +116,9 @@ static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
116 u32 color; 116 u32 color;
117 int r; 117 int r;
118 118
119 if (sscanf(buf, "%d", &color) != 1) 119 r = kstrtouint(buf, 0, &color);
120 return -EINVAL; 120 if (r)
121 return r;
121 122
122 mgr->get_manager_info(mgr, &info); 123 mgr->get_manager_info(mgr, &info);
123 124
@@ -184,7 +185,7 @@ static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
184static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, 185static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
185 char *buf) 186 char *buf)
186{ 187{
187 return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_key); 188 return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.trans_key);
188} 189}
189 190
190static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, 191static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
@@ -194,8 +195,9 @@ static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
194 u32 key_value; 195 u32 key_value;
195 int r; 196 int r;
196 197
197 if (sscanf(buf, "%d", &key_value) != 1) 198 r = kstrtouint(buf, 0, &key_value);
198 return -EINVAL; 199 if (r)
200 return r;
199 201
200 mgr->get_manager_info(mgr, &info); 202 mgr->get_manager_info(mgr, &info);
201 203
@@ -222,15 +224,16 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
222 const char *buf, size_t size) 224 const char *buf, size_t size)
223{ 225{
224 struct omap_overlay_manager_info info; 226 struct omap_overlay_manager_info info;
225 int enable; 227 bool enable;
226 int r; 228 int r;
227 229
228 if (sscanf(buf, "%d", &enable) != 1) 230 r = strtobool(buf, &enable);
229 return -EINVAL; 231 if (r)
232 return r;
230 233
231 mgr->get_manager_info(mgr, &info); 234 mgr->get_manager_info(mgr, &info);
232 235
233 info.trans_enabled = enable ? true : false; 236 info.trans_enabled = enable;
234 237
235 r = mgr->set_manager_info(mgr, &info); 238 r = mgr->set_manager_info(mgr, &info);
236 if (r) 239 if (r)
@@ -246,7 +249,10 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
246static ssize_t manager_alpha_blending_enabled_show( 249static ssize_t manager_alpha_blending_enabled_show(
247 struct omap_overlay_manager *mgr, char *buf) 250 struct omap_overlay_manager *mgr, char *buf)
248{ 251{
249 return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.alpha_enabled); 252 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
253
254 return snprintf(buf, PAGE_SIZE, "%d\n",
255 mgr->info.partial_alpha_enabled);
250} 256}
251 257
252static ssize_t manager_alpha_blending_enabled_store( 258static ssize_t manager_alpha_blending_enabled_store(
@@ -254,15 +260,18 @@ static ssize_t manager_alpha_blending_enabled_store(
254 const char *buf, size_t size) 260 const char *buf, size_t size)
255{ 261{
256 struct omap_overlay_manager_info info; 262 struct omap_overlay_manager_info info;
257 int enable; 263 bool enable;
258 int r; 264 int r;
259 265
260 if (sscanf(buf, "%d", &enable) != 1) 266 WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
261 return -EINVAL; 267
268 r = strtobool(buf, &enable);
269 if (r)
270 return r;
262 271
263 mgr->get_manager_info(mgr, &info); 272 mgr->get_manager_info(mgr, &info);
264 273
265 info.alpha_enabled = enable ? true : false; 274 info.partial_alpha_enabled = enable;
266 275
267 r = mgr->set_manager_info(mgr, &info); 276 r = mgr->set_manager_info(mgr, &info);
268 if (r) 277 if (r)
@@ -285,19 +294,16 @@ static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
285 const char *buf, size_t size) 294 const char *buf, size_t size)
286{ 295{
287 struct omap_overlay_manager_info info; 296 struct omap_overlay_manager_info info;
288 int v;
289 int r; 297 int r;
290 bool enable; 298 bool enable;
291 299
292 if (!dss_has_feature(FEAT_CPR)) 300 if (!dss_has_feature(FEAT_CPR))
293 return -ENODEV; 301 return -ENODEV;
294 302
295 r = kstrtoint(buf, 0, &v); 303 r = strtobool(buf, &enable);
296 if (r) 304 if (r)
297 return r; 305 return r;
298 306
299 enable = !!v;
300
301 mgr->get_manager_info(mgr, &info); 307 mgr->get_manager_info(mgr, &info);
302 308
303 if (info.cpr_enable == enable) 309 if (info.cpr_enable == enable)
@@ -586,6 +592,13 @@ static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
586 return -EINVAL; 592 return -EINVAL;
587 } 593 }
588 594
595 /*
596 * Don't allow currently enabled displays to have the overlay manager
597 * pulled out from underneath them
598 */
599 if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
600 return -EINVAL;
601
589 mgr->device->manager = NULL; 602 mgr->device->manager = NULL;
590 mgr->device = NULL; 603 mgr->device = NULL;
591 mgr->device_changed = true; 604 mgr->device_changed = true;
@@ -801,7 +814,7 @@ static int configure_overlay(enum omap_plane plane)
801{ 814{
802 struct overlay_cache_data *c; 815 struct overlay_cache_data *c;
803 struct manager_cache_data *mc; 816 struct manager_cache_data *mc;
804 struct omap_overlay_info *oi; 817 struct omap_overlay_info *oi, new_oi;
805 struct omap_overlay_manager_info *mi; 818 struct omap_overlay_manager_info *mi;
806 u16 outw, outh; 819 u16 outw, outh;
807 u16 x, y, w, h; 820 u16 x, y, w, h;
@@ -815,7 +828,7 @@ static int configure_overlay(enum omap_plane plane)
815 oi = &c->info; 828 oi = &c->info;
816 829
817 if (!c->enabled) { 830 if (!c->enabled) {
818 dispc_enable_plane(plane, 0); 831 dispc_ovl_enable(plane, 0);
819 return 0; 832 return 0;
820 } 833 }
821 834
@@ -843,7 +856,7 @@ static int configure_overlay(enum omap_plane plane)
843 /* If the overlay is outside the update region, disable it */ 856 /* If the overlay is outside the update region, disable it */
844 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h, 857 if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
845 x, y, outw, outh)) { 858 x, y, outw, outh)) {
846 dispc_enable_plane(plane, 0); 859 dispc_ovl_enable(plane, 0);
847 return 0; 860 return 0;
848 } 861 }
849 862
@@ -921,34 +934,27 @@ static int configure_overlay(enum omap_plane plane)
921 } 934 }
922 } 935 }
923 936
924 r = dispc_setup_plane(plane, 937 new_oi = *oi;
925 paddr, 938
926 oi->screen_width, 939 /* update new_oi members which could have been possibly updated */
927 x, y, 940 new_oi.pos_x = x;
928 w, h, 941 new_oi.pos_y = y;
929 outw, outh, 942 new_oi.width = w;
930 oi->color_mode, 943 new_oi.height = h;
931 c->ilace, 944 new_oi.out_width = outw;
932 oi->rotation_type, 945 new_oi.out_height = outh;
933 oi->rotation, 946 new_oi.paddr = paddr;
934 oi->mirror,
935 oi->global_alpha,
936 oi->pre_mult_alpha,
937 c->channel,
938 oi->p_uv_addr);
939 947
948 r = dispc_ovl_setup(plane, &new_oi, c->ilace, c->channel,
949 c->replication, c->fifo_low, c->fifo_high);
940 if (r) { 950 if (r) {
941 /* this shouldn't happen */ 951 /* this shouldn't happen */
942 DSSERR("dispc_setup_plane failed for ovl %d\n", plane); 952 DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
943 dispc_enable_plane(plane, 0); 953 dispc_ovl_enable(plane, 0);
944 return r; 954 return r;
945 } 955 }
946 956
947 dispc_enable_replication(plane, c->replication); 957 dispc_ovl_enable(plane, 1);
948
949 dispc_set_fifo_threshold(plane, c->fifo_low, c->fifo_high);
950
951 dispc_enable_plane(plane, 1);
952 958
953 return 0; 959 return 0;
954} 960}
@@ -962,13 +968,13 @@ static void configure_manager(enum omap_channel channel)
962 /* picking info from the cache */ 968 /* picking info from the cache */
963 mi = &dss_cache.manager_cache[channel].info; 969 mi = &dss_cache.manager_cache[channel].info;
964 970
965 dispc_set_default_color(channel, mi->default_color); 971 dispc_mgr_set_default_color(channel, mi->default_color);
966 dispc_set_trans_key(channel, mi->trans_key_type, mi->trans_key); 972 dispc_mgr_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
967 dispc_enable_trans_key(channel, mi->trans_enabled); 973 dispc_mgr_enable_trans_key(channel, mi->trans_enabled);
968 dispc_enable_alpha_blending(channel, mi->alpha_enabled); 974 dispc_mgr_enable_alpha_fixed_zorder(channel, mi->partial_alpha_enabled);
969 if (dss_has_feature(FEAT_CPR)) { 975 if (dss_has_feature(FEAT_CPR)) {
970 dispc_enable_cpr(channel, mi->cpr_enable); 976 dispc_mgr_enable_cpr(channel, mi->cpr_enable);
971 dispc_set_cpr_coef(channel, &mi->cpr_coefs); 977 dispc_mgr_set_cpr_coef(channel, &mi->cpr_coefs);
972 } 978 }
973} 979}
974 980
@@ -992,7 +998,7 @@ static int configure_dispc(void)
992 busy = false; 998 busy = false;
993 999
994 for (i = 0; i < num_mgrs; i++) { 1000 for (i = 0; i < num_mgrs; i++) {
995 mgr_busy[i] = dispc_go_busy(i); 1001 mgr_busy[i] = dispc_mgr_go_busy(i);
996 mgr_go[i] = false; 1002 mgr_go[i] = false;
997 } 1003 }
998 1004
@@ -1053,7 +1059,7 @@ static int configure_dispc(void)
1053 * always be turned off after frame, and new settings will be 1059 * always be turned off after frame, and new settings will be
1054 * taken in to use at next update */ 1060 * taken in to use at next update */
1055 if (!mc->manual_update) 1061 if (!mc->manual_update)
1056 dispc_go(i); 1062 dispc_mgr_go(i);
1057 } 1063 }
1058 1064
1059 if (busy) 1065 if (busy)
@@ -1258,7 +1264,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1258 u32 irq_mask; 1264 u32 irq_mask;
1259 1265
1260 for (i = 0; i < num_mgrs; i++) 1266 for (i = 0; i < num_mgrs; i++)
1261 mgr_busy[i] = dispc_go_busy(i); 1267 mgr_busy[i] = dispc_mgr_go_busy(i);
1262 1268
1263 spin_lock(&dss_cache.lock); 1269 spin_lock(&dss_cache.lock);
1264 1270
@@ -1280,7 +1286,7 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1280 1286
1281 /* re-read busy flags */ 1287 /* re-read busy flags */
1282 for (i = 0; i < num_mgrs; i++) 1288 for (i = 0; i < num_mgrs; i++)
1283 mgr_busy[i] = dispc_go_busy(i); 1289 mgr_busy[i] = dispc_mgr_go_busy(i);
1284 1290
1285 /* keep running as long as there are busy managers, so that 1291 /* keep running as long as there are busy managers, so that
1286 * we can collect overlay-applied information */ 1292 * we can collect overlay-applied information */
@@ -1326,11 +1332,13 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1326 1332
1327 ovl = omap_dss_get_overlay(i); 1333 ovl = omap_dss_get_overlay(i);
1328 1334
1329 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
1330 continue;
1331
1332 oc = &dss_cache.overlay_cache[ovl->id]; 1335 oc = &dss_cache.overlay_cache[ovl->id];
1333 1336
1337 if (ovl->manager_changed) {
1338 ovl->manager_changed = false;
1339 ovl->info_dirty = true;
1340 }
1341
1334 if (!overlay_enabled(ovl)) { 1342 if (!overlay_enabled(ovl)) {
1335 if (oc->enabled) { 1343 if (oc->enabled) {
1336 oc->enabled = false; 1344 oc->enabled = false;
@@ -1375,9 +1383,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1375 list_for_each_entry(mgr, &manager_list, list) { 1383 list_for_each_entry(mgr, &manager_list, list) {
1376 struct omap_dss_device *dssdev; 1384 struct omap_dss_device *dssdev;
1377 1385
1378 if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC))
1379 continue;
1380
1381 mc = &dss_cache.manager_cache[mgr->id]; 1386 mc = &dss_cache.manager_cache[mgr->id];
1382 1387
1383 if (mgr->device_changed) { 1388 if (mgr->device_changed) {
@@ -1423,9 +1428,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1423 1428
1424 ovl = omap_dss_get_overlay(i); 1429 ovl = omap_dss_get_overlay(i);
1425 1430
1426 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
1427 continue;
1428
1429 oc = &dss_cache.overlay_cache[ovl->id]; 1431 oc = &dss_cache.overlay_cache[ovl->id];
1430 1432
1431 if (!oc->enabled) 1433 if (!oc->enabled)
@@ -1433,11 +1435,11 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1433 1435
1434 dssdev = ovl->manager->device; 1436 dssdev = ovl->manager->device;
1435 1437
1436 size = dispc_get_plane_fifo_size(ovl->id); 1438 size = dispc_ovl_get_fifo_size(ovl->id);
1437 if (use_fifomerge) 1439 if (use_fifomerge)
1438 size *= 3; 1440 size *= 3;
1439 1441
1440 burst_size = dispc_get_burst_size(ovl->id); 1442 burst_size = dispc_ovl_get_burst_size(ovl->id);
1441 1443
1442 switch (dssdev->type) { 1444 switch (dssdev->type) {
1443 case OMAP_DISPLAY_TYPE_DPI: 1445 case OMAP_DISPLAY_TYPE_DPI:
@@ -1484,12 +1486,17 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1484 1486
1485static int dss_check_manager(struct omap_overlay_manager *mgr) 1487static int dss_check_manager(struct omap_overlay_manager *mgr)
1486{ 1488{
1487 /* OMAP supports only graphics source transparency color key and alpha 1489 if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
1488 * blending simultaneously. See TRM 15.4.2.4.2.2 Alpha Mode */ 1490 /*
1489 1491 * OMAP3 supports only graphics source transparency color key
1490 if (mgr->info.alpha_enabled && mgr->info.trans_enabled && 1492 * and alpha blending simultaneously. See TRM 15.4.2.4.2.2
1491 mgr->info.trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) 1493 * Alpha Mode
1492 return -EINVAL; 1494 */
1495 if (mgr->info.partial_alpha_enabled && mgr->info.trans_enabled
1496 && mgr->info.trans_key_type !=
1497 OMAP_DSS_COLOR_KEY_GFX_DST)
1498 return -EINVAL;
1499 }
1493 1500
1494 return 0; 1501 return 0;
1495} 1502}
@@ -1522,13 +1529,13 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
1522 1529
1523static int dss_mgr_enable(struct omap_overlay_manager *mgr) 1530static int dss_mgr_enable(struct omap_overlay_manager *mgr)
1524{ 1531{
1525 dispc_enable_channel(mgr->id, 1); 1532 dispc_mgr_enable(mgr->id, 1);
1526 return 0; 1533 return 0;
1527} 1534}
1528 1535
1529static int dss_mgr_disable(struct omap_overlay_manager *mgr) 1536static int dss_mgr_disable(struct omap_overlay_manager *mgr)
1530{ 1537{
1531 dispc_enable_channel(mgr->id, 0); 1538 dispc_mgr_enable(mgr->id, 0);
1532 return 0; 1539 return 0;
1533} 1540}
1534 1541
@@ -1580,7 +1587,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1580 mgr->enable = &dss_mgr_enable; 1587 mgr->enable = &dss_mgr_enable;
1581 mgr->disable = &dss_mgr_disable; 1588 mgr->disable = &dss_mgr_disable;
1582 1589
1583 mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; 1590 mgr->caps = 0;
1584 mgr->supported_displays = 1591 mgr->supported_displays =
1585 dss_feat_get_supported_displays(mgr->id); 1592 dss_feat_get_supported_displays(mgr->id);
1586 1593
@@ -1597,42 +1604,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1597 } 1604 }
1598 } 1605 }
1599 1606
1600#ifdef L4_EXAMPLE
1601 {
1602 int omap_dss_mgr_apply_l4(struct omap_overlay_manager *mgr)
1603 {
1604 DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name);
1605
1606 return 0;
1607 }
1608
1609 struct omap_overlay_manager *mgr;
1610 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
1611
1612 BUG_ON(mgr == NULL);
1613
1614 mgr->name = "l4";
1615 mgr->supported_displays =
1616 OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI;
1617
1618 mgr->set_device = &omap_dss_set_device;
1619 mgr->unset_device = &omap_dss_unset_device;
1620 mgr->apply = &omap_dss_mgr_apply_l4;
1621 mgr->set_manager_info = &omap_dss_mgr_set_info;
1622 mgr->get_manager_info = &omap_dss_mgr_get_info;
1623
1624 dss_overlay_setup_l4_manager(mgr);
1625
1626 omap_dss_add_overlay_manager(mgr);
1627
1628 r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
1629 &pdev->dev.kobj, "managerl4");
1630
1631 if (r)
1632 DSSERR("failed to create sysfs file\n");
1633 }
1634#endif
1635
1636 return 0; 1607 return 0;
1637} 1608}
1638 1609
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index c84380c53c39..ab8e40e48759 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -211,16 +211,17 @@ static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
211static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, 211static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
212 size_t size) 212 size_t size)
213{ 213{
214 int r, enable; 214 int r;
215 bool enable;
215 struct omap_overlay_info info; 216 struct omap_overlay_info info;
216 217
217 ovl->get_overlay_info(ovl, &info); 218 ovl->get_overlay_info(ovl, &info);
218 219
219 r = kstrtoint(buf, 0, &enable); 220 r = strtobool(buf, &enable);
220 if (r) 221 if (r)
221 return r; 222 return r;
222 223
223 info.enabled = !!enable; 224 info.enabled = enable;
224 225
225 r = ovl->set_overlay_info(ovl, &info); 226 r = ovl->set_overlay_info(ovl, &info);
226 if (r) 227 if (r)
@@ -248,7 +249,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
248 u8 alpha; 249 u8 alpha;
249 struct omap_overlay_info info; 250 struct omap_overlay_info info;
250 251
251 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 252 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
252 return -ENODEV; 253 return -ENODEV;
253 254
254 r = kstrtou8(buf, 0, &alpha); 255 r = kstrtou8(buf, 0, &alpha);
@@ -257,14 +258,7 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
257 258
258 ovl->get_overlay_info(ovl, &info); 259 ovl->get_overlay_info(ovl, &info);
259 260
260 /* Video1 plane does not support global alpha 261 info.global_alpha = alpha;
261 * to always make it 255 completely opaque
262 */
263 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
264 ovl->id == OMAP_DSS_VIDEO1)
265 info.global_alpha = 255;
266 else
267 info.global_alpha = alpha;
268 262
269 r = ovl->set_overlay_info(ovl, &info); 263 r = ovl->set_overlay_info(ovl, &info);
270 if (r) 264 if (r)
@@ -293,20 +287,52 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
293 u8 alpha; 287 u8 alpha;
294 struct omap_overlay_info info; 288 struct omap_overlay_info info;
295 289
290 if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
291 return -ENODEV;
292
296 r = kstrtou8(buf, 0, &alpha); 293 r = kstrtou8(buf, 0, &alpha);
297 if (r) 294 if (r)
298 return r; 295 return r;
299 296
300 ovl->get_overlay_info(ovl, &info); 297 ovl->get_overlay_info(ovl, &info);
301 298
302 /* only GFX and Video2 plane support pre alpha multiplied 299 info.pre_mult_alpha = alpha;
303 * set zero for Video1 plane 300
304 */ 301 r = ovl->set_overlay_info(ovl, &info);
305 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) && 302 if (r)
306 ovl->id == OMAP_DSS_VIDEO1) 303 return r;
307 info.pre_mult_alpha = 0; 304
308 else 305 if (ovl->manager) {
309 info.pre_mult_alpha = alpha; 306 r = ovl->manager->apply(ovl->manager);
307 if (r)
308 return r;
309 }
310
311 return size;
312}
313
314static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
315{
316 return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
317}
318
319static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
320 const char *buf, size_t size)
321{
322 int r;
323 u8 zorder;
324 struct omap_overlay_info info;
325
326 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
327 return -ENODEV;
328
329 r = kstrtou8(buf, 0, &zorder);
330 if (r)
331 return r;
332
333 ovl->get_overlay_info(ovl, &info);
334
335 info.zorder = zorder;
310 336
311 r = ovl->set_overlay_info(ovl, &info); 337 r = ovl->set_overlay_info(ovl, &info);
312 if (r) 338 if (r)
@@ -347,6 +373,8 @@ static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
347static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, 373static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
348 overlay_pre_mult_alpha_show, 374 overlay_pre_mult_alpha_show,
349 overlay_pre_mult_alpha_store); 375 overlay_pre_mult_alpha_store);
376static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
377 overlay_zorder_show, overlay_zorder_store);
350 378
351static struct attribute *overlay_sysfs_attrs[] = { 379static struct attribute *overlay_sysfs_attrs[] = {
352 &overlay_attr_name.attr, 380 &overlay_attr_name.attr,
@@ -358,6 +386,7 @@ static struct attribute *overlay_sysfs_attrs[] = {
358 &overlay_attr_enabled.attr, 386 &overlay_attr_enabled.attr,
359 &overlay_attr_global_alpha.attr, 387 &overlay_attr_global_alpha.attr,
360 &overlay_attr_pre_mult_alpha.attr, 388 &overlay_attr_pre_mult_alpha.attr,
389 &overlay_attr_zorder.attr,
361 NULL 390 NULL
362}; 391};
363 392
@@ -407,6 +436,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
407 struct omap_overlay_info *info; 436 struct omap_overlay_info *info;
408 u16 outw, outh; 437 u16 outw, outh;
409 u16 dw, dh; 438 u16 dw, dh;
439 int i;
410 440
411 if (!dssdev) 441 if (!dssdev)
412 return 0; 442 return 0;
@@ -462,6 +492,31 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
462 return -EINVAL; 492 return -EINVAL;
463 } 493 }
464 494
495 if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
496 if (info->zorder < 0 || info->zorder > 3) {
497 DSSERR("zorder out of range: %d\n",
498 info->zorder);
499 return -EINVAL;
500 }
501 /*
502 * Check that zorder doesn't match with zorder of any other
503 * overlay which is enabled and is also connected to the same
504 * manager
505 */
506 for (i = 0; i < omap_dss_get_num_overlays(); i++) {
507 struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
508
509 if (tmp_ovl->id != ovl->id &&
510 tmp_ovl->manager == ovl->manager &&
511 tmp_ovl->info.enabled == true &&
512 tmp_ovl->info.zorder == info->zorder) {
513 DSSERR("%s and %s have same zorder: %d\n",
514 ovl->name, tmp_ovl->name, info->zorder);
515 return -EINVAL;
516 }
517 }
518 }
519
465 return 0; 520 return 0;
466} 521}
467 522
@@ -516,6 +571,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
516 } 571 }
517 572
518 ovl->manager = mgr; 573 ovl->manager = mgr;
574 ovl->manager_changed = true;
519 575
520 /* XXX: When there is an overlay on a DSI manual update display, and 576 /* XXX: When there is an overlay on a DSI manual update display, and
521 * the overlay is first disabled, then moved to tv, and enabled, we 577 * the overlay is first disabled, then moved to tv, and enabled, we
@@ -529,15 +585,12 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
529 * Userspace workaround for this is to update the LCD after disabling 585 * Userspace workaround for this is to update the LCD after disabling
530 * the overlay, but before moving the overlay to TV. 586 * the overlay, but before moving the overlay to TV.
531 */ 587 */
532 dispc_set_channel_out(ovl->id, mgr->id);
533 588
534 return 0; 589 return 0;
535} 590}
536 591
537static int omap_dss_unset_manager(struct omap_overlay *ovl) 592static int omap_dss_unset_manager(struct omap_overlay *ovl)
538{ 593{
539 int r;
540
541 if (!ovl->manager) { 594 if (!ovl->manager) {
542 DSSERR("failed to detach overlay: manager not set\n"); 595 DSSERR("failed to detach overlay: manager not set\n");
543 return -EINVAL; 596 return -EINVAL;
@@ -548,11 +601,8 @@ static int omap_dss_unset_manager(struct omap_overlay *ovl)
548 return -EINVAL; 601 return -EINVAL;
549 } 602 }
550 603
551 r = ovl->wait_for_go(ovl);
552 if (r)
553 return r;
554
555 ovl->manager = NULL; 604 ovl->manager = NULL;
605 ovl->manager_changed = true;
556 606
557 return 0; 607 return 0;
558} 608}
@@ -618,22 +668,29 @@ void dss_init_overlays(struct platform_device *pdev)
618 case 0: 668 case 0:
619 ovl->name = "gfx"; 669 ovl->name = "gfx";
620 ovl->id = OMAP_DSS_GFX; 670 ovl->id = OMAP_DSS_GFX;
621 ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
622 ovl->info.global_alpha = 255; 671 ovl->info.global_alpha = 255;
672 ovl->info.zorder = 0;
623 break; 673 break;
624 case 1: 674 case 1:
625 ovl->name = "vid1"; 675 ovl->name = "vid1";
626 ovl->id = OMAP_DSS_VIDEO1; 676 ovl->id = OMAP_DSS_VIDEO1;
627 ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
628 OMAP_DSS_OVL_CAP_DISPC;
629 ovl->info.global_alpha = 255; 677 ovl->info.global_alpha = 255;
678 ovl->info.zorder =
679 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
630 break; 680 break;
631 case 2: 681 case 2:
632 ovl->name = "vid2"; 682 ovl->name = "vid2";
633 ovl->id = OMAP_DSS_VIDEO2; 683 ovl->id = OMAP_DSS_VIDEO2;
634 ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
635 OMAP_DSS_OVL_CAP_DISPC;
636 ovl->info.global_alpha = 255; 684 ovl->info.global_alpha = 255;
685 ovl->info.zorder =
686 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
687 break;
688 case 3:
689 ovl->name = "vid3";
690 ovl->id = OMAP_DSS_VIDEO3;
691 ovl->info.global_alpha = 255;
692 ovl->info.zorder =
693 dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
637 break; 694 break;
638 } 695 }
639 696
@@ -643,6 +700,7 @@ void dss_init_overlays(struct platform_device *pdev)
643 ovl->get_overlay_info = &dss_ovl_get_overlay_info; 700 ovl->get_overlay_info = &dss_ovl_get_overlay_info;
644 ovl->wait_for_go = &dss_ovl_wait_for_go; 701 ovl->wait_for_go = &dss_ovl_wait_for_go;
645 702
703 ovl->caps = dss_feat_get_overlay_caps(ovl->id);
646 ovl->supported_modes = 704 ovl->supported_modes =
647 dss_feat_get_supported_color_modes(ovl->id); 705 dss_feat_get_supported_color_modes(ovl->id);
648 706
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 39f4c597026a..1bd3703e42ff 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -309,9 +309,9 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
309 309
310 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 310 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
311 311
312 dispc_set_lcd_size(dssdev->manager->id, width, height); 312 dispc_mgr_set_lcd_size(dssdev->manager->id, width, height);
313 313
314 dispc_enable_channel(dssdev->manager->id, true); 314 dispc_mgr_enable(dssdev->manager->id, true);
315 315
316 rfbi.framedone_callback = callback; 316 rfbi.framedone_callback = callback;
317 rfbi.framedone_callback_data = data; 317 rfbi.framedone_callback_data = data;
@@ -783,10 +783,8 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
783 if (*w == 0 || *h == 0) 783 if (*w == 0 || *h == 0)
784 return -EINVAL; 784 return -EINVAL;
785 785
786 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 786 dss_setup_partial_planes(dssdev, x, y, w, h, true);
787 dss_setup_partial_planes(dssdev, x, y, w, h, true); 787 dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
788 dispc_set_lcd_size(dssdev->manager->id, *w, *h);
789 }
790 788
791 return 0; 789 return 0;
792} 790}
@@ -796,22 +794,7 @@ int omap_rfbi_update(struct omap_dss_device *dssdev,
796 u16 x, u16 y, u16 w, u16 h, 794 u16 x, u16 y, u16 w, u16 h,
797 void (*callback)(void *), void *data) 795 void (*callback)(void *), void *data)
798{ 796{
799 if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { 797 rfbi_transfer_area(dssdev, w, h, callback, data);
800 rfbi_transfer_area(dssdev, w, h, callback, data);
801 } else {
802 struct omap_overlay *ovl;
803 void __iomem *addr;
804 int scr_width;
805
806 ovl = dssdev->manager->overlays[0];
807 scr_width = ovl->info.screen_width;
808 addr = ovl->info.vaddr;
809
810 omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
811
812 callback(data);
813 }
814
815 return 0; 798 return 0;
816} 799}
817EXPORT_SYMBOL(omap_rfbi_update); 800EXPORT_SYMBOL(omap_rfbi_update);
@@ -860,6 +843,11 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
860{ 843{
861 int r; 844 int r;
862 845
846 if (dssdev->manager == NULL) {
847 DSSERR("failed to enable display: no manager\n");
848 return -ENODEV;
849 }
850
863 r = rfbi_runtime_get(); 851 r = rfbi_runtime_get();
864 if (r) 852 if (r)
865 return r; 853 return r;
@@ -877,13 +865,13 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
877 goto err1; 865 goto err1;
878 } 866 }
879 867
880 dispc_set_lcd_display_type(dssdev->manager->id, 868 dispc_mgr_set_lcd_display_type(dssdev->manager->id,
881 OMAP_DSS_LCD_DISPLAY_TFT); 869 OMAP_DSS_LCD_DISPLAY_TFT);
882 870
883 dispc_set_parallel_interface_mode(dssdev->manager->id, 871 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
884 OMAP_DSS_PARALLELMODE_RFBI); 872 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
885 873
886 dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size); 874 dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
887 875
888 rfbi_configure(dssdev->phy.rfbi.channel, 876 rfbi_configure(dssdev->phy.rfbi.channel,
889 dssdev->ctrl.pixel_size, 877 dssdev->ctrl.pixel_size,
@@ -952,10 +940,7 @@ static int omap_rfbihw_probe(struct platform_device *pdev)
952 940
953 msleep(10); 941 msleep(10);
954 942
955 if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap3630()) 943 clk = clk_get(&pdev->dev, "ick");
956 clk = dss_get_ick();
957 else
958 clk = clk_get(&pdev->dev, "ick");
959 if (IS_ERR(clk)) { 944 if (IS_ERR(clk)) {
960 DSSERR("can't get ick\n"); 945 DSSERR("can't get ick\n");
961 r = PTR_ERR(clk); 946 r = PTR_ERR(clk);
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3a688c871a45..695dc04cabba 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -35,13 +35,13 @@ static struct {
35static void sdi_basic_init(struct omap_dss_device *dssdev) 35static void sdi_basic_init(struct omap_dss_device *dssdev)
36 36
37{ 37{
38 dispc_set_parallel_interface_mode(dssdev->manager->id, 38 dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
39 OMAP_DSS_PARALLELMODE_BYPASS); 39 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
40 40
41 dispc_set_lcd_display_type(dssdev->manager->id, 41 dispc_mgr_set_lcd_display_type(dssdev->manager->id,
42 OMAP_DSS_LCD_DISPLAY_TFT); 42 OMAP_DSS_LCD_DISPLAY_TFT);
43 43
44 dispc_set_tft_data_lines(dssdev->manager->id, 24); 44 dispc_mgr_set_tft_data_lines(dssdev->manager->id, 24);
45 dispc_lcd_enable_signal_polarity(1); 45 dispc_lcd_enable_signal_polarity(1);
46} 46}
47 47
@@ -55,6 +55,11 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
55 unsigned long pck; 55 unsigned long pck;
56 int r; 56 int r;
57 57
58 if (dssdev->manager == NULL) {
59 DSSERR("failed to enable display: no manager\n");
60 return -ENODEV;
61 }
62
58 r = omap_dss_start_device(dssdev); 63 r = omap_dss_start_device(dssdev);
59 if (r) { 64 if (r) {
60 DSSERR("failed to start device\n"); 65 DSSERR("failed to start device\n");
@@ -78,7 +83,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
78 /* 15.5.9.1.2 */ 83 /* 15.5.9.1.2 */
79 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; 84 dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
80 85
81 dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, 86 dispc_mgr_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
82 dssdev->panel.acbi, dssdev->panel.acb); 87 dssdev->panel.acbi, dssdev->panel.acb);
83 88
84 r = dss_calc_clock_div(1, t->pixel_clock * 1000, 89 r = dss_calc_clock_div(1, t->pixel_clock * 1000,
@@ -101,13 +106,13 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
101 } 106 }
102 107
103 108
104 dispc_set_lcd_timings(dssdev->manager->id, t); 109 dispc_mgr_set_lcd_timings(dssdev->manager->id, t);
105 110
106 r = dss_set_clock_div(&dss_cinfo); 111 r = dss_set_clock_div(&dss_cinfo);
107 if (r) 112 if (r)
108 goto err_set_dss_clock_div; 113 goto err_set_dss_clock_div;
109 114
110 r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); 115 r = dispc_mgr_set_clock_div(dssdev->manager->id, &dispc_cinfo);
111 if (r) 116 if (r)
112 goto err_set_dispc_clock_div; 117 goto err_set_dispc_clock_div;
113 118
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
new file mode 100644
index 000000000000..2c3443dabb14
--- /dev/null
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -0,0 +1,138 @@
1/*
2 * ti_hdmi.h
3 *
4 * HDMI driver definition for TI OMAP4, DM81xx, DM38xx Processor.
5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
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 _TI_HDMI_H
22#define _TI_HDMI_H
23
24struct hdmi_ip_data;
25
26enum hdmi_pll_pwr {
27 HDMI_PLLPWRCMD_ALLOFF = 0,
28 HDMI_PLLPWRCMD_PLLONLY = 1,
29 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
30 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
31};
32
33enum hdmi_core_hdmi_dvi {
34 HDMI_DVI = 0,
35 HDMI_HDMI = 1
36};
37
38enum hdmi_clk_refsel {
39 HDMI_REFSEL_PCLK = 0,
40 HDMI_REFSEL_REF1 = 1,
41 HDMI_REFSEL_REF2 = 2,
42 HDMI_REFSEL_SYSCLK = 3
43};
44
45struct hdmi_video_timings {
46 u16 x_res;
47 u16 y_res;
48 /* Unit: KHz */
49 u32 pixel_clock;
50 u16 hsw;
51 u16 hfp;
52 u16 hbp;
53 u16 vsw;
54 u16 vfp;
55 u16 vbp;
56};
57
58/* HDMI timing structure */
59struct hdmi_timings {
60 struct hdmi_video_timings timings;
61 int vsync_pol;
62 int hsync_pol;
63};
64
65struct hdmi_cm {
66 int code;
67 int mode;
68};
69
70struct hdmi_config {
71 struct hdmi_timings timings;
72 u16 interlace;
73 struct hdmi_cm cm;
74};
75
76/* HDMI PLL structure */
77struct hdmi_pll_info {
78 u16 regn;
79 u16 regm;
80 u32 regmf;
81 u16 regm2;
82 u16 regsd;
83 u16 dcofreq;
84 enum hdmi_clk_refsel refsel;
85};
86
87struct ti_hdmi_ip_ops {
88
89 void (*video_configure)(struct hdmi_ip_data *ip_data);
90
91 int (*phy_enable)(struct hdmi_ip_data *ip_data);
92
93 void (*phy_disable)(struct hdmi_ip_data *ip_data);
94
95 int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
96
97 bool (*detect)(struct hdmi_ip_data *ip_data);
98
99 int (*pll_enable)(struct hdmi_ip_data *ip_data);
100
101 void (*pll_disable)(struct hdmi_ip_data *ip_data);
102
103 void (*video_enable)(struct hdmi_ip_data *ip_data, bool start);
104
105 void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s);
106
107 void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s);
108
109 void (*dump_pll)(struct hdmi_ip_data *ip_data, struct seq_file *s);
110
111 void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s);
112
113};
114
115struct hdmi_ip_data {
116 void __iomem *base_wp; /* HDMI wrapper */
117 unsigned long core_sys_offset;
118 unsigned long core_av_offset;
119 unsigned long pll_offset;
120 unsigned long phy_offset;
121 const struct ti_hdmi_ip_ops *ops;
122 struct hdmi_config cfg;
123 struct hdmi_pll_info pll_data;
124};
125int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
126void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
127int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
128bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
129void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
130int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
131void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
132void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data);
133void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
134void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
135void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
136void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
137
138#endif
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
new file mode 100644
index 000000000000..e1a6ce518af6
--- /dev/null
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -0,0 +1,1239 @@
1/*
2 * ti_hdmi_4xxx_ip.c
3 *
4 * HDMI TI81xx, TI38xx, TI OMAP4 etc IP driver Library
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
6 * Authors: Yong Zhi
7 * Mythri pk <mythripk@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/interrupt.h>
27#include <linux/mutex.h>
28#include <linux/delay.h>
29#include <linux/string.h>
30#include <linux/seq_file.h>
31
32#include "ti_hdmi_4xxx_ip.h"
33#include "dss.h"
34
35static inline void hdmi_write_reg(void __iomem *base_addr,
36 const u16 idx, u32 val)
37{
38 __raw_writel(val, base_addr + idx);
39}
40
41static inline u32 hdmi_read_reg(void __iomem *base_addr,
42 const u16 idx)
43{
44 return __raw_readl(base_addr + idx);
45}
46
47static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data)
48{
49 return ip_data->base_wp;
50}
51
52static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data)
53{
54 return ip_data->base_wp + ip_data->phy_offset;
55}
56
57static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data)
58{
59 return ip_data->base_wp + ip_data->pll_offset;
60}
61
62static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data)
63{
64 return ip_data->base_wp + ip_data->core_av_offset;
65}
66
67static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data)
68{
69 return ip_data->base_wp + ip_data->core_sys_offset;
70}
71
72static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
73 const u16 idx,
74 int b2, int b1, u32 val)
75{
76 u32 t = 0;
77 while (val != REG_GET(base_addr, idx, b2, b1)) {
78 udelay(1);
79 if (t++ > 10000)
80 return !val;
81 }
82 return val;
83}
84
85static int hdmi_pll_init(struct hdmi_ip_data *ip_data)
86{
87 u32 r;
88 void __iomem *pll_base = hdmi_pll_base(ip_data);
89 struct hdmi_pll_info *fmt = &ip_data->pll_data;
90
91 /* PLL start always use manual mode */
92 REG_FLD_MOD(pll_base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
93
94 r = hdmi_read_reg(pll_base, PLLCTRL_CFG1);
95 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
96 r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */
97
98 hdmi_write_reg(pll_base, PLLCTRL_CFG1, r);
99
100 r = hdmi_read_reg(pll_base, PLLCTRL_CFG2);
101
102 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
103 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
104 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
105 r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
106
107 if (fmt->dcofreq) {
108 /* divider programming for frequency beyond 1000Mhz */
109 REG_FLD_MOD(pll_base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
110 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
111 } else {
112 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
113 }
114
115 hdmi_write_reg(pll_base, PLLCTRL_CFG2, r);
116
117 r = hdmi_read_reg(pll_base, PLLCTRL_CFG4);
118 r = FLD_MOD(r, fmt->regm2, 24, 18);
119 r = FLD_MOD(r, fmt->regmf, 17, 0);
120
121 hdmi_write_reg(pll_base, PLLCTRL_CFG4, r);
122
123 /* go now */
124 REG_FLD_MOD(pll_base, PLLCTRL_PLL_GO, 0x1, 0, 0);
125
126 /* wait for bit change */
127 if (hdmi_wait_for_bit_change(pll_base, PLLCTRL_PLL_GO,
128 0, 0, 1) != 1) {
129 pr_err("PLL GO bit not set\n");
130 return -ETIMEDOUT;
131 }
132
133 /* Wait till the lock bit is set in PLL status */
134 if (hdmi_wait_for_bit_change(pll_base,
135 PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
136 pr_err("cannot lock PLL\n");
137 pr_err("CFG1 0x%x\n",
138 hdmi_read_reg(pll_base, PLLCTRL_CFG1));
139 pr_err("CFG2 0x%x\n",
140 hdmi_read_reg(pll_base, PLLCTRL_CFG2));
141 pr_err("CFG4 0x%x\n",
142 hdmi_read_reg(pll_base, PLLCTRL_CFG4));
143 return -ETIMEDOUT;
144 }
145
146 pr_debug("PLL locked!\n");
147
148 return 0;
149}
150
151/* PHY_PWR_CMD */
152static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val)
153{
154 /* Command for power control of HDMI PHY */
155 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6);
156
157 /* Status of the power control of HDMI PHY */
158 if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data),
159 HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
160 pr_err("Failed to set PHY power mode to %d\n", val);
161 return -ETIMEDOUT;
162 }
163
164 return 0;
165}
166
167/* PLL_PWR_CMD */
168static int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val)
169{
170 /* Command for power control of HDMI PLL */
171 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2);
172
173 /* wait till PHY_PWR_STATUS is set */
174 if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL,
175 1, 0, val) != val) {
176 pr_err("Failed to set PLL_PWR_STATUS\n");
177 return -ETIMEDOUT;
178 }
179
180 return 0;
181}
182
183static int hdmi_pll_reset(struct hdmi_ip_data *ip_data)
184{
185 /* SYSRESET controlled by power FSM */
186 REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
187
188 /* READ 0x0 reset is in progress */
189 if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data),
190 PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
191 pr_err("Failed to sysreset PLL\n");
192 return -ETIMEDOUT;
193 }
194
195 return 0;
196}
197
198int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data)
199{
200 u16 r = 0;
201
202 r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
203 if (r)
204 return r;
205
206 r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
207 if (r)
208 return r;
209
210 r = hdmi_pll_reset(ip_data);
211 if (r)
212 return r;
213
214 r = hdmi_pll_init(ip_data);
215 if (r)
216 return r;
217
218 return 0;
219}
220
221void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
222{
223 hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
224}
225
226int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
227{
228 u16 r = 0;
229 void __iomem *phy_base = hdmi_phy_base(ip_data);
230
231 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
232 if (r)
233 return r;
234
235 r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
236 if (r)
237 return r;
238
239 /*
240 * Read address 0 in order to get the SCP reset done completed
241 * Dummy access performed to make sure reset is done
242 */
243 hdmi_read_reg(phy_base, HDMI_TXPHY_TX_CTRL);
244
245 /*
246 * Write to phy address 0 to configure the clock
247 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
248 */
249 REG_FLD_MOD(phy_base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
250
251 /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
252 hdmi_write_reg(phy_base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
253
254 /* Setup max LDO voltage */
255 REG_FLD_MOD(phy_base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
256
257 /* Write to phy address 3 to change the polarity control */
258 REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
259
260 return 0;
261}
262
263void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
264{
265 hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
266}
267
268static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
269{
270 void __iomem *base = hdmi_core_sys_base(ip_data);
271
272 /* Turn on CLK for DDC */
273 REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
274
275 /* IN_PROG */
276 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) {
277 /* Abort transaction */
278 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
279 /* IN_PROG */
280 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
281 4, 4, 0) != 0) {
282 DSSERR("Timeout aborting DDC transaction\n");
283 return -ETIMEDOUT;
284 }
285 }
286
287 /* Clk SCL Devices */
288 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
289
290 /* HDMI_CORE_DDC_STATUS_IN_PROG */
291 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
292 4, 4, 0) != 0) {
293 DSSERR("Timeout starting SCL clock\n");
294 return -ETIMEDOUT;
295 }
296
297 /* Clear FIFO */
298 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
299
300 /* HDMI_CORE_DDC_STATUS_IN_PROG */
301 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
302 4, 4, 0) != 0) {
303 DSSERR("Timeout clearing DDC fifo\n");
304 return -ETIMEDOUT;
305 }
306
307 return 0;
308}
309
310static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
311 u8 *pedid, int ext)
312{
313 void __iomem *base = hdmi_core_sys_base(ip_data);
314 u32 i;
315 char checksum;
316 u32 offset = 0;
317
318 /* HDMI_CORE_DDC_STATUS_IN_PROG */
319 if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
320 4, 4, 0) != 0) {
321 DSSERR("Timeout waiting DDC to be ready\n");
322 return -ETIMEDOUT;
323 }
324
325 if (ext % 2 != 0)
326 offset = 0x80;
327
328 /* Load Segment Address Register */
329 REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0);
330
331 /* Load Slave Address Register */
332 REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
333
334 /* Load Offset Address Register */
335 REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
336
337 /* Load Byte Count */
338 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
339 REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
340
341 /* Set DDC_CMD */
342 if (ext)
343 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
344 else
345 REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
346
347 /* HDMI_CORE_DDC_STATUS_BUS_LOW */
348 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
349 pr_err("I2C Bus Low?\n");
350 return -EIO;
351 }
352 /* HDMI_CORE_DDC_STATUS_NO_ACK */
353 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
354 pr_err("I2C No Ack\n");
355 return -EIO;
356 }
357
358 for (i = 0; i < 0x80; ++i) {
359 int t;
360
361 /* IN_PROG */
362 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) {
363 DSSERR("operation stopped when reading edid\n");
364 return -EIO;
365 }
366
367 t = 0;
368 /* FIFO_EMPTY */
369 while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) {
370 if (t++ > 10000) {
371 DSSERR("timeout reading edid\n");
372 return -ETIMEDOUT;
373 }
374 udelay(1);
375 }
376
377 pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
378 }
379
380 checksum = 0;
381 for (i = 0; i < 0x80; ++i)
382 checksum += pedid[i];
383
384 if (checksum != 0) {
385 pr_err("E-EDID checksum failed!!\n");
386 return -EIO;
387 }
388
389 return 0;
390}
391
392int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
393 u8 *edid, int len)
394{
395 int r, l;
396
397 if (len < 128)
398 return -EINVAL;
399
400 r = hdmi_core_ddc_init(ip_data);
401 if (r)
402 return r;
403
404 r = hdmi_core_ddc_edid(ip_data, edid, 0);
405 if (r)
406 return r;
407
408 l = 128;
409
410 if (len >= 128 * 2 && edid[0x7e] > 0) {
411 r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1);
412 if (r)
413 return r;
414 l += 128;
415 }
416
417 return l;
418}
419
420bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
421{
422 int r;
423
424 void __iomem *base = hdmi_core_sys_base(ip_data);
425
426 /* HPD */
427 r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
428
429 return r == 1;
430}
431
432static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
433 struct hdmi_core_infoframe_avi *avi_cfg,
434 struct hdmi_core_packet_enable_repeat *repeat_cfg)
435{
436 pr_debug("Enter hdmi_core_init\n");
437
438 /* video core */
439 video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
440 video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
441 video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
442 video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
443 video_cfg->hdmi_dvi = HDMI_DVI;
444 video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
445
446 /* info frame */
447 avi_cfg->db1_format = 0;
448 avi_cfg->db1_active_info = 0;
449 avi_cfg->db1_bar_info_dv = 0;
450 avi_cfg->db1_scan_info = 0;
451 avi_cfg->db2_colorimetry = 0;
452 avi_cfg->db2_aspect_ratio = 0;
453 avi_cfg->db2_active_fmt_ar = 0;
454 avi_cfg->db3_itc = 0;
455 avi_cfg->db3_ec = 0;
456 avi_cfg->db3_q_range = 0;
457 avi_cfg->db3_nup_scaling = 0;
458 avi_cfg->db4_videocode = 0;
459 avi_cfg->db5_pixel_repeat = 0;
460 avi_cfg->db6_7_line_eoftop = 0 ;
461 avi_cfg->db8_9_line_sofbottom = 0;
462 avi_cfg->db10_11_pixel_eofleft = 0;
463 avi_cfg->db12_13_pixel_sofright = 0;
464
465 /* packet enable and repeat */
466 repeat_cfg->audio_pkt = 0;
467 repeat_cfg->audio_pkt_repeat = 0;
468 repeat_cfg->avi_infoframe = 0;
469 repeat_cfg->avi_infoframe_repeat = 0;
470 repeat_cfg->gen_cntrl_pkt = 0;
471 repeat_cfg->gen_cntrl_pkt_repeat = 0;
472 repeat_cfg->generic_pkt = 0;
473 repeat_cfg->generic_pkt_repeat = 0;
474}
475
476static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data)
477{
478 pr_debug("Enter hdmi_core_powerdown_disable\n");
479 REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0);
480}
481
482static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data)
483{
484 pr_debug("Enter hdmi_core_swreset_release\n");
485 REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0);
486}
487
488static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data)
489{
490 pr_debug("Enter hdmi_core_swreset_assert\n");
491 REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0);
492}
493
494/* HDMI_CORE_VIDEO_CONFIG */
495static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,
496 struct hdmi_core_video_config *cfg)
497{
498 u32 r = 0;
499 void __iomem *core_sys_base = hdmi_core_sys_base(ip_data);
500
501 /* sys_ctrl1 default configuration not tunable */
502 r = hdmi_read_reg(core_sys_base, HDMI_CORE_CTRL1);
503 r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
504 r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
505 r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
506 r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
507 hdmi_write_reg(core_sys_base, HDMI_CORE_CTRL1, r);
508
509 REG_FLD_MOD(core_sys_base,
510 HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
511
512 /* Vid_Mode */
513 r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE);
514
515 /* dither truncation configuration */
516 if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
517 r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
518 r = FLD_MOD(r, 1, 5, 5);
519 } else {
520 r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
521 r = FLD_MOD(r, 0, 5, 5);
522 }
523 hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r);
524
525 /* HDMI_Ctrl */
526 r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL);
527 r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
528 r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
529 r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
530 hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r);
531
532 /* TMDS_CTRL */
533 REG_FLD_MOD(core_sys_base,
534 HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
535}
536
537static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data,
538 struct hdmi_core_infoframe_avi info_avi)
539{
540 u32 val;
541 char sum = 0, checksum = 0;
542 void __iomem *av_base = hdmi_av_base(ip_data);
543
544 sum += 0x82 + 0x002 + 0x00D;
545 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
546 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
547 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
548
549 val = (info_avi.db1_format << 5) |
550 (info_avi.db1_active_info << 4) |
551 (info_avi.db1_bar_info_dv << 2) |
552 (info_avi.db1_scan_info);
553 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
554 sum += val;
555
556 val = (info_avi.db2_colorimetry << 6) |
557 (info_avi.db2_aspect_ratio << 4) |
558 (info_avi.db2_active_fmt_ar);
559 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
560 sum += val;
561
562 val = (info_avi.db3_itc << 7) |
563 (info_avi.db3_ec << 4) |
564 (info_avi.db3_q_range << 2) |
565 (info_avi.db3_nup_scaling);
566 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
567 sum += val;
568
569 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
570 info_avi.db4_videocode);
571 sum += info_avi.db4_videocode;
572
573 val = info_avi.db5_pixel_repeat;
574 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
575 sum += val;
576
577 val = info_avi.db6_7_line_eoftop & 0x00FF;
578 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
579 sum += val;
580
581 val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
582 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
583 sum += val;
584
585 val = info_avi.db8_9_line_sofbottom & 0x00FF;
586 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
587 sum += val;
588
589 val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
590 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
591 sum += val;
592
593 val = info_avi.db10_11_pixel_eofleft & 0x00FF;
594 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
595 sum += val;
596
597 val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
598 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
599 sum += val;
600
601 val = info_avi.db12_13_pixel_sofright & 0x00FF;
602 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
603 sum += val;
604
605 val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
606 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
607 sum += val;
608
609 checksum = 0x100 - sum;
610 hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);
611}
612
613static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data,
614 struct hdmi_core_packet_enable_repeat repeat_cfg)
615{
616 /* enable/repeat the infoframe */
617 hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1,
618 (repeat_cfg.audio_pkt << 5) |
619 (repeat_cfg.audio_pkt_repeat << 4) |
620 (repeat_cfg.avi_infoframe << 1) |
621 (repeat_cfg.avi_infoframe_repeat));
622
623 /* enable/repeat the packet */
624 hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2,
625 (repeat_cfg.gen_cntrl_pkt << 3) |
626 (repeat_cfg.gen_cntrl_pkt_repeat << 2) |
627 (repeat_cfg.generic_pkt << 1) |
628 (repeat_cfg.generic_pkt_repeat));
629}
630
631static void hdmi_wp_init(struct omap_video_timings *timings,
632 struct hdmi_video_format *video_fmt,
633 struct hdmi_video_interface *video_int)
634{
635 pr_debug("Enter hdmi_wp_init\n");
636
637 timings->hbp = 0;
638 timings->hfp = 0;
639 timings->hsw = 0;
640 timings->vbp = 0;
641 timings->vfp = 0;
642 timings->vsw = 0;
643
644 video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
645 video_fmt->y_res = 0;
646 video_fmt->x_res = 0;
647
648 video_int->vsp = 0;
649 video_int->hsp = 0;
650
651 video_int->interlacing = 0;
652 video_int->tm = 0; /* HDMI_TIMING_SLAVE */
653
654}
655
656void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start)
657{
658 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, start, 31, 31);
659}
660
661static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
662 struct omap_video_timings *timings, struct hdmi_config *param)
663{
664 pr_debug("Enter hdmi_wp_video_init_format\n");
665
666 video_fmt->y_res = param->timings.timings.y_res;
667 video_fmt->x_res = param->timings.timings.x_res;
668
669 timings->hbp = param->timings.timings.hbp;
670 timings->hfp = param->timings.timings.hfp;
671 timings->hsw = param->timings.timings.hsw;
672 timings->vbp = param->timings.timings.vbp;
673 timings->vfp = param->timings.timings.vfp;
674 timings->vsw = param->timings.timings.vsw;
675}
676
677static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data,
678 struct hdmi_video_format *video_fmt)
679{
680 u32 l = 0;
681
682 REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG,
683 video_fmt->packing_mode, 10, 8);
684
685 l |= FLD_VAL(video_fmt->y_res, 31, 16);
686 l |= FLD_VAL(video_fmt->x_res, 15, 0);
687 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l);
688}
689
690static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data,
691 struct hdmi_video_interface *video_int)
692{
693 u32 r;
694 pr_debug("Enter hdmi_wp_video_config_interface\n");
695
696 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG);
697 r = FLD_MOD(r, video_int->vsp, 7, 7);
698 r = FLD_MOD(r, video_int->hsp, 6, 6);
699 r = FLD_MOD(r, video_int->interlacing, 3, 3);
700 r = FLD_MOD(r, video_int->tm, 1, 0);
701 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r);
702}
703
704static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data,
705 struct omap_video_timings *timings)
706{
707 u32 timing_h = 0;
708 u32 timing_v = 0;
709
710 pr_debug("Enter hdmi_wp_video_config_timing\n");
711
712 timing_h |= FLD_VAL(timings->hbp, 31, 20);
713 timing_h |= FLD_VAL(timings->hfp, 19, 8);
714 timing_h |= FLD_VAL(timings->hsw, 7, 0);
715 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h);
716
717 timing_v |= FLD_VAL(timings->vbp, 31, 20);
718 timing_v |= FLD_VAL(timings->vfp, 19, 8);
719 timing_v |= FLD_VAL(timings->vsw, 7, 0);
720 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v);
721}
722
723void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)
724{
725 /* HDMI */
726 struct omap_video_timings video_timing;
727 struct hdmi_video_format video_format;
728 struct hdmi_video_interface video_interface;
729 /* HDMI core */
730 struct hdmi_core_infoframe_avi avi_cfg;
731 struct hdmi_core_video_config v_core_cfg;
732 struct hdmi_core_packet_enable_repeat repeat_cfg;
733 struct hdmi_config *cfg = &ip_data->cfg;
734
735 hdmi_wp_init(&video_timing, &video_format,
736 &video_interface);
737
738 hdmi_core_init(&v_core_cfg,
739 &avi_cfg,
740 &repeat_cfg);
741
742 hdmi_wp_video_init_format(&video_format, &video_timing, cfg);
743
744 hdmi_wp_video_config_timing(ip_data, &video_timing);
745
746 /* video config */
747 video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
748
749 hdmi_wp_video_config_format(ip_data, &video_format);
750
751 video_interface.vsp = cfg->timings.vsync_pol;
752 video_interface.hsp = cfg->timings.hsync_pol;
753 video_interface.interlacing = cfg->interlace;
754 video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
755
756 hdmi_wp_video_config_interface(ip_data, &video_interface);
757
758 /*
759 * configure core video part
760 * set software reset in the core
761 */
762 hdmi_core_swreset_assert(ip_data);
763
764 /* power down off */
765 hdmi_core_powerdown_disable(ip_data);
766
767 v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
768 v_core_cfg.hdmi_dvi = cfg->cm.mode;
769
770 hdmi_core_video_config(ip_data, &v_core_cfg);
771
772 /* release software reset in the core */
773 hdmi_core_swreset_release(ip_data);
774
775 /*
776 * configure packet
777 * info frame video see doc CEA861-D page 65
778 */
779 avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
780 avi_cfg.db1_active_info =
781 HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
782 avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
783 avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
784 avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
785 avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
786 avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
787 avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
788 avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
789 avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
790 avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
791 avi_cfg.db4_videocode = cfg->cm.code;
792 avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
793 avi_cfg.db6_7_line_eoftop = 0;
794 avi_cfg.db8_9_line_sofbottom = 0;
795 avi_cfg.db10_11_pixel_eofleft = 0;
796 avi_cfg.db12_13_pixel_sofright = 0;
797
798 hdmi_core_aux_infoframe_avi_config(ip_data, avi_cfg);
799
800 /* enable/repeat the infoframe */
801 repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
802 repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
803 /* wakeup */
804 repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
805 repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
806 hdmi_core_av_packet_config(ip_data, repeat_cfg);
807}
808
809void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
810{
811#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r,\
812 hdmi_read_reg(hdmi_wp_base(ip_data), r))
813
814 DUMPREG(HDMI_WP_REVISION);
815 DUMPREG(HDMI_WP_SYSCONFIG);
816 DUMPREG(HDMI_WP_IRQSTATUS_RAW);
817 DUMPREG(HDMI_WP_IRQSTATUS);
818 DUMPREG(HDMI_WP_PWR_CTRL);
819 DUMPREG(HDMI_WP_IRQENABLE_SET);
820 DUMPREG(HDMI_WP_VIDEO_CFG);
821 DUMPREG(HDMI_WP_VIDEO_SIZE);
822 DUMPREG(HDMI_WP_VIDEO_TIMING_H);
823 DUMPREG(HDMI_WP_VIDEO_TIMING_V);
824 DUMPREG(HDMI_WP_WP_CLK);
825 DUMPREG(HDMI_WP_AUDIO_CFG);
826 DUMPREG(HDMI_WP_AUDIO_CFG2);
827 DUMPREG(HDMI_WP_AUDIO_CTRL);
828 DUMPREG(HDMI_WP_AUDIO_DATA);
829}
830
831void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
832{
833#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
834 hdmi_read_reg(hdmi_pll_base(ip_data), r))
835
836 DUMPPLL(PLLCTRL_PLL_CONTROL);
837 DUMPPLL(PLLCTRL_PLL_STATUS);
838 DUMPPLL(PLLCTRL_PLL_GO);
839 DUMPPLL(PLLCTRL_CFG1);
840 DUMPPLL(PLLCTRL_CFG2);
841 DUMPPLL(PLLCTRL_CFG3);
842 DUMPPLL(PLLCTRL_CFG4);
843}
844
845void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
846{
847 int i;
848
849#define CORE_REG(i, name) name(i)
850#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\
851 hdmi_read_reg(hdmi_pll_base(ip_data), r))
852#define DUMPCOREAV(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \
853 (i < 10) ? 32 - strlen(#r) : 31 - strlen(#r), " ", \
854 hdmi_read_reg(hdmi_pll_base(ip_data), CORE_REG(i, r)))
855
856 DUMPCORE(HDMI_CORE_SYS_VND_IDL);
857 DUMPCORE(HDMI_CORE_SYS_DEV_IDL);
858 DUMPCORE(HDMI_CORE_SYS_DEV_IDH);
859 DUMPCORE(HDMI_CORE_SYS_DEV_REV);
860 DUMPCORE(HDMI_CORE_SYS_SRST);
861 DUMPCORE(HDMI_CORE_CTRL1);
862 DUMPCORE(HDMI_CORE_SYS_SYS_STAT);
863 DUMPCORE(HDMI_CORE_SYS_VID_ACEN);
864 DUMPCORE(HDMI_CORE_SYS_VID_MODE);
865 DUMPCORE(HDMI_CORE_SYS_INTR_STATE);
866 DUMPCORE(HDMI_CORE_SYS_INTR1);
867 DUMPCORE(HDMI_CORE_SYS_INTR2);
868 DUMPCORE(HDMI_CORE_SYS_INTR3);
869 DUMPCORE(HDMI_CORE_SYS_INTR4);
870 DUMPCORE(HDMI_CORE_SYS_UMASK1);
871 DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL);
872 DUMPCORE(HDMI_CORE_SYS_DE_DLY);
873 DUMPCORE(HDMI_CORE_SYS_DE_CTRL);
874 DUMPCORE(HDMI_CORE_SYS_DE_TOP);
875 DUMPCORE(HDMI_CORE_SYS_DE_CNTL);
876 DUMPCORE(HDMI_CORE_SYS_DE_CNTH);
877 DUMPCORE(HDMI_CORE_SYS_DE_LINL);
878 DUMPCORE(HDMI_CORE_SYS_DE_LINH_1);
879
880 DUMPCORE(HDMI_CORE_DDC_CMD);
881 DUMPCORE(HDMI_CORE_DDC_STATUS);
882 DUMPCORE(HDMI_CORE_DDC_ADDR);
883 DUMPCORE(HDMI_CORE_DDC_OFFSET);
884 DUMPCORE(HDMI_CORE_DDC_COUNT1);
885 DUMPCORE(HDMI_CORE_DDC_COUNT2);
886 DUMPCORE(HDMI_CORE_DDC_DATA);
887 DUMPCORE(HDMI_CORE_DDC_SEGM);
888
889 DUMPCORE(HDMI_CORE_AV_HDMI_CTRL);
890 DUMPCORE(HDMI_CORE_AV_DPD);
891 DUMPCORE(HDMI_CORE_AV_PB_CTRL1);
892 DUMPCORE(HDMI_CORE_AV_PB_CTRL2);
893 DUMPCORE(HDMI_CORE_AV_AVI_TYPE);
894 DUMPCORE(HDMI_CORE_AV_AVI_VERS);
895 DUMPCORE(HDMI_CORE_AV_AVI_LEN);
896 DUMPCORE(HDMI_CORE_AV_AVI_CHSUM);
897
898 for (i = 0; i < HDMI_CORE_AV_AVI_DBYTE_NELEMS; i++)
899 DUMPCOREAV(i, HDMI_CORE_AV_AVI_DBYTE);
900
901 for (i = 0; i < HDMI_CORE_AV_SPD_DBYTE_NELEMS; i++)
902 DUMPCOREAV(i, HDMI_CORE_AV_SPD_DBYTE);
903
904 for (i = 0; i < HDMI_CORE_AV_AUD_DBYTE_NELEMS; i++)
905 DUMPCOREAV(i, HDMI_CORE_AV_AUD_DBYTE);
906
907 for (i = 0; i < HDMI_CORE_AV_MPEG_DBYTE_NELEMS; i++)
908 DUMPCOREAV(i, HDMI_CORE_AV_MPEG_DBYTE);
909
910 for (i = 0; i < HDMI_CORE_AV_GEN_DBYTE_NELEMS; i++)
911 DUMPCOREAV(i, HDMI_CORE_AV_GEN_DBYTE);
912
913 for (i = 0; i < HDMI_CORE_AV_GEN2_DBYTE_NELEMS; i++)
914 DUMPCOREAV(i, HDMI_CORE_AV_GEN2_DBYTE);
915
916 DUMPCORE(HDMI_CORE_AV_ACR_CTRL);
917 DUMPCORE(HDMI_CORE_AV_FREQ_SVAL);
918 DUMPCORE(HDMI_CORE_AV_N_SVAL1);
919 DUMPCORE(HDMI_CORE_AV_N_SVAL2);
920 DUMPCORE(HDMI_CORE_AV_N_SVAL3);
921 DUMPCORE(HDMI_CORE_AV_CTS_SVAL1);
922 DUMPCORE(HDMI_CORE_AV_CTS_SVAL2);
923 DUMPCORE(HDMI_CORE_AV_CTS_SVAL3);
924 DUMPCORE(HDMI_CORE_AV_CTS_HVAL1);
925 DUMPCORE(HDMI_CORE_AV_CTS_HVAL2);
926 DUMPCORE(HDMI_CORE_AV_CTS_HVAL3);
927 DUMPCORE(HDMI_CORE_AV_AUD_MODE);
928 DUMPCORE(HDMI_CORE_AV_SPDIF_CTRL);
929 DUMPCORE(HDMI_CORE_AV_HW_SPDIF_FS);
930 DUMPCORE(HDMI_CORE_AV_SWAP_I2S);
931 DUMPCORE(HDMI_CORE_AV_SPDIF_ERTH);
932 DUMPCORE(HDMI_CORE_AV_I2S_IN_MAP);
933 DUMPCORE(HDMI_CORE_AV_I2S_IN_CTRL);
934 DUMPCORE(HDMI_CORE_AV_I2S_CHST0);
935 DUMPCORE(HDMI_CORE_AV_I2S_CHST1);
936 DUMPCORE(HDMI_CORE_AV_I2S_CHST2);
937 DUMPCORE(HDMI_CORE_AV_I2S_CHST4);
938 DUMPCORE(HDMI_CORE_AV_I2S_CHST5);
939 DUMPCORE(HDMI_CORE_AV_ASRC);
940 DUMPCORE(HDMI_CORE_AV_I2S_IN_LEN);
941 DUMPCORE(HDMI_CORE_AV_HDMI_CTRL);
942 DUMPCORE(HDMI_CORE_AV_AUDO_TXSTAT);
943 DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_1);
944 DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_2);
945 DUMPCORE(HDMI_CORE_AV_AUD_PAR_BUSCLK_3);
946 DUMPCORE(HDMI_CORE_AV_TEST_TXCTRL);
947 DUMPCORE(HDMI_CORE_AV_DPD);
948 DUMPCORE(HDMI_CORE_AV_PB_CTRL1);
949 DUMPCORE(HDMI_CORE_AV_PB_CTRL2);
950 DUMPCORE(HDMI_CORE_AV_AVI_TYPE);
951 DUMPCORE(HDMI_CORE_AV_AVI_VERS);
952 DUMPCORE(HDMI_CORE_AV_AVI_LEN);
953 DUMPCORE(HDMI_CORE_AV_AVI_CHSUM);
954 DUMPCORE(HDMI_CORE_AV_SPD_TYPE);
955 DUMPCORE(HDMI_CORE_AV_SPD_VERS);
956 DUMPCORE(HDMI_CORE_AV_SPD_LEN);
957 DUMPCORE(HDMI_CORE_AV_SPD_CHSUM);
958 DUMPCORE(HDMI_CORE_AV_AUDIO_TYPE);
959 DUMPCORE(HDMI_CORE_AV_AUDIO_VERS);
960 DUMPCORE(HDMI_CORE_AV_AUDIO_LEN);
961 DUMPCORE(HDMI_CORE_AV_AUDIO_CHSUM);
962 DUMPCORE(HDMI_CORE_AV_MPEG_TYPE);
963 DUMPCORE(HDMI_CORE_AV_MPEG_VERS);
964 DUMPCORE(HDMI_CORE_AV_MPEG_LEN);
965 DUMPCORE(HDMI_CORE_AV_MPEG_CHSUM);
966 DUMPCORE(HDMI_CORE_AV_CP_BYTE1);
967 DUMPCORE(HDMI_CORE_AV_CEC_ADDR_ID);
968}
969
970void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)
971{
972#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\
973 hdmi_read_reg(hdmi_phy_base(ip_data), r))
974
975 DUMPPHY(HDMI_TXPHY_TX_CTRL);
976 DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL);
977 DUMPPHY(HDMI_TXPHY_POWER_CTRL);
978 DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL);
979}
980
981#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
982 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
983void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data,
984 struct hdmi_audio_format *aud_fmt)
985{
986 u32 r;
987
988 DSSDBG("Enter hdmi_wp_audio_config_format\n");
989
990 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG);
991 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
992 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
993 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
994 r = FLD_MOD(r, aud_fmt->type, 4, 4);
995 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
996 r = FLD_MOD(r, aud_fmt->sample_order, 2, 2);
997 r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1);
998 r = FLD_MOD(r, aud_fmt->sample_size, 0, 0);
999 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r);
1000}
1001
1002void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
1003 struct hdmi_audio_dma *aud_dma)
1004{
1005 u32 r;
1006
1007 DSSDBG("Enter hdmi_wp_audio_config_dma\n");
1008
1009 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2);
1010 r = FLD_MOD(r, aud_dma->transfer_size, 15, 8);
1011 r = FLD_MOD(r, aud_dma->block_size, 7, 0);
1012 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r);
1013
1014 r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL);
1015 r = FLD_MOD(r, aud_dma->mode, 9, 9);
1016 r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0);
1017 hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r);
1018}
1019
1020void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
1021 struct hdmi_core_audio_config *cfg)
1022{
1023 u32 r;
1024 void __iomem *av_base = hdmi_av_base(ip_data);
1025
1026 /* audio clock recovery parameters */
1027 r = hdmi_read_reg(av_base, HDMI_CORE_AV_ACR_CTRL);
1028 r = FLD_MOD(r, cfg->use_mclk, 2, 2);
1029 r = FLD_MOD(r, cfg->en_acr_pkt, 1, 1);
1030 r = FLD_MOD(r, cfg->cts_mode, 0, 0);
1031 hdmi_write_reg(av_base, HDMI_CORE_AV_ACR_CTRL, r);
1032
1033 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL1, cfg->n, 7, 0);
1034 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL2, cfg->n >> 8, 7, 0);
1035 REG_FLD_MOD(av_base, HDMI_CORE_AV_N_SVAL3, cfg->n >> 16, 7, 0);
1036
1037 if (cfg->cts_mode == HDMI_AUDIO_CTS_MODE_SW) {
1038 REG_FLD_MOD(av_base, HDMI_CORE_AV_CTS_SVAL1, cfg->cts, 7, 0);
1039 REG_FLD_MOD(av_base,
1040 HDMI_CORE_AV_CTS_SVAL2, cfg->cts >> 8, 7, 0);
1041 REG_FLD_MOD(av_base,
1042 HDMI_CORE_AV_CTS_SVAL3, cfg->cts >> 16, 7, 0);
1043 } else {
1044 /*
1045 * HDMI IP uses this configuration to divide the MCLK to
1046 * update CTS value.
1047 */
1048 REG_FLD_MOD(av_base,
1049 HDMI_CORE_AV_FREQ_SVAL, cfg->mclk_mode, 2, 0);
1050
1051 /* Configure clock for audio packets */
1052 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_1,
1053 cfg->aud_par_busclk, 7, 0);
1054 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_2,
1055 (cfg->aud_par_busclk >> 8), 7, 0);
1056 REG_FLD_MOD(av_base, HDMI_CORE_AV_AUD_PAR_BUSCLK_3,
1057 (cfg->aud_par_busclk >> 16), 7, 0);
1058 }
1059
1060 /* Override of SPDIF sample frequency with value in I2S_CHST4 */
1061 REG_FLD_MOD(av_base, HDMI_CORE_AV_SPDIF_CTRL,
1062 cfg->fs_override, 1, 1);
1063
1064 /* I2S parameters */
1065 REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_CHST4,
1066 cfg->freq_sample, 3, 0);
1067
1068 r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL);
1069 r = FLD_MOD(r, cfg->i2s_cfg.en_high_bitrate_aud, 7, 7);
1070 r = FLD_MOD(r, cfg->i2s_cfg.sck_edge_mode, 6, 6);
1071 r = FLD_MOD(r, cfg->i2s_cfg.cbit_order, 5, 5);
1072 r = FLD_MOD(r, cfg->i2s_cfg.vbit, 4, 4);
1073 r = FLD_MOD(r, cfg->i2s_cfg.ws_polarity, 3, 3);
1074 r = FLD_MOD(r, cfg->i2s_cfg.justification, 2, 2);
1075 r = FLD_MOD(r, cfg->i2s_cfg.direction, 1, 1);
1076 r = FLD_MOD(r, cfg->i2s_cfg.shift, 0, 0);
1077 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_IN_CTRL, r);
1078
1079 r = hdmi_read_reg(av_base, HDMI_CORE_AV_I2S_CHST5);
1080 r = FLD_MOD(r, cfg->freq_sample, 7, 4);
1081 r = FLD_MOD(r, cfg->i2s_cfg.word_length, 3, 1);
1082 r = FLD_MOD(r, cfg->i2s_cfg.word_max_length, 0, 0);
1083 hdmi_write_reg(av_base, HDMI_CORE_AV_I2S_CHST5, r);
1084
1085 REG_FLD_MOD(av_base, HDMI_CORE_AV_I2S_IN_LEN,
1086 cfg->i2s_cfg.in_length_bits, 3, 0);
1087
1088 /* Audio channels and mode parameters */
1089 REG_FLD_MOD(av_base, HDMI_CORE_AV_HDMI_CTRL, cfg->layout, 2, 1);
1090 r = hdmi_read_reg(av_base, HDMI_CORE_AV_AUD_MODE);
1091 r = FLD_MOD(r, cfg->i2s_cfg.active_sds, 7, 4);
1092 r = FLD_MOD(r, cfg->en_dsd_audio, 3, 3);
1093 r = FLD_MOD(r, cfg->en_parallel_aud_input, 2, 2);
1094 r = FLD_MOD(r, cfg->en_spdif, 1, 1);
1095 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_MODE, r);
1096}
1097
1098void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
1099 struct hdmi_core_infoframe_audio *info_aud)
1100{
1101 u8 val;
1102 u8 sum = 0, checksum = 0;
1103 void __iomem *av_base = hdmi_av_base(ip_data);
1104
1105 /*
1106 * Set audio info frame type, version and length as
1107 * described in HDMI 1.4a Section 8.2.2 specification.
1108 * Checksum calculation is defined in Section 5.3.5.
1109 */
1110 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_TYPE, 0x84);
1111 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_VERS, 0x01);
1112 hdmi_write_reg(av_base, HDMI_CORE_AV_AUDIO_LEN, 0x0a);
1113 sum += 0x84 + 0x001 + 0x00a;
1114
1115 val = (info_aud->db1_coding_type << 4)
1116 | (info_aud->db1_channel_count - 1);
1117 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(0), val);
1118 sum += val;
1119
1120 val = (info_aud->db2_sample_freq << 2) | info_aud->db2_sample_size;
1121 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(1), val);
1122 sum += val;
1123
1124 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), 0x00);
1125
1126 val = info_aud->db4_channel_alloc;
1127 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), val);
1128 sum += val;
1129
1130 val = (info_aud->db5_downmix_inh << 7) | (info_aud->db5_lsv << 3);
1131 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(4), val);
1132 sum += val;
1133
1134 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(5), 0x00);
1135 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(6), 0x00);
1136 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(7), 0x00);
1137 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(8), 0x00);
1138 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(9), 0x00);
1139
1140 checksum = 0x100 - sum;
1141 hdmi_write_reg(av_base,
1142 HDMI_CORE_AV_AUDIO_CHSUM, checksum);
1143
1144 /*
1145 * TODO: Add MPEG and SPD enable and repeat cfg when EDID parsing
1146 * is available.
1147 */
1148}
1149
1150int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
1151 u32 sample_freq, u32 *n, u32 *cts)
1152{
1153 u32 r;
1154 u32 deep_color = 0;
1155 u32 pclk = ip_data->cfg.timings.timings.pixel_clock;
1156
1157 if (n == NULL || cts == NULL)
1158 return -EINVAL;
1159 /*
1160 * Obtain current deep color configuration. This needed
1161 * to calculate the TMDS clock based on the pixel clock.
1162 */
1163 r = REG_GET(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, 1, 0);
1164 switch (r) {
1165 case 1: /* No deep color selected */
1166 deep_color = 100;
1167 break;
1168 case 2: /* 10-bit deep color selected */
1169 deep_color = 125;
1170 break;
1171 case 3: /* 12-bit deep color selected */
1172 deep_color = 150;
1173 break;
1174 default:
1175 return -EINVAL;
1176 }
1177
1178 switch (sample_freq) {
1179 case 32000:
1180 if ((deep_color == 125) && ((pclk == 54054)
1181 || (pclk == 74250)))
1182 *n = 8192;
1183 else
1184 *n = 4096;
1185 break;
1186 case 44100:
1187 *n = 6272;
1188 break;
1189 case 48000:
1190 if ((deep_color == 125) && ((pclk == 54054)
1191 || (pclk == 74250)))
1192 *n = 8192;
1193 else
1194 *n = 6144;
1195 break;
1196 default:
1197 *n = 0;
1198 return -EINVAL;
1199 }
1200
1201 /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
1202 *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
1203
1204 return 0;
1205}
1206
1207int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
1208 struct snd_pcm_substream *substream, int cmd,
1209 struct snd_soc_dai *dai)
1210{
1211 int err = 0;
1212 switch (cmd) {
1213 case SNDRV_PCM_TRIGGER_START:
1214 case SNDRV_PCM_TRIGGER_RESUME:
1215 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1216 REG_FLD_MOD(hdmi_av_base(ip_data),
1217 HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
1218 REG_FLD_MOD(hdmi_wp_base(ip_data),
1219 HDMI_WP_AUDIO_CTRL, 1, 31, 31);
1220 REG_FLD_MOD(hdmi_wp_base(ip_data),
1221 HDMI_WP_AUDIO_CTRL, 1, 30, 30);
1222 break;
1223
1224 case SNDRV_PCM_TRIGGER_STOP:
1225 case SNDRV_PCM_TRIGGER_SUSPEND:
1226 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1227 REG_FLD_MOD(hdmi_av_base(ip_data),
1228 HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
1229 REG_FLD_MOD(hdmi_wp_base(ip_data),
1230 HDMI_WP_AUDIO_CTRL, 0, 30, 30);
1231 REG_FLD_MOD(hdmi_wp_base(ip_data),
1232 HDMI_WP_AUDIO_CTRL, 0, 31, 31);
1233 break;
1234 default:
1235 err = -EINVAL;
1236 }
1237 return err;
1238}
1239#endif
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index c885f9cb0659..204095632d27 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * hdmi.h 2 * ti_hdmi_4xxx_ip.h
3 * 3 *
4 * HDMI driver definition for TI OMAP4 processors. 4 * HDMI header definition for DM81xx, DM38xx, TI OMAP4 etc processors.
5 * 5 *
6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ 6 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
7 * 7 *
@@ -18,202 +18,177 @@
18 * this program. If not, see <http://www.gnu.org/licenses/>. 18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */ 19 */
20 20
21#ifndef _OMAP4_DSS_HDMI_H_ 21#ifndef _HDMI_TI_4xxx_H_
22#define _OMAP4_DSS_HDMI_H_ 22#define _HDMI_TI_4xxx_H_
23 23
24#include <linux/string.h> 24#include <linux/string.h>
25#include <video/omapdss.h> 25#include <video/omapdss.h>
26 26#include "ti_hdmi.h"
27#define HDMI_WP 0x0 27#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
28#define HDMI_CORE_SYS 0x400 28 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
29#define HDMI_CORE_AV 0x900 29#include <sound/soc.h>
30#define HDMI_PLLCTRL 0x200 30#include <sound/pcm_params.h>
31#define HDMI_PHY 0x300 31#endif
32
33struct hdmi_reg { u16 idx; };
34
35#define HDMI_REG(idx) ((const struct hdmi_reg) { idx })
36 32
37/* HDMI Wrapper */ 33/* HDMI Wrapper */
38#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx) 34
39 35#define HDMI_WP_REVISION 0x0
40#define HDMI_WP_REVISION HDMI_WP_REG(0x0) 36#define HDMI_WP_SYSCONFIG 0x10
41#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10) 37#define HDMI_WP_IRQSTATUS_RAW 0x24
42#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24) 38#define HDMI_WP_IRQSTATUS 0x28
43#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28) 39#define HDMI_WP_PWR_CTRL 0x40
44#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40) 40#define HDMI_WP_IRQENABLE_SET 0x2C
45#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C) 41#define HDMI_WP_VIDEO_CFG 0x50
46#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50) 42#define HDMI_WP_VIDEO_SIZE 0x60
47#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60) 43#define HDMI_WP_VIDEO_TIMING_H 0x68
48#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68) 44#define HDMI_WP_VIDEO_TIMING_V 0x6C
49#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C) 45#define HDMI_WP_WP_CLK 0x70
50#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70) 46#define HDMI_WP_AUDIO_CFG 0x80
51#define HDMI_WP_AUDIO_CFG HDMI_WP_REG(0x80) 47#define HDMI_WP_AUDIO_CFG2 0x84
52#define HDMI_WP_AUDIO_CFG2 HDMI_WP_REG(0x84) 48#define HDMI_WP_AUDIO_CTRL 0x88
53#define HDMI_WP_AUDIO_CTRL HDMI_WP_REG(0x88) 49#define HDMI_WP_AUDIO_DATA 0x8C
54#define HDMI_WP_AUDIO_DATA HDMI_WP_REG(0x8C)
55 50
56/* HDMI IP Core System */ 51/* HDMI IP Core System */
57#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx) 52
58 53#define HDMI_CORE_SYS_VND_IDL 0x0
59#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0) 54#define HDMI_CORE_SYS_DEV_IDL 0x8
60#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8) 55#define HDMI_CORE_SYS_DEV_IDH 0xC
61#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC) 56#define HDMI_CORE_SYS_DEV_REV 0x10
62#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10) 57#define HDMI_CORE_SYS_SRST 0x14
63#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14) 58#define HDMI_CORE_CTRL1 0x20
64#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20) 59#define HDMI_CORE_SYS_SYS_STAT 0x24
65#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24) 60#define HDMI_CORE_SYS_VID_ACEN 0x124
66#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124) 61#define HDMI_CORE_SYS_VID_MODE 0x128
67#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128) 62#define HDMI_CORE_SYS_INTR_STATE 0x1C0
68#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0) 63#define HDMI_CORE_SYS_INTR1 0x1C4
69#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4) 64#define HDMI_CORE_SYS_INTR2 0x1C8
70#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8) 65#define HDMI_CORE_SYS_INTR3 0x1CC
71#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC) 66#define HDMI_CORE_SYS_INTR4 0x1D0
72#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0) 67#define HDMI_CORE_SYS_UMASK1 0x1D4
73#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4) 68#define HDMI_CORE_SYS_TMDS_CTRL 0x208
74#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208) 69#define HDMI_CORE_SYS_DE_DLY 0xC8
75#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8) 70#define HDMI_CORE_SYS_DE_CTRL 0xCC
76#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC) 71#define HDMI_CORE_SYS_DE_TOP 0xD0
77#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0) 72#define HDMI_CORE_SYS_DE_CNTL 0xD8
78#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8) 73#define HDMI_CORE_SYS_DE_CNTH 0xDC
79#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC) 74#define HDMI_CORE_SYS_DE_LINL 0xE0
80#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0) 75#define HDMI_CORE_SYS_DE_LINH_1 0xE4
81#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4)
82#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 76#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1
83#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 77#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1
84#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 78#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1
85#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 79#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1
86 80
87/* HDMI DDC E-DID */ 81/* HDMI DDC E-DID */
88#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC) 82#define HDMI_CORE_DDC_CMD 0x3CC
89#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8) 83#define HDMI_CORE_DDC_STATUS 0x3C8
90#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4) 84#define HDMI_CORE_DDC_ADDR 0x3B4
91#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC) 85#define HDMI_CORE_DDC_OFFSET 0x3BC
92#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0) 86#define HDMI_CORE_DDC_COUNT1 0x3C0
93#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4) 87#define HDMI_CORE_DDC_COUNT2 0x3C4
94#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0) 88#define HDMI_CORE_DDC_DATA 0x3D0
95#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8) 89#define HDMI_CORE_DDC_SEGM 0x3B8
96 90
97/* HDMI IP Core Audio Video */ 91/* HDMI IP Core Audio Video */
98#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx) 92
99 93#define HDMI_CORE_AV_HDMI_CTRL 0xBC
100#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC) 94#define HDMI_CORE_AV_DPD 0xF4
101#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4) 95#define HDMI_CORE_AV_PB_CTRL1 0xF8
102#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8) 96#define HDMI_CORE_AV_PB_CTRL2 0xFC
103#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC) 97#define HDMI_CORE_AV_AVI_TYPE 0x100
104#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100) 98#define HDMI_CORE_AV_AVI_VERS 0x104
105#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104) 99#define HDMI_CORE_AV_AVI_LEN 0x108
106#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108) 100#define HDMI_CORE_AV_AVI_CHSUM 0x10C
107#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C) 101#define HDMI_CORE_AV_AVI_DBYTE(n) (n * 4 + 0x110)
108#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110) 102#define HDMI_CORE_AV_AVI_DBYTE_NELEMS 15
109#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15) 103#define HDMI_CORE_AV_SPD_DBYTE(n) (n * 4 + 0x190)
110#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190) 104#define HDMI_CORE_AV_SPD_DBYTE_NELEMS 27
111#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27) 105#define HDMI_CORE_AV_AUD_DBYTE(n) (n * 4 + 0x210)
112#define HDMI_CORE_AV_AUD_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x210) 106#define HDMI_CORE_AV_AUD_DBYTE_NELEMS 10
113#define HDMI_CORE_AV_AUD_DBYTE_NELEMS HDMI_CORE_AV_REG(10) 107#define HDMI_CORE_AV_MPEG_DBYTE(n) (n * 4 + 0x290)
114#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290) 108#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS 27
115#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27) 109#define HDMI_CORE_AV_GEN_DBYTE(n) (n * 4 + 0x300)
116#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300) 110#define HDMI_CORE_AV_GEN_DBYTE_NELEMS 31
117#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31) 111#define HDMI_CORE_AV_GEN2_DBYTE(n) (n * 4 + 0x380)
118#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380) 112#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS 31
119#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31) 113#define HDMI_CORE_AV_ACR_CTRL 0x4
120#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4) 114#define HDMI_CORE_AV_FREQ_SVAL 0x8
121#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8) 115#define HDMI_CORE_AV_N_SVAL1 0xC
122#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC) 116#define HDMI_CORE_AV_N_SVAL2 0x10
123#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10) 117#define HDMI_CORE_AV_N_SVAL3 0x14
124#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14) 118#define HDMI_CORE_AV_CTS_SVAL1 0x18
125#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18) 119#define HDMI_CORE_AV_CTS_SVAL2 0x1C
126#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C) 120#define HDMI_CORE_AV_CTS_SVAL3 0x20
127#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20) 121#define HDMI_CORE_AV_CTS_HVAL1 0x24
128#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24) 122#define HDMI_CORE_AV_CTS_HVAL2 0x28
129#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28) 123#define HDMI_CORE_AV_CTS_HVAL3 0x2C
130#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C) 124#define HDMI_CORE_AV_AUD_MODE 0x50
131#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50) 125#define HDMI_CORE_AV_SPDIF_CTRL 0x54
132#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54) 126#define HDMI_CORE_AV_HW_SPDIF_FS 0x60
133#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60) 127#define HDMI_CORE_AV_SWAP_I2S 0x64
134#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64) 128#define HDMI_CORE_AV_SPDIF_ERTH 0x6C
135#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C) 129#define HDMI_CORE_AV_I2S_IN_MAP 0x70
136#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70) 130#define HDMI_CORE_AV_I2S_IN_CTRL 0x74
137#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74) 131#define HDMI_CORE_AV_I2S_CHST0 0x78
138#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78) 132#define HDMI_CORE_AV_I2S_CHST1 0x7C
139#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C) 133#define HDMI_CORE_AV_I2S_CHST2 0x80
140#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80) 134#define HDMI_CORE_AV_I2S_CHST4 0x84
141#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84) 135#define HDMI_CORE_AV_I2S_CHST5 0x88
142#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88) 136#define HDMI_CORE_AV_ASRC 0x8C
143#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C) 137#define HDMI_CORE_AV_I2S_IN_LEN 0x90
144#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90) 138#define HDMI_CORE_AV_HDMI_CTRL 0xBC
145#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC) 139#define HDMI_CORE_AV_AUDO_TXSTAT 0xC0
146#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0) 140#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 0xCC
147#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC) 141#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 0xD0
148#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0) 142#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 0xD4
149#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4) 143#define HDMI_CORE_AV_TEST_TXCTRL 0xF0
150#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0) 144#define HDMI_CORE_AV_DPD 0xF4
151#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4) 145#define HDMI_CORE_AV_PB_CTRL1 0xF8
152#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8) 146#define HDMI_CORE_AV_PB_CTRL2 0xFC
153#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC) 147#define HDMI_CORE_AV_AVI_TYPE 0x100
154#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100) 148#define HDMI_CORE_AV_AVI_VERS 0x104
155#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104) 149#define HDMI_CORE_AV_AVI_LEN 0x108
156#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108) 150#define HDMI_CORE_AV_AVI_CHSUM 0x10C
157#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C) 151#define HDMI_CORE_AV_SPD_TYPE 0x180
158#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180) 152#define HDMI_CORE_AV_SPD_VERS 0x184
159#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184) 153#define HDMI_CORE_AV_SPD_LEN 0x188
160#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188) 154#define HDMI_CORE_AV_SPD_CHSUM 0x18C
161#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C) 155#define HDMI_CORE_AV_AUDIO_TYPE 0x200
162#define HDMI_CORE_AV_AUDIO_TYPE HDMI_CORE_AV_REG(0x200) 156#define HDMI_CORE_AV_AUDIO_VERS 0x204
163#define HDMI_CORE_AV_AUDIO_VERS HDMI_CORE_AV_REG(0x204) 157#define HDMI_CORE_AV_AUDIO_LEN 0x208
164#define HDMI_CORE_AV_AUDIO_LEN HDMI_CORE_AV_REG(0x208) 158#define HDMI_CORE_AV_AUDIO_CHSUM 0x20C
165#define HDMI_CORE_AV_AUDIO_CHSUM HDMI_CORE_AV_REG(0x20C) 159#define HDMI_CORE_AV_MPEG_TYPE 0x280
166#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280) 160#define HDMI_CORE_AV_MPEG_VERS 0x284
167#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284) 161#define HDMI_CORE_AV_MPEG_LEN 0x288
168#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288) 162#define HDMI_CORE_AV_MPEG_CHSUM 0x28C
169#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C) 163#define HDMI_CORE_AV_CP_BYTE1 0x37C
170#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C) 164#define HDMI_CORE_AV_CEC_ADDR_ID 0x3FC
171#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC)
172#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 165#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4
173#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 166#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4
174#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 167#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4
175#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 168#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4
176 169
177/* PLL */ 170/* PLL */
178#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx)
179 171
180#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0) 172#define PLLCTRL_PLL_CONTROL 0x0
181#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4) 173#define PLLCTRL_PLL_STATUS 0x4
182#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8) 174#define PLLCTRL_PLL_GO 0x8
183#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC) 175#define PLLCTRL_CFG1 0xC
184#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10) 176#define PLLCTRL_CFG2 0x10
185#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14) 177#define PLLCTRL_CFG3 0x14
186#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20) 178#define PLLCTRL_CFG4 0x20
187 179
188/* HDMI PHY */ 180/* HDMI PHY */
189#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx)
190
191#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0)
192#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4)
193#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8)
194#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC)
195
196/* HDMI EDID Length */
197#define HDMI_EDID_MAX_LENGTH 256
198#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
199#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
200#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
201#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
202#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
203 181
204#define OMAP_HDMI_TIMINGS_NB 34 182#define HDMI_TXPHY_TX_CTRL 0x0
183#define HDMI_TXPHY_DIGITAL_CTRL 0x4
184#define HDMI_TXPHY_POWER_CTRL 0x8
185#define HDMI_TXPHY_PAD_CFG_CTRL 0xC
205 186
206#define REG_FLD_MOD(idx, val, start, end) \ 187#define REG_FLD_MOD(base, idx, val, start, end) \
207 hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end)) 188 hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
208#define REG_GET(idx, start, end) \ 189 val, start, end))
209 FLD_GET(hdmi_read_reg(idx), start, end) 190#define REG_GET(base, idx, start, end) \
210 191 FLD_GET(hdmi_read_reg(base, idx), start, end)
211/* HDMI timing structure */
212struct hdmi_timings {
213 struct omap_video_timings timings;
214 int vsync_pol;
215 int hsync_pol;
216};
217 192
218enum hdmi_phy_pwr { 193enum hdmi_phy_pwr {
219 HDMI_PHYPWRCMD_OFF = 0, 194 HDMI_PHYPWRCMD_OFF = 0,
@@ -221,20 +196,6 @@ enum hdmi_phy_pwr {
221 HDMI_PHYPWRCMD_TXON = 2 196 HDMI_PHYPWRCMD_TXON = 2
222}; 197};
223 198
224enum hdmi_pll_pwr {
225 HDMI_PLLPWRCMD_ALLOFF = 0,
226 HDMI_PLLPWRCMD_PLLONLY = 1,
227 HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
228 HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
229};
230
231enum hdmi_clk_refsel {
232 HDMI_REFSEL_PCLK = 0,
233 HDMI_REFSEL_REF1 = 1,
234 HDMI_REFSEL_REF2 = 2,
235 HDMI_REFSEL_SYSCLK = 3
236};
237
238enum hdmi_core_inputbus_width { 199enum hdmi_core_inputbus_width {
239 HDMI_INPUT_8BIT = 0, 200 HDMI_INPUT_8BIT = 0,
240 HDMI_INPUT_10BIT = 1, 201 HDMI_INPUT_10BIT = 1,
@@ -263,11 +224,6 @@ enum hdmi_core_packet_mode {
263 HDMI_PACKETMODE48BITPERPIXEL = 7 224 HDMI_PACKETMODE48BITPERPIXEL = 7
264}; 225};
265 226
266enum hdmi_core_hdmi_dvi {
267 HDMI_DVI = 0,
268 HDMI_HDMI = 1
269};
270
271enum hdmi_core_tclkselclkmult { 227enum hdmi_core_tclkselclkmult {
272 HDMI_FPLL05IDCK = 0, 228 HDMI_FPLL05IDCK = 0,
273 HDMI_FPLL10IDCK = 1, 229 HDMI_FPLL10IDCK = 1,
@@ -495,40 +451,40 @@ struct hdmi_core_video_config {
495 * details about infoframe databytes 451 * details about infoframe databytes
496 */ 452 */
497struct hdmi_core_infoframe_avi { 453struct hdmi_core_infoframe_avi {
454 /* Y0, Y1 rgb,yCbCr */
498 u8 db1_format; 455 u8 db1_format;
499 /* Y0, Y1 rgb,yCbCr */ 456 /* A0 Active information Present */
500 u8 db1_active_info; 457 u8 db1_active_info;
501 /* A0 Active information Present */ 458 /* B0, B1 Bar info data valid */
502 u8 db1_bar_info_dv; 459 u8 db1_bar_info_dv;
503 /* B0, B1 Bar info data valid */ 460 /* S0, S1 scan information */
504 u8 db1_scan_info; 461 u8 db1_scan_info;
505 /* S0, S1 scan information */ 462 /* C0, C1 colorimetry */
506 u8 db2_colorimetry; 463 u8 db2_colorimetry;
507 /* C0, C1 colorimetry */ 464 /* M0, M1 Aspect ratio (4:3, 16:9) */
508 u8 db2_aspect_ratio; 465 u8 db2_aspect_ratio;
509 /* M0, M1 Aspect ratio (4:3, 16:9) */ 466 /* R0...R3 Active format aspect ratio */
510 u8 db2_active_fmt_ar; 467 u8 db2_active_fmt_ar;
511 /* R0...R3 Active format aspect ratio */ 468 /* ITC IT content. */
512 u8 db3_itc; 469 u8 db3_itc;
513 /* ITC IT content. */ 470 /* EC0, EC1, EC2 Extended colorimetry */
514 u8 db3_ec; 471 u8 db3_ec;
515 /* EC0, EC1, EC2 Extended colorimetry */ 472 /* Q1, Q0 Quantization range */
516 u8 db3_q_range; 473 u8 db3_q_range;
517 /* Q1, Q0 Quantization range */ 474 /* SC1, SC0 Non-uniform picture scaling */
518 u8 db3_nup_scaling; 475 u8 db3_nup_scaling;
519 /* SC1, SC0 Non-uniform picture scaling */ 476 /* VIC0..6 Video format identification */
520 u8 db4_videocode; 477 u8 db4_videocode;
521 /* VIC0..6 Video format identification */ 478 /* PR0..PR3 Pixel repetition factor */
522 u8 db5_pixel_repeat; 479 u8 db5_pixel_repeat;
523 /* PR0..PR3 Pixel repetition factor */ 480 /* Line number end of top bar */
524 u16 db6_7_line_eoftop; 481 u16 db6_7_line_eoftop;
525 /* Line number end of top bar */ 482 /* Line number start of bottom bar */
526 u16 db8_9_line_sofbottom; 483 u16 db8_9_line_sofbottom;
527 /* Line number start of bottom bar */ 484 /* Pixel number end of left bar */
528 u16 db10_11_pixel_eofleft; 485 u16 db10_11_pixel_eofleft;
529 /* Pixel number end of left bar */ 486 /* Pixel number start of right bar */
530 u16 db12_13_pixel_sofright; 487 u16 db12_13_pixel_sofright;
531 /* Pixel number start of right bar */
532}; 488};
533/* 489/*
534 * Refer to section 8.2 in HDMI 1.3 specification for 490 * Refer to section 8.2 in HDMI 1.3 specification for
@@ -568,17 +524,6 @@ struct hdmi_video_interface {
568 int tm; /* Timing mode */ 524 int tm; /* Timing mode */
569}; 525};
570 526
571struct hdmi_cm {
572 int code;
573 int mode;
574};
575
576struct hdmi_config {
577 struct hdmi_timings timings;
578 u16 interlace;
579 struct hdmi_cm cm;
580};
581
582struct hdmi_audio_format { 527struct hdmi_audio_format {
583 enum hdmi_stereo_channels stereo_channels; 528 enum hdmi_stereo_channels stereo_channels;
584 u8 active_chnnls_msk; 529 u8 active_chnnls_msk;
@@ -628,4 +573,21 @@ struct hdmi_core_audio_config {
628 bool en_parallel_aud_input; 573 bool en_parallel_aud_input;
629 bool en_spdif; 574 bool en_spdif;
630}; 575};
576
577#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
578 defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
579int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
580 struct snd_pcm_substream *substream, int cmd,
581 struct snd_soc_dai *dai);
582int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
583 u32 sample_freq, u32 *n, u32 *cts);
584void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
585 struct hdmi_core_infoframe_audio *info_aud);
586void hdmi_core_audio_config(struct hdmi_ip_data *ip_data,
587 struct hdmi_core_audio_config *cfg);
588void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data,
589 struct hdmi_audio_dma *aud_dma);
590void hdmi_wp_audio_config_format(struct hdmi_ip_data *ip_data,
591 struct hdmi_audio_format *aud_fmt);
592#endif
631#endif 593#endif
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 173c66430dad..7533458ba4d2 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -295,7 +295,6 @@ static struct {
295 u32 wss_data; 295 u32 wss_data;
296 struct regulator *vdda_dac_reg; 296 struct regulator *vdda_dac_reg;
297 297
298 struct clk *tv_clk;
299 struct clk *tv_dac_clk; 298 struct clk *tv_dac_clk;
300} venc; 299} venc;
301 300
@@ -464,9 +463,11 @@ static void venc_power_off(struct omap_dss_device *dssdev)
464 regulator_disable(venc.vdda_dac_reg); 463 regulator_disable(venc.vdda_dac_reg);
465} 464}
466 465
467 466unsigned long venc_get_pixel_clock(void)
468 467{
469 468 /* VENC Pixel Clock in Mhz */
469 return 13500000;
470}
470 471
471/* driver */ 472/* driver */
472static int venc_panel_probe(struct omap_dss_device *dssdev) 473static int venc_panel_probe(struct omap_dss_device *dssdev)
@@ -732,22 +733,10 @@ static int venc_get_clocks(struct platform_device *pdev)
732{ 733{
733 struct clk *clk; 734 struct clk *clk;
734 735
735 clk = clk_get(&pdev->dev, "fck");
736 if (IS_ERR(clk)) {
737 DSSERR("can't get fck\n");
738 return PTR_ERR(clk);
739 }
740
741 venc.tv_clk = clk;
742
743 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) { 736 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
744 if (cpu_is_omap34xx() || cpu_is_omap3630()) 737 clk = clk_get(&pdev->dev, "tv_dac_clk");
745 clk = clk_get(&pdev->dev, "dss_96m_fck");
746 else
747 clk = clk_get(&pdev->dev, "tv_dac_clk");
748 if (IS_ERR(clk)) { 738 if (IS_ERR(clk)) {
749 DSSERR("can't get tv_dac_clk\n"); 739 DSSERR("can't get tv_dac_clk\n");
750 clk_put(venc.tv_clk);
751 return PTR_ERR(clk); 740 return PTR_ERR(clk);
752 } 741 }
753 } else { 742 } else {
@@ -761,8 +750,6 @@ static int venc_get_clocks(struct platform_device *pdev)
761 750
762static void venc_put_clocks(void) 751static void venc_put_clocks(void)
763{ 752{
764 if (venc.tv_clk)
765 clk_put(venc.tv_clk);
766 if (venc.tv_dac_clk) 753 if (venc.tv_dac_clk)
767 clk_put(venc.tv_dac_clk); 754 clk_put(venc.tv_dac_clk);
768} 755}
@@ -838,7 +825,6 @@ static int venc_runtime_suspend(struct device *dev)
838{ 825{
839 if (venc.tv_dac_clk) 826 if (venc.tv_dac_clk)
840 clk_disable(venc.tv_dac_clk); 827 clk_disable(venc.tv_dac_clk);
841 clk_disable(venc.tv_clk);
842 828
843 dispc_runtime_put(); 829 dispc_runtime_put();
844 dss_runtime_put(); 830 dss_runtime_put();
@@ -858,7 +844,6 @@ static int venc_runtime_resume(struct device *dev)
858 if (r < 0) 844 if (r < 0)
859 goto err_get_dispc; 845 goto err_get_dispc;
860 846
861 clk_enable(venc.tv_clk);
862 if (venc.tv_dac_clk) 847 if (venc.tv_dac_clk)
863 clk_enable(venc.tv_dac_clk); 848 clk_enable(venc.tv_dac_clk);
864 849
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index aa33386c81ff..83d3fe7ec9ae 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
1menuconfig FB_OMAP2 1menuconfig FB_OMAP2
2 tristate "OMAP2+ frame buffer support (EXPERIMENTAL)" 2 tristate "OMAP2+ frame buffer support"
3 depends on FB && OMAP2_DSS 3 depends on FB && OMAP2_DSS
4 4
5 select OMAP2_VRAM 5 select OMAP2_VRAM
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 602b71a92d3c..70aa47de7146 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -808,19 +808,15 @@ static unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var,
808static void omapfb_calc_addr(const struct omapfb_info *ofbi, 808static void omapfb_calc_addr(const struct omapfb_info *ofbi,
809 const struct fb_var_screeninfo *var, 809 const struct fb_var_screeninfo *var,
810 const struct fb_fix_screeninfo *fix, 810 const struct fb_fix_screeninfo *fix,
811 int rotation, u32 *paddr, void __iomem **vaddr) 811 int rotation, u32 *paddr)
812{ 812{
813 u32 data_start_p; 813 u32 data_start_p;
814 void __iomem *data_start_v;
815 int offset; 814 int offset;
816 815
817 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 816 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
818 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); 817 data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
819 data_start_v = NULL; 818 else
820 } else {
821 data_start_p = omapfb_get_region_paddr(ofbi); 819 data_start_p = omapfb_get_region_paddr(ofbi);
822 data_start_v = omapfb_get_region_vaddr(ofbi);
823 }
824 820
825 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 821 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
826 offset = calc_rotation_offset_vrfb(var, fix, rotation); 822 offset = calc_rotation_offset_vrfb(var, fix, rotation);
@@ -828,16 +824,14 @@ static void omapfb_calc_addr(const struct omapfb_info *ofbi,
828 offset = calc_rotation_offset_dma(var, fix, rotation); 824 offset = calc_rotation_offset_dma(var, fix, rotation);
829 825
830 data_start_p += offset; 826 data_start_p += offset;
831 data_start_v += offset;
832 827
833 if (offset) 828 if (offset)
834 DBG("offset %d, %d = %d\n", 829 DBG("offset %d, %d = %d\n",
835 var->xoffset, var->yoffset, offset); 830 var->xoffset, var->yoffset, offset);
836 831
837 DBG("paddr %x, vaddr %p\n", data_start_p, data_start_v); 832 DBG("paddr %x\n", data_start_p);
838 833
839 *paddr = data_start_p; 834 *paddr = data_start_p;
840 *vaddr = data_start_v;
841} 835}
842 836
843/* setup overlay according to the fb */ 837/* setup overlay according to the fb */
@@ -850,7 +844,6 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
850 struct fb_fix_screeninfo *fix = &fbi->fix; 844 struct fb_fix_screeninfo *fix = &fbi->fix;
851 enum omap_color_mode mode = 0; 845 enum omap_color_mode mode = 0;
852 u32 data_start_p = 0; 846 u32 data_start_p = 0;
853 void __iomem *data_start_v = NULL;
854 struct omap_overlay_info info; 847 struct omap_overlay_info info;
855 int xres, yres; 848 int xres, yres;
856 int screen_width; 849 int screen_width;
@@ -880,8 +873,7 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
880 } 873 }
881 874
882 if (ofbi->region->size) 875 if (ofbi->region->size)
883 omapfb_calc_addr(ofbi, var, fix, rotation, 876 omapfb_calc_addr(ofbi, var, fix, rotation, &data_start_p);
884 &data_start_p, &data_start_v);
885 877
886 r = fb_mode_to_dss_mode(var, &mode); 878 r = fb_mode_to_dss_mode(var, &mode);
887 if (r) { 879 if (r) {
@@ -910,7 +902,6 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
910 mirror = ofbi->mirror; 902 mirror = ofbi->mirror;
911 903
912 info.paddr = data_start_p; 904 info.paddr = data_start_p;
913 info.vaddr = data_start_v;
914 info.screen_width = screen_width; 905 info.screen_width = screen_width;
915 info.width = xres; 906 info.width = xres;
916 info.height = yres; 907 info.height = yres;
@@ -2276,6 +2267,87 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
2276 return r; 2267 return r;
2277} 2268}
2278 2269
2270static void fb_videomode_to_omap_timings(struct fb_videomode *m,
2271 struct omap_video_timings *t)
2272{
2273 t->x_res = m->xres;
2274 t->y_res = m->yres;
2275 t->pixel_clock = PICOS2KHZ(m->pixclock);
2276 t->hsw = m->hsync_len;
2277 t->hfp = m->right_margin;
2278 t->hbp = m->left_margin;
2279 t->vsw = m->vsync_len;
2280 t->vfp = m->lower_margin;
2281 t->vbp = m->upper_margin;
2282}
2283
2284static int omapfb_find_best_mode(struct omap_dss_device *display,
2285 struct omap_video_timings *timings)
2286{
2287 struct fb_monspecs *specs;
2288 u8 *edid;
2289 int r, i, best_xres, best_idx, len;
2290
2291 if (!display->driver->read_edid)
2292 return -ENODEV;
2293
2294 len = 0x80 * 2;
2295 edid = kmalloc(len, GFP_KERNEL);
2296
2297 r = display->driver->read_edid(display, edid, len);
2298 if (r < 0)
2299 goto err1;
2300
2301 specs = kzalloc(sizeof(*specs), GFP_KERNEL);
2302
2303 fb_edid_to_monspecs(edid, specs);
2304
2305 if (edid[126] > 0)
2306 fb_edid_add_monspecs(edid + 0x80, specs);
2307
2308 best_xres = 0;
2309 best_idx = -1;
2310
2311 for (i = 0; i < specs->modedb_len; ++i) {
2312 struct fb_videomode *m;
2313 struct omap_video_timings t;
2314
2315 m = &specs->modedb[i];
2316
2317 if (m->pixclock == 0)
2318 continue;
2319
2320 /* skip repeated pixel modes */
2321 if (m->xres == 2880 || m->xres == 1440)
2322 continue;
2323
2324 fb_videomode_to_omap_timings(m, &t);
2325
2326 r = display->driver->check_timings(display, &t);
2327 if (r == 0 && best_xres < m->xres) {
2328 best_xres = m->xres;
2329 best_idx = i;
2330 }
2331 }
2332
2333 if (best_xres == 0) {
2334 r = -ENOENT;
2335 goto err2;
2336 }
2337
2338 fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings);
2339
2340 r = 0;
2341
2342err2:
2343 fb_destroy_modedb(specs->modedb);
2344 kfree(specs);
2345err1:
2346 kfree(edid);
2347
2348 return r;
2349}
2350
2279static int omapfb_init_display(struct omapfb2_device *fbdev, 2351static int omapfb_init_display(struct omapfb2_device *fbdev,
2280 struct omap_dss_device *dssdev) 2352 struct omap_dss_device *dssdev)
2281{ 2353{
@@ -2373,8 +2445,10 @@ static int omapfb_probe(struct platform_device *pdev)
2373 omap_dss_get_device(dssdev); 2445 omap_dss_get_device(dssdev);
2374 2446
2375 if (!dssdev->driver) { 2447 if (!dssdev->driver) {
2376 dev_err(&pdev->dev, "no driver for display\n"); 2448 dev_warn(&pdev->dev, "no driver for display: %s\n",
2377 r = -ENODEV; 2449 dssdev->name);
2450 omap_dss_put_device(dssdev);
2451 continue;
2378 } 2452 }
2379 2453
2380 d = &fbdev->displays[fbdev->num_displays++]; 2454 d = &fbdev->displays[fbdev->num_displays++];
@@ -2402,9 +2476,27 @@ static int omapfb_probe(struct platform_device *pdev)
2402 for (i = 0; i < fbdev->num_managers; i++) 2476 for (i = 0; i < fbdev->num_managers; i++)
2403 fbdev->managers[i] = omap_dss_get_overlay_manager(i); 2477 fbdev->managers[i] = omap_dss_get_overlay_manager(i);
2404 2478
2479 /* gfx overlay should be the default one. find a display
2480 * connected to that, and use it as default display */
2481 ovl = omap_dss_get_overlay(0);
2482 if (ovl->manager && ovl->manager->device) {
2483 def_display = ovl->manager->device;
2484 } else {
2485 dev_warn(&pdev->dev, "cannot find default display\n");
2486 def_display = NULL;
2487 }
2488
2405 if (def_mode && strlen(def_mode) > 0) { 2489 if (def_mode && strlen(def_mode) > 0) {
2406 if (omapfb_parse_def_modes(fbdev)) 2490 if (omapfb_parse_def_modes(fbdev))
2407 dev_warn(&pdev->dev, "cannot parse default modes\n"); 2491 dev_warn(&pdev->dev, "cannot parse default modes\n");
2492 } else if (def_display && def_display->driver->set_timings &&
2493 def_display->driver->check_timings) {
2494 struct omap_video_timings t;
2495
2496 r = omapfb_find_best_mode(def_display, &t);
2497
2498 if (r == 0)
2499 def_display->driver->set_timings(def_display, &t);
2408 } 2500 }
2409 2501
2410 r = omapfb_create_framebuffers(fbdev); 2502 r = omapfb_create_framebuffers(fbdev);
@@ -2421,16 +2513,6 @@ static int omapfb_probe(struct platform_device *pdev)
2421 2513
2422 DBG("mgr->apply'ed\n"); 2514 DBG("mgr->apply'ed\n");
2423 2515
2424 /* gfx overlay should be the default one. find a display
2425 * connected to that, and use it as default display */
2426 ovl = omap_dss_get_overlay(0);
2427 if (ovl->manager && ovl->manager->device) {
2428 def_display = ovl->manager->device;
2429 } else {
2430 dev_warn(&pdev->dev, "cannot find default display\n");
2431 def_display = NULL;
2432 }
2433
2434 if (def_display) { 2516 if (def_display) {
2435 r = omapfb_init_display(fbdev, def_display); 2517 r = omapfb_init_display(fbdev, def_display);
2436 if (r) { 2518 if (r) {
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 153bf1aceebc..1694d5148f32 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -104,16 +104,14 @@ static ssize_t store_mirror(struct device *dev,
104{ 104{
105 struct fb_info *fbi = dev_get_drvdata(dev); 105 struct fb_info *fbi = dev_get_drvdata(dev);
106 struct omapfb_info *ofbi = FB2OFB(fbi); 106 struct omapfb_info *ofbi = FB2OFB(fbi);
107 int mirror; 107 bool mirror;
108 int r; 108 int r;
109 struct fb_var_screeninfo new_var; 109 struct fb_var_screeninfo new_var;
110 110
111 r = kstrtoint(buf, 0, &mirror); 111 r = strtobool(buf, &mirror);
112 if (r) 112 if (r)
113 return r; 113 return r;
114 114
115 mirror = !!mirror;
116
117 if (!lock_fb_info(fbi)) 115 if (!lock_fb_info(fbi))
118 return -ENODEV; 116 return -ENODEV;
119 117