diff options
author | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2011-10-14 20:19:52 -0400 |
---|---|---|
committer | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2011-10-14 20:19:52 -0400 |
commit | ef26b7943c5821aaff1efc14c098840c49fe15c0 (patch) | |
tree | a91834ef396633c5c56a0597c2fc525e0684fc30 /drivers/video | |
parent | 07aaae44f5a3962c3a410a6dd7936dfa7dece2b9 (diff) | |
parent | 3e28189038bb831512cf4f8313e1aead97c3e63f (diff) |
Merge branch 'for-florian' of git://gitorious.org/linux-omap-dss2/linux into fbdev-next
Diffstat (limited to 'drivers/video')
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 | ||
12 | config 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. | ||
20 | choice | ||
21 | depends on FB_OMAP && MACH_OVERO | ||
22 | prompt "Screen resolution" | ||
23 | default FB_OMAP_079M3R | ||
24 | help | ||
25 | Selected desired screen resolution | ||
26 | |||
27 | config FB_OMAP_031M3R | ||
28 | boolean "640 x 480 @ 60 Hz Reduced blanking" | ||
29 | |||
30 | config FB_OMAP_048M3R | ||
31 | boolean "800 x 600 @ 60 Hz Reduced blanking" | ||
32 | |||
33 | config FB_OMAP_079M3R | ||
34 | boolean "1024 x 768 @ 60 Hz Reduced blanking" | ||
35 | |||
36 | config FB_OMAP_092M9R | ||
37 | boolean "1280 x 720 @ 60 Hz Reduced blanking" | ||
38 | |||
39 | endchoice | ||
40 | |||
41 | config FB_OMAP_LCDC_EXTERNAL | 12 | config 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 | |||
17 | objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o | 17 | objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o |
18 | 18 | ||
19 | objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o | 19 | objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o |
20 | objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o | ||
21 | objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o | 20 | objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o |
22 | objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o | 21 | objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o |
23 | objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o | 22 | objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o |
@@ -26,14 +25,7 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o | |||
26 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o | 25 | objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o |
27 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o | 26 | objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o |
28 | 27 | ||
29 | objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o | ||
30 | objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o | ||
31 | objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o | ||
32 | objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o | ||
33 | objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o | ||
34 | objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o | ||
35 | objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o | 28 | objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o |
36 | objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o | ||
37 | objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o | 29 | objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o |
38 | 30 | ||
39 | omapfb-objs := $(objs-yy) | 31 | omapfb-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 | |||
40 | static unsigned backlight_gpio; | ||
41 | static 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 | |||
58 | static 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 | |||
77 | static void sdp2430_panel_cleanup(struct lcd_panel *panel) | ||
78 | { | ||
79 | gpio_free(backlight_gpio); | ||
80 | gpio_free(enable_gpio); | ||
81 | } | ||
82 | |||
83 | static 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 | |||
118 | static 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 | |||
129 | static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel) | ||
130 | { | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | struct 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 | |||
159 | static int sdp2430_panel_probe(struct platform_device *pdev) | ||
160 | { | ||
161 | omapfb_register_panel(&sdp2430_panel); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int sdp2430_panel_remove(struct platform_device *pdev) | ||
166 | { | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int sdp2430_panel_suspend(struct platform_device *pdev, | ||
171 | pm_message_t mesg) | ||
172 | { | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int sdp2430_panel_resume(struct platform_device *pdev) | ||
177 | { | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | struct 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 | |||
192 | static int __init sdp2430_panel_drv_init(void) | ||
193 | { | ||
194 | return platform_driver_register(&sdp2430_panel_driver); | ||
195 | } | ||
196 | |||
197 | static void __exit sdp2430_panel_drv_exit(void) | ||
198 | { | ||
199 | platform_driver_unregister(&sdp2430_panel_driver); | ||
200 | } | ||
201 | |||
202 | module_init(sdp2430_panel_drv_init); | ||
203 | module_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 | |||
33 | static int apollon_panel_init(struct lcd_panel *panel, | ||
34 | struct omapfb_device *fbdev) | ||
35 | { | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static void apollon_panel_cleanup(struct lcd_panel *panel) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | static int apollon_panel_enable(struct lcd_panel *panel) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static void apollon_panel_disable(struct lcd_panel *panel) | ||
49 | { | ||
50 | } | ||
51 | |||
52 | static unsigned long apollon_panel_get_caps(struct lcd_panel *panel) | ||
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | struct 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 | |||
92 | static int apollon_panel_probe(struct platform_device *pdev) | ||
93 | { | ||
94 | omapfb_register_panel(&apollon_panel); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int apollon_panel_remove(struct platform_device *pdev) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int apollon_panel_suspend(struct platform_device *pdev, | ||
104 | pm_message_t mesg) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int apollon_panel_resume(struct platform_device *pdev) | ||
110 | { | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | struct 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 | |||
125 | static int __init apollon_panel_drv_init(void) | ||
126 | { | ||
127 | return platform_driver_register(&apollon_panel_driver); | ||
128 | } | ||
129 | |||
130 | static void __exit apollon_panel_drv_exit(void) | ||
131 | { | ||
132 | platform_driver_unregister(&apollon_panel_driver); | ||
133 | } | ||
134 | |||
135 | module_init(apollon_panel_drv_init); | ||
136 | module_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 | |||
27 | static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) | ||
28 | { | ||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | static void h4_panel_cleanup(struct lcd_panel *panel) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | static int h4_panel_enable(struct lcd_panel *panel) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static void h4_panel_disable(struct lcd_panel *panel) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | static unsigned long h4_panel_get_caps(struct lcd_panel *panel) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static 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 | |||
73 | static int h4_panel_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | omapfb_register_panel(&h4_panel); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int h4_panel_remove(struct platform_device *pdev) | ||
80 | { | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
85 | { | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int h4_panel_resume(struct platform_device *pdev) | ||
90 | { | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static 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 | |||
105 | static int __init h4_panel_drv_init(void) | ||
106 | { | ||
107 | return platform_driver_register(&h4_panel_driver); | ||
108 | } | ||
109 | |||
110 | static void __exit h4_panel_drv_cleanup(void) | ||
111 | { | ||
112 | platform_driver_unregister(&h4_panel_driver); | ||
113 | } | ||
114 | |||
115 | module_init(h4_panel_drv_init); | ||
116 | module_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 | |||
65 | static 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 | |||
88 | static 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 | |||
96 | static 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 | |||
118 | static 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 | |||
128 | static unsigned long ldp_panel_get_caps(struct lcd_panel *panel) | ||
129 | { | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | struct 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 | |||
158 | static int ldp_panel_probe(struct platform_device *pdev) | ||
159 | { | ||
160 | omapfb_register_panel(&ldp_panel); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int ldp_panel_remove(struct platform_device *pdev) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
170 | { | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int ldp_panel_resume(struct platform_device *pdev) | ||
175 | { | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | struct 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 | |||
190 | static int __init ldp_panel_drv_init(void) | ||
191 | { | ||
192 | return platform_driver_register(&ldp_panel_driver); | ||
193 | } | ||
194 | |||
195 | static void __exit ldp_panel_drv_exit(void) | ||
196 | { | ||
197 | platform_driver_unregister(&ldp_panel_driver); | ||
198 | } | ||
199 | |||
200 | module_init(ldp_panel_drv_init); | ||
201 | module_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 | |||
34 | static 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 | |||
41 | static void omap3beagle_panel_cleanup(struct lcd_panel *panel) | ||
42 | { | ||
43 | gpio_free(LCD_PANEL_ENABLE_GPIO); | ||
44 | } | ||
45 | |||
46 | static int omap3beagle_panel_enable(struct lcd_panel *panel) | ||
47 | { | ||
48 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static void omap3beagle_panel_disable(struct lcd_panel *panel) | ||
53 | { | ||
54 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); | ||
55 | } | ||
56 | |||
57 | static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | struct 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 | |||
86 | static int omap3beagle_panel_probe(struct platform_device *pdev) | ||
87 | { | ||
88 | omapfb_register_panel(&omap3beagle_panel); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int omap3beagle_panel_remove(struct platform_device *pdev) | ||
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int omap3beagle_panel_suspend(struct platform_device *pdev, | ||
98 | pm_message_t mesg) | ||
99 | { | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static int omap3beagle_panel_resume(struct platform_device *pdev) | ||
104 | { | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | struct 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 | |||
119 | static int __init omap3beagle_panel_drv_init(void) | ||
120 | { | ||
121 | return platform_driver_register(&omap3beagle_panel_driver); | ||
122 | } | ||
123 | |||
124 | static void __exit omap3beagle_panel_drv_exit(void) | ||
125 | { | ||
126 | platform_driver_unregister(&omap3beagle_panel_driver); | ||
127 | } | ||
128 | |||
129 | module_init(omap3beagle_panel_drv_init); | ||
130 | module_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 | |||
49 | static unsigned int bklight_level; | ||
50 | |||
51 | static 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 | |||
74 | static 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 | |||
83 | static int omap3evm_panel_enable(struct lcd_panel *panel) | ||
84 | { | ||
85 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static void omap3evm_panel_disable(struct lcd_panel *panel) | ||
90 | { | ||
91 | gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); | ||
92 | } | ||
93 | |||
94 | static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static 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 | |||
111 | static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel) | ||
112 | { | ||
113 | return bklight_level; | ||
114 | } | ||
115 | |||
116 | static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel) | ||
117 | { | ||
118 | return 100; | ||
119 | } | ||
120 | |||
121 | struct 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 | |||
149 | static int omap3evm_panel_probe(struct platform_device *pdev) | ||
150 | { | ||
151 | omapfb_register_panel(&omap3evm_panel); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int omap3evm_panel_remove(struct platform_device *pdev) | ||
156 | { | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int omap3evm_panel_suspend(struct platform_device *pdev, | ||
161 | pm_message_t mesg) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int omap3evm_panel_resume(struct platform_device *pdev) | ||
167 | { | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | struct 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 | |||
182 | static int __init omap3evm_panel_drv_init(void) | ||
183 | { | ||
184 | return platform_driver_register(&omap3evm_panel_driver); | ||
185 | } | ||
186 | |||
187 | static void __exit omap3evm_panel_drv_exit(void) | ||
188 | { | ||
189 | platform_driver_unregister(&omap3evm_panel_driver); | ||
190 | } | ||
191 | |||
192 | module_init(omap3evm_panel_drv_init); | ||
193 | module_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 | |||
34 | static 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 | |||
46 | static void overo_panel_cleanup(struct lcd_panel *panel) | ||
47 | { | ||
48 | gpio_free(LCD_ENABLE); | ||
49 | } | ||
50 | |||
51 | static int overo_panel_enable(struct lcd_panel *panel) | ||
52 | { | ||
53 | gpio_set_value(LCD_ENABLE, 1); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void overo_panel_disable(struct lcd_panel *panel) | ||
58 | { | ||
59 | gpio_set_value(LCD_ENABLE, 0); | ||
60 | } | ||
61 | |||
62 | static unsigned long overo_panel_get_caps(struct lcd_panel *panel) | ||
63 | { | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | struct 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 | |||
148 | static int overo_panel_probe(struct platform_device *pdev) | ||
149 | { | ||
150 | omapfb_register_panel(&overo_panel); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int overo_panel_remove(struct platform_device *pdev) | ||
155 | { | ||
156 | /* omapfb does not have unregister_panel */ | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static 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 | |||
169 | static int __init overo_panel_drv_init(void) | ||
170 | { | ||
171 | return platform_driver_register(&overo_panel_driver); | ||
172 | } | ||
173 | |||
174 | static void __exit overo_panel_drv_exit(void) | ||
175 | { | ||
176 | platform_driver_unregister(&overo_panel_driver); | ||
177 | } | ||
178 | |||
179 | module_init(overo_panel_drv_init); | ||
180 | module_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 | ||
13 | config 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 | |||
13 | config PANEL_LGPHILIPS_LB035Q02 | 20 | config 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 | |||
19 | config PANEL_SHARP_LS037V7DW01 | 26 | config 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 | ||
26 | config PANEL_NEC_NL8048HL11_01B | 33 | config 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 | ||
42 | config 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 | |||
33 | config PANEL_TAAL | 49 | config 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 | |||
45 | config PANEL_ACX565AKM | 62 | config 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 | |||
69 | config 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 | ||
51 | endmenu | 75 | endmenu |
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 @@ | |||
1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o | 1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o |
2 | obj-$(CONFIG_PANEL_DVI) += panel-dvi.o | ||
2 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o | 3 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o |
3 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o | 4 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o |
4 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o | 5 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o |
5 | 6 | ||
6 | obj-$(CONFIG_PANEL_TAAL) += panel-taal.o | 7 | obj-$(CONFIG_PANEL_TAAL) += panel-taal.o |
8 | obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o | ||
7 | obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o | 9 | obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o |
8 | obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o | 10 | obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o |
11 | obj-$(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 | |||
28 | static 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 | |||
43 | struct panel_drv_data { | ||
44 | struct omap_dss_device *dssdev; | ||
45 | |||
46 | struct mutex lock; | ||
47 | }; | ||
48 | |||
49 | static inline struct panel_dvi_platform_data | ||
50 | *get_pdata(const struct omap_dss_device *dssdev) | ||
51 | { | ||
52 | return dssdev->data; | ||
53 | } | ||
54 | |||
55 | static 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; | ||
74 | err1: | ||
75 | omapdss_dpi_display_disable(dssdev); | ||
76 | err0: | ||
77 | return r; | ||
78 | } | ||
79 | |||
80 | static 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 | |||
93 | static 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 | |||
112 | static 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 | |||
125 | static 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 | |||
141 | static 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 | |||
154 | static 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 | |||
169 | static 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 | |||
185 | static 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 | |||
195 | static 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 | |||
205 | static 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 | |||
219 | static 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 | |||
250 | static 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 | |||
296 | err: | ||
297 | mutex_unlock(&ddata->lock); | ||
298 | return r; | ||
299 | } | ||
300 | |||
301 | static 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 | |||
324 | out: | ||
325 | mutex_unlock(&ddata->lock); | ||
326 | return true; | ||
327 | } | ||
328 | |||
329 | static 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 | |||
351 | static int __init panel_dvi_init(void) | ||
352 | { | ||
353 | return omap_dss_register_driver(&panel_dvi_driver); | ||
354 | } | ||
355 | |||
356 | static void __exit panel_dvi_exit(void) | ||
357 | { | ||
358 | omap_dss_unregister_driver(&panel_dvi_driver); | ||
359 | } | ||
360 | |||
361 | module_init(panel_dvi_init); | ||
362 | module_exit(panel_dvi_exit); | ||
363 | MODULE_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 */ |
60 | static struct panel_config generic_dpi_panels[] = { | 60 | static 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 | ||
237 | struct panel_drv_data { | 302 | struct 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 | |||
67 | static 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 | |||
78 | static inline | ||
79 | struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev) | ||
80 | { | ||
81 | return dssdev->data; | ||
82 | } | ||
83 | |||
84 | static inline | ||
85 | struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev) | ||
86 | { | ||
87 | return &s_drv_data; | ||
88 | } | ||
89 | |||
90 | |||
91 | static inline void blizzard_cmd(u8 cmd) | ||
92 | { | ||
93 | omap_rfbi_write_command(&cmd, 1); | ||
94 | } | ||
95 | |||
96 | static 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 | |||
102 | static 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 | |||
108 | static u8 blizzard_read_reg(u8 cmd) | ||
109 | { | ||
110 | u8 data; | ||
111 | blizzard_read(cmd, &data, 1); | ||
112 | return data; | ||
113 | } | ||
114 | |||
115 | static 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 | |||
160 | static 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 | |||
215 | static inline void mipid_cmd(struct spi_device *spi, int cmd) | ||
216 | { | ||
217 | mipid_transfer(spi, cmd, NULL, 0, NULL, 0); | ||
218 | } | ||
219 | |||
220 | static 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 | |||
226 | static 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 | |||
232 | static 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 | |||
251 | static 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 | |||
257 | static void send_display_on(struct spi_device *spi) | ||
258 | { | ||
259 | mipid_cmd(spi, MIPID_CMD_DISP_ON); | ||
260 | } | ||
261 | |||
262 | static void send_display_off(struct spi_device *spi) | ||
263 | { | ||
264 | mipid_cmd(spi, MIPID_CMD_DISP_OFF); | ||
265 | } | ||
266 | |||
267 | static void send_sleep_out(struct spi_device *spi) | ||
268 | { | ||
269 | mipid_cmd(spi, MIPID_CMD_SLEEP_OUT); | ||
270 | msleep(120); | ||
271 | } | ||
272 | |||
273 | static void send_sleep_in(struct spi_device *spi) | ||
274 | { | ||
275 | mipid_cmd(spi, MIPID_CMD_SLEEP_IN); | ||
276 | msleep(50); | ||
277 | } | ||
278 | |||
279 | static 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 | |||
356 | err_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); */ | ||
363 | err_inv_chip: | ||
364 | omapdss_rfbi_display_disable(dssdev); | ||
365 | err_rfbi_en: | ||
366 | if (bdata->platform_disable) | ||
367 | bdata->platform_disable(dssdev); | ||
368 | err_plat_en: | ||
369 | gpio_direction_output(bdata->ctrl_pwrdown, 0); | ||
370 | return r; | ||
371 | } | ||
372 | |||
373 | static 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 | |||
398 | static 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 | |||
415 | static 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 | |||
443 | static 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 | |||
452 | static const struct backlight_ops n8x0_bl_ops = { | ||
453 | .get_brightness = n8x0_bl_get_intensity, | ||
454 | .update_status = n8x0_bl_update_status, | ||
455 | }; | ||
456 | |||
457 | static 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 | |||
504 | static 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 | |||
519 | static 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 | |||
546 | static 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 | |||
565 | static 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 | |||
586 | static 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 | |||
613 | static void n8x0_panel_get_timings(struct omap_dss_device *dssdev, | ||
614 | struct omap_video_timings *timings) | ||
615 | { | ||
616 | *timings = dssdev->panel.timings; | ||
617 | } | ||
618 | |||
619 | static 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 | |||
626 | static void update_done(void *data) | ||
627 | { | ||
628 | rfbi_bus_unlock(); | ||
629 | } | ||
630 | |||
631 | static 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 | |||
652 | static 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 | |||
666 | static 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 | |||
691 | static 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 | |||
702 | static int mipid_spi_remove(struct spi_device *spi) | ||
703 | { | ||
704 | dev_dbg(&spi->dev, "mipid_spi_remove\n"); | ||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | static 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 | |||
718 | static 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 | |||
738 | static 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 | |||
745 | module_init(n8x0_panel_drv_init); | ||
746 | module_exit(n8x0_panel_drv_exit); | ||
747 | MODULE_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 | |||
38 | struct picodlp_data { | ||
39 | struct mutex lock; | ||
40 | struct i2c_client *picodlp_i2c_client; | ||
41 | }; | ||
42 | |||
43 | static struct i2c_board_info picodlp_i2c_board_info = { | ||
44 | I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b), | ||
45 | }; | ||
46 | |||
47 | struct picodlp_i2c_data { | ||
48 | struct mutex xfer_lock; | ||
49 | }; | ||
50 | |||
51 | static struct i2c_device_id picodlp_i2c_id[] = { | ||
52 | { "picodlp_i2c_driver", 0 }, | ||
53 | }; | ||
54 | |||
55 | struct picodlp_i2c_command { | ||
56 | u8 reg; | ||
57 | u32 value; | ||
58 | }; | ||
59 | |||
60 | static 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 | |||
74 | static 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 | |||
80 | static 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 | |||
103 | static 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; | ||
140 | err: | ||
141 | dev_err(&client->dev, "picodlp_i2c_write error\n"); | ||
142 | return r; | ||
143 | } | ||
144 | |||
145 | static 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 | |||
157 | static 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 | |||
171 | static 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 | */ | ||
192 | static 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 | |||
311 | static 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 | |||
327 | static 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 | |||
335 | static 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 | |||
344 | static 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; | ||
387 | err: | ||
388 | omapdss_dpi_display_disable(dssdev); | ||
389 | err1: | ||
390 | if (dssdev->platform_disable) | ||
391 | dssdev->platform_disable(dssdev); | ||
392 | |||
393 | return r; | ||
394 | } | ||
395 | |||
396 | static 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 | |||
409 | static 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; | ||
449 | err: | ||
450 | kfree(picod); | ||
451 | return r; | ||
452 | } | ||
453 | |||
454 | static 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 | |||
465 | static 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 | |||
484 | static 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 | |||
499 | static 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 | |||
521 | static 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 | |||
540 | static 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 | |||
547 | static 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 | |||
565 | static 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 | |||
583 | static void __exit picodlp_exit(void) | ||
584 | { | ||
585 | i2c_del_driver(&picodlp_i2c_driver); | ||
586 | omap_dss_unregister_driver(&picodlp_driver); | ||
587 | } | ||
588 | |||
589 | module_init(picodlp_init); | ||
590 | module_exit(picodlp_exit); | ||
591 | |||
592 | MODULE_AUTHOR("Mythri P K <mythripk@ti.com>"); | ||
593 | MODULE_DESCRIPTION("picodlp driver"); | ||
594 | MODULE_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 | ||
396 | static int taal_set_update_window(struct taal_data *td, | 380 | static 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); |
1113 | err_gpio: | 1080 | err_gpio: |
1114 | backlight_device_unregister(bldev); | 1081 | if (bldev != NULL) |
1082 | backlight_device_unregister(bldev); | ||
1115 | err_bl: | 1083 | err_bl: |
1116 | destroy_workqueue(td->workqueue); | 1084 | destroy_workqueue(td->workqueue); |
1117 | err_wq: | 1085 | err_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 @@ | |||
1 | menuconfig OMAP2_DSS | 1 | menuconfig 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 | |||
6 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 6 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
7 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 7 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
8 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ | 8 | omapdss-$(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 | ||
172 | static void dispc_save_context(void) | 172 | static 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 | ||
350 | static void dispc_restore_context(void) | 276 | static 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 | ||
423 | static 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 | |||
432 | static 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 | ||
574 | bool dispc_go_busy(enum omap_channel channel) | 437 | return mgr ? mgr->device : NULL; |
438 | } | ||
439 | |||
440 | bool 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 | ||
590 | void dispc_go(enum omap_channel channel) | 455 | void 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 | ||
635 | static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) | 498 | static 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 | ||
640 | static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value) | 503 | static 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 | ||
645 | static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value) | 508 | static 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 | ||
650 | static void _dispc_write_firh2_reg(enum omap_plane plane, int reg, u32 value) | 513 | static 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 | ||
657 | static void _dispc_write_firhv2_reg(enum omap_plane plane, int reg, u32 value) | 520 | static 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 | ||
664 | static void _dispc_write_firv2_reg(enum omap_plane plane, int reg, u32 value) | 528 | static 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 | ||
671 | static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup, | 535 | static 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 | ||
794 | static void _dispc_setup_color_conv_coef(void) | 658 | static 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 | ||
840 | static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr) | 694 | static 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 | ||
845 | static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr) | 699 | static 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 | ||
850 | static void _dispc_set_plane_ba0_uv(enum omap_plane plane, u32 paddr) | 704 | static 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 | ||
855 | static void _dispc_set_plane_ba1_uv(enum omap_plane plane, u32 paddr) | 709 | static 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 | ||
860 | static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y) | 714 | static 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 | ||
867 | static void _dispc_set_pic_size(enum omap_plane plane, int width, int height) | 721 | static 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 | ||
877 | static void _dispc_set_vid_size(enum omap_plane plane, int width, int height) | 731 | static 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 | ||
888 | static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable) | 742 | static 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 | |||
752 | static 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 | ||
900 | static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) | 763 | static 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 | |||
773 | static 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 | ||
915 | static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc) | 786 | static 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 | ||
920 | static void _dispc_set_row_inc(enum omap_plane plane, s32 inc) | 791 | static 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 | ||
925 | static void _dispc_set_color_mode(enum omap_plane plane, | 796 | static 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 | ||
1006 | void dispc_set_channel_out(enum omap_plane plane, | 877 | static 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 | ||
1053 | static void dispc_set_burst_size(enum omap_plane plane, | 925 | static 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 | ||
1084 | u32 dispc_get_burst_size(enum omap_plane plane) | 945 | u32 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 | ||
1105 | void dispc_enable_cpr(enum omap_channel channel, bool enable) | 966 | void 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 | ||
1119 | void dispc_set_cpr_coef(enum omap_channel channel, | 980 | void 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 | ||
1139 | static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) | 1000 | static 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 | ||
1150 | void dispc_enable_replication(enum omap_plane plane, bool enable) | 1011 | static 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 | ||
1162 | void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height) | 1020 | void 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 | ||
1196 | u32 dispc_get_plane_fifo_size(enum omap_plane plane) | 1054 | u32 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 | ||
1201 | void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) | 1059 | static 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 | ||
1236 | static void _dispc_set_fir(enum omap_plane plane, | 1095 | static 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 | ||
1259 | static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) | 1118 | static 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 | ||
1273 | static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) | 1132 | static 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 | ||
1287 | static void _dispc_set_vid_accu2_0(enum omap_plane plane, int haccu, int vaccu) | 1146 | static 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 | ||
1295 | static void _dispc_set_vid_accu2_1(enum omap_plane plane, int haccu, int vaccu) | 1155 | static 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 | ||
1303 | static void _dispc_set_scale_param(enum omap_plane plane, | 1164 | static 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 | ||
1323 | static void _dispc_set_scaling_common(enum omap_plane plane, | 1185 | static 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 | ||
1377 | static void _dispc_set_scaling_uv(enum omap_plane plane, | 1239 | static 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 | ||
1440 | static void _dispc_set_scaling(enum omap_plane plane, | 1302 | static 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 | ||
1464 | static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, | 1326 | static 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 | ||
1853 | int dispc_setup_plane(enum omap_plane plane, | 1713 | static 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 || | 1773 | int 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 | ||
2028 | int dispc_enable_plane(enum omap_plane plane, bool enable) | 1902 | int 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 | ||
2051 | static void dispc_enable_lcd_out(enum omap_channel channel, bool enable) | 1925 | static 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 | ||
2098 | static void dispc_enable_digit_out(bool enable) | 1972 | static 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 | ||
2158 | bool dispc_is_channel_enabled(enum omap_channel channel) | 2041 | bool 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 | ||
2170 | void dispc_enable_channel(enum omap_channel channel, bool enable) | 2053 | void 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 | ||
2205 | void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) | 2087 | void 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 | ||
2214 | void dispc_set_lcd_display_type(enum omap_channel channel, | 2096 | void 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 | ||
2245 | void dispc_set_default_color(enum omap_channel channel, u32 color) | 2127 | void 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 | ||
2250 | u32 dispc_get_default_color(enum omap_channel channel) | 2132 | u32 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 | ||
2263 | void dispc_set_trans_key(enum omap_channel ch, | 2145 | void 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 | ||
2277 | void dispc_get_trans_key(enum omap_channel ch, | 2159 | void 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 | ||
2296 | void dispc_enable_trans_key(enum omap_channel ch, bool enable) | 2178 | void 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 | } |
2305 | void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) | 2187 | |
2188 | void 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 | } |
2317 | bool dispc_alpha_blending_enabled(enum omap_channel ch) | 2198 | |
2199 | bool 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 | 2216 | bool dispc_mgr_trans_key_enabled(enum omap_channel ch) | |
2337 | bool 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 | ||
2354 | void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines) | 2233 | void 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 | ||
2382 | void dispc_set_parallel_interface_mode(enum omap_channel channel, | 2261 | void 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); | 2290 | void 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 | ||
2424 | static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, | 2298 | static 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 | ||
2455 | static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw, | 2329 | static 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? */ |
2479 | void dispc_set_lcd_timings(enum omap_channel channel, | 2353 | void 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 | ||
2512 | static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div, | 2386 | static 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 | ||
2522 | static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, | 2396 | static 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 | ||
2555 | unsigned long dispc_lclk_rate(enum omap_channel channel) | 2429 | unsigned 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 | ||
2585 | unsigned long dispc_pclk_rate(enum omap_channel channel) | 2459 | unsigned 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 | ||
2600 | void dispc_dump_clocks(struct seq_file *s) | 2489 | void 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 | ||
2708 | void dispc_dump_regs(struct seq_file *s) | 2601 | void 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 | ||
2962 | static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf, | 2761 | static 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 | ||
2982 | void dispc_set_pol_freq(enum omap_channel channel, | 2782 | void 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, | |||
2995 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 2795 | void 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 | ||
3054 | int dispc_set_clock_div(enum omap_channel channel, | 2860 | int 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 | ||
3065 | int dispc_get_clock_div(enum omap_channel channel, | 2871 | int 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 | ||
3497 | int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout) | 3199 | int 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) | |||
3734 | static int dispc_runtime_suspend(struct device *dev) | 3440 | static 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 | |||
213 | typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); | 202 | typedef 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 | ||
231 | enum dsi_vc_mode { | 220 | enum 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 | ||
236 | enum dsi_lane { | 225 | enum 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 | ||
371 | static int dsi_get_dsidev_id(struct platform_device *dsidev) | 361 | static 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 | ||
381 | static inline void dsi_write_reg(struct platform_device *dsidev, | 366 | static 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 | ||
425 | u8 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 |
441 | static void dsi_perf_mark_setup(struct platform_device *dsidev) | 441 | static 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) | |||
453 | static void dsi_perf_show(struct platform_device *dsidev, const char *name) | 453 | static 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 | ||
2364 | static 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 | |||
2363 | static int dsi_cio_init(struct omap_dss_device *dssdev) | 2382 | static 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); |
2468 | err_scp_clk_dom: | 2494 | err_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 | ||
2475 | static void dsi_cio_uninit(struct platform_device *dsidev) | 2500 | static 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 | ||
2485 | static void dsi_config_tx_fifo(struct platform_device *dsidev, | 2513 | static 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 | ||
2729 | static int dsi_vc_config_l4(struct platform_device *dsidev, int channel) | 2757 | static 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 | |||
2761 | static 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 | |||
2795 | void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | 2793 | void 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 | } |
2814 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); | 2816 | EXPORT_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, | |||
3085 | int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) | 3087 | int 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 | } |
3093 | EXPORT_SYMBOL(dsi_vc_send_null); | 3094 | EXPORT_SYMBOL(dsi_vc_send_null); |
3094 | 3095 | ||
3095 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, | 3096 | static 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 | |||
3127 | int 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 | } | ||
3117 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | 3133 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); |
3118 | 3134 | ||
3119 | int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, | 3135 | int 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 | } | ||
3141 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); | ||
3142 | |||
3143 | static 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; |
3142 | err: | 3166 | err: |
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 | |||
3172 | int 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 | } | ||
3147 | EXPORT_SYMBOL(dsi_vc_dcs_write); | 3178 | EXPORT_SYMBOL(dsi_vc_dcs_write); |
3148 | 3179 | ||
3180 | int 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 | } | ||
3186 | EXPORT_SYMBOL(dsi_vc_generic_write); | ||
3187 | |||
3149 | int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd) | 3188 | int 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 | } |
3153 | EXPORT_SYMBOL(dsi_vc_dcs_write_0); | 3192 | EXPORT_SYMBOL(dsi_vc_dcs_write_0); |
3154 | 3193 | ||
3194 | int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel) | ||
3195 | { | ||
3196 | return dsi_vc_generic_write(dssdev, channel, NULL, 0); | ||
3197 | } | ||
3198 | EXPORT_SYMBOL(dsi_vc_generic_write_0); | ||
3199 | |||
3155 | int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | 3200 | int 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 | } |
3163 | EXPORT_SYMBOL(dsi_vc_dcs_write_1); | 3208 | EXPORT_SYMBOL(dsi_vc_dcs_write_1); |
3164 | 3209 | ||
3165 | int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | 3210 | int 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, ¶m, 1); | ||
3214 | } | ||
3215 | EXPORT_SYMBOL(dsi_vc_generic_write_1); | ||
3216 | |||
3217 | int 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 | } | ||
3225 | EXPORT_SYMBOL(dsi_vc_generic_write_2); | ||
3226 | |||
3227 | static 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 | |
3248 | static 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 | |||
3284 | static 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(); |
3268 | err: | 3387 | err: |
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 | ||
3394 | int 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; | ||
3419 | err: | ||
3420 | DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd); | ||
3421 | return r; | ||
3273 | } | 3422 | } |
3274 | EXPORT_SYMBOL(dsi_vc_dcs_read); | 3423 | EXPORT_SYMBOL(dsi_vc_dcs_read); |
3275 | 3424 | ||
3276 | int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | 3425 | static 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 | } |
3291 | EXPORT_SYMBOL(dsi_vc_dcs_read_1); | ||
3292 | 3451 | ||
3293 | int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | 3452 | int 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 | } | ||
3465 | EXPORT_SYMBOL(dsi_vc_generic_read_0); | ||
3466 | |||
3467 | int 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, ¶m, 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 | } |
3480 | EXPORT_SYMBOL(dsi_vc_generic_read_1); | ||
3306 | 3481 | ||
3307 | *data1 = buf[0]; | 3482 | int 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 | } |
3312 | EXPORT_SYMBOL(dsi_vc_dcs_read_2); | 3499 | EXPORT_SYMBOL(dsi_vc_generic_read_2); |
3313 | 3500 | ||
3314 | int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, | 3501 | int 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 | } |
3322 | EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); | 3509 | EXPORT_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 | |||
3699 | static 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 | |||
3725 | static 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 | |||
3746 | static 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 | |||
3511 | static int dsi_proto_config(struct omap_dss_device *dssdev) | 3767 | static 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) \ | 3947 | int 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 | |||
3656 | static 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 | } | ||
3988 | EXPORT_SYMBOL(dsi_video_mode_enable); | ||
3771 | 3989 | ||
3772 | while (pixels-- > 0) { | 3990 | void 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 | } |
4005 | EXPORT_SYMBOL(dsi_video_mode_disable); | ||
3791 | 4006 | ||
3792 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | 4007 | static 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); | |||
4013 | static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | 4215 | static 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 | ||
4053 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | 4259 | static 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 | ||
4064 | static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) | 4272 | static 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; |
4168 | err3: | 4376 | err3: |
4169 | dsi_cio_uninit(dsidev); | 4377 | dsi_cio_uninit(dssdev); |
4170 | err2: | 4378 | err2: |
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 | |||
4173 | err1: | 4383 | err1: |
4174 | dsi_pll_uninit(dsidev, true); | 4384 | dsi_pll_uninit(dsidev, true); |
4175 | err0: | 4385 | err0: |
@@ -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 */ |
4465 | static int omap_dsi1hw_probe(struct platform_device *dsidev) | 4680 | static 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 | ||
4575 | static int omap_dsi1hw_remove(struct platform_device *dsidev) | 4791 | static 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 | ||
4603 | static int dsi_runtime_suspend(struct device *dev) | 4819 | static 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 | ||
4615 | static int dsi_runtime_resume(struct device *dev) | 4827 | static 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 | ||
4632 | err_get_dispc: | 4841 | err_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 | ||
4643 | static struct platform_driver omap_dsi1hw_driver = { | 4852 | static 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 | ||
4653 | int dsi_init_platform_driver(void) | 4862 | int 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 | ||
4658 | void dsi_uninit_platform_driver(void) | 4867 | void 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 | ||
642 | enum 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 | |||
642 | static int dss_get_clocks(void) | 653 | static 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 | ||
694 | struct clk *dss_get_ick(void) | ||
695 | { | ||
696 | return clk_get(&dss.pdev->dev, "ick"); | ||
697 | } | ||
698 | |||
699 | int dss_runtime_get(void) | 705 | int 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) | |||
824 | static int dss_runtime_suspend(struct device *dev) | 830 | static 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 | ||
831 | static int dss_runtime_resume(struct device *dev) | 836 | static 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 | ||
100 | enum omap_parallel_interface_mode { | 100 | enum 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 | ||
106 | enum dss_hdmi_venc_clk_source_select { | 106 | enum 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 | ||
111 | enum dss_dsi_content_type { | ||
112 | DSS_DSI_CONTENT_DCS, | ||
113 | DSS_DSI_CONTENT_GENERIC, | ||
114 | }; | ||
115 | |||
111 | struct dss_clock_info { | 116 | struct 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 */ | ||
154 | struct hdmi_pll_info { | ||
155 | u16 regn; | ||
156 | u16 regm; | ||
157 | u32 regmf; | ||
158 | u16 regm2; | ||
159 | u16 regsd; | ||
160 | u16 dcofreq; | ||
161 | }; | ||
162 | |||
163 | struct seq_file; | 158 | struct seq_file; |
164 | struct platform_device; | 159 | struct platform_device; |
165 | 160 | ||
@@ -209,9 +204,8 @@ void dss_uninit_platform_driver(void); | |||
209 | int dss_runtime_get(void); | 204 | int dss_runtime_get(void); |
210 | void dss_runtime_put(void); | 205 | void dss_runtime_put(void); |
211 | 206 | ||
212 | struct clk *dss_get_ick(void); | ||
213 | |||
214 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 207 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
208 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | ||
215 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 209 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); |
216 | void dss_dump_clocks(struct seq_file *s); | 210 | void 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 | ||
280 | int dsi_init_display(struct omap_dss_device *display); | 274 | int dsi_init_display(struct omap_dss_device *display); |
281 | void dsi_irq_handler(void); | 275 | void dsi_irq_handler(void); |
276 | u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); | ||
277 | |||
282 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); | 278 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); |
283 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 279 | int 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) | |||
309 | static inline void dsi_runtime_put(struct platform_device *dsidev) | 305 | static inline void dsi_runtime_put(struct platform_device *dsidev) |
310 | { | 306 | { |
311 | } | 307 | } |
308 | static 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 | } | ||
312 | static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) | 313 | static 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); | |||
385 | void dispc_lcd_enable_signal_polarity(bool act_high); | 386 | void dispc_lcd_enable_signal_polarity(bool act_high); |
386 | void dispc_lcd_enable_signal(bool enable); | 387 | void dispc_lcd_enable_signal(bool enable); |
387 | void dispc_pck_free_enable(bool enable); | 388 | void dispc_pck_free_enable(bool enable); |
388 | void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable); | ||
389 | |||
390 | void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height); | ||
391 | void dispc_set_digit_size(u16 width, u16 height); | 389 | void dispc_set_digit_size(u16 width, u16 height); |
392 | u32 dispc_get_plane_fifo_size(enum omap_plane plane); | ||
393 | void dispc_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); | ||
394 | void dispc_enable_fifomerge(bool enable); | 390 | void dispc_enable_fifomerge(bool enable); |
395 | u32 dispc_get_burst_size(enum omap_plane plane); | ||
396 | void dispc_enable_cpr(enum omap_channel channel, bool enable); | ||
397 | void dispc_set_cpr_coef(enum omap_channel channel, | ||
398 | struct omap_dss_cpr_coefs *coefs); | ||
399 | |||
400 | void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); | ||
401 | void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr); | ||
402 | void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y); | ||
403 | void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); | ||
404 | void dispc_set_channel_out(enum omap_plane plane, | ||
405 | enum omap_channel channel_out); | ||
406 | |||
407 | void dispc_enable_gamma_table(bool enable); | 391 | void dispc_enable_gamma_table(bool enable); |
408 | int 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 | |||
421 | bool dispc_go_busy(enum omap_channel channel); | ||
422 | void dispc_go(enum omap_channel channel); | ||
423 | void dispc_enable_channel(enum omap_channel channel, bool enable); | ||
424 | bool dispc_is_channel_enabled(enum omap_channel channel); | ||
425 | int dispc_enable_plane(enum omap_plane plane, bool enable); | ||
426 | void dispc_enable_replication(enum omap_plane plane, bool enable); | ||
427 | |||
428 | void dispc_set_parallel_interface_mode(enum omap_channel channel, | ||
429 | enum omap_parallel_interface_mode mode); | ||
430 | void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines); | ||
431 | void dispc_set_lcd_display_type(enum omap_channel channel, | ||
432 | enum omap_lcd_display_type type); | ||
433 | void dispc_set_loadmode(enum omap_dss_load_mode mode); | 392 | void dispc_set_loadmode(enum omap_dss_load_mode mode); |
434 | 393 | ||
435 | void dispc_set_default_color(enum omap_channel channel, u32 color); | ||
436 | u32 dispc_get_default_color(enum omap_channel channel); | ||
437 | void dispc_set_trans_key(enum omap_channel ch, | ||
438 | enum omap_dss_trans_key_type type, | ||
439 | u32 trans_key); | ||
440 | void dispc_get_trans_key(enum omap_channel ch, | ||
441 | enum omap_dss_trans_key_type *type, | ||
442 | u32 *trans_key); | ||
443 | void dispc_enable_trans_key(enum omap_channel ch, bool enable); | ||
444 | void dispc_enable_alpha_blending(enum omap_channel ch, bool enable); | ||
445 | bool dispc_trans_key_enabled(enum omap_channel ch); | ||
446 | bool dispc_alpha_blending_enabled(enum omap_channel ch); | ||
447 | |||
448 | bool dispc_lcd_timings_ok(struct omap_video_timings *timings); | 394 | bool dispc_lcd_timings_ok(struct omap_video_timings *timings); |
449 | void dispc_set_lcd_timings(enum omap_channel channel, | ||
450 | struct omap_video_timings *timings); | ||
451 | unsigned long dispc_fclk_rate(void); | 395 | unsigned long dispc_fclk_rate(void); |
452 | unsigned long dispc_lclk_rate(enum omap_channel channel); | ||
453 | unsigned long dispc_pclk_rate(enum omap_channel channel); | ||
454 | void dispc_set_pol_freq(enum omap_channel channel, | ||
455 | enum omap_panel_config config, u8 acbi, u8 acb); | ||
456 | void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, | 396 | void 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); |
458 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, | 398 | int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, |
459 | struct dispc_clock_info *cinfo); | 399 | struct dispc_clock_info *cinfo); |
460 | int dispc_set_clock_div(enum omap_channel channel, | 400 | |
401 | |||
402 | u32 dispc_ovl_get_fifo_size(enum omap_plane plane); | ||
403 | u32 dispc_ovl_get_burst_size(enum omap_plane plane); | ||
404 | int 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); | ||
407 | int dispc_ovl_enable(enum omap_plane plane, bool enable); | ||
408 | |||
409 | |||
410 | void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable); | ||
411 | void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height); | ||
412 | void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable); | ||
413 | void dispc_mgr_set_cpr_coef(enum omap_channel channel, | ||
414 | struct omap_dss_cpr_coefs *coefs); | ||
415 | bool dispc_mgr_go_busy(enum omap_channel channel); | ||
416 | void dispc_mgr_go(enum omap_channel channel); | ||
417 | void dispc_mgr_enable(enum omap_channel channel, bool enable); | ||
418 | bool dispc_mgr_is_channel_enabled(enum omap_channel channel); | ||
419 | void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode); | ||
420 | void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable); | ||
421 | void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines); | ||
422 | void dispc_mgr_set_lcd_display_type(enum omap_channel channel, | ||
423 | enum omap_lcd_display_type type); | ||
424 | void dispc_mgr_set_default_color(enum omap_channel channel, u32 color); | ||
425 | u32 dispc_mgr_get_default_color(enum omap_channel channel); | ||
426 | void dispc_mgr_set_trans_key(enum omap_channel ch, | ||
427 | enum omap_dss_trans_key_type type, | ||
428 | u32 trans_key); | ||
429 | void dispc_mgr_get_trans_key(enum omap_channel ch, | ||
430 | enum omap_dss_trans_key_type *type, | ||
431 | u32 *trans_key); | ||
432 | void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable); | ||
433 | void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable); | ||
434 | bool dispc_mgr_trans_key_enabled(enum omap_channel ch); | ||
435 | bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch); | ||
436 | void dispc_mgr_set_lcd_timings(enum omap_channel channel, | ||
437 | struct omap_video_timings *timings); | ||
438 | void dispc_mgr_set_pol_freq(enum omap_channel channel, | ||
439 | enum omap_panel_config config, u8 acbi, u8 acb); | ||
440 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); | ||
441 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); | ||
442 | int dispc_mgr_set_clock_div(enum omap_channel channel, | ||
461 | struct dispc_clock_info *cinfo); | 443 | struct dispc_clock_info *cinfo); |
462 | int dispc_get_clock_div(enum omap_channel channel, | 444 | int 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 |
468 | int venc_init_platform_driver(void); | 449 | int venc_init_platform_driver(void); |
469 | void venc_uninit_platform_driver(void); | 450 | void venc_uninit_platform_driver(void); |
470 | void venc_dump_regs(struct seq_file *s); | 451 | void venc_dump_regs(struct seq_file *s); |
471 | int venc_init_display(struct omap_dss_device *display); | 452 | int venc_init_display(struct omap_dss_device *display); |
453 | unsigned long venc_get_pixel_clock(void); | ||
472 | #else | 454 | #else |
473 | static inline int venc_init_platform_driver(void) | 455 | static inline int venc_init_platform_driver(void) |
474 | { | 456 | { |
@@ -477,6 +459,11 @@ static inline int venc_init_platform_driver(void) | |||
477 | static inline void venc_uninit_platform_driver(void) | 459 | static inline void venc_uninit_platform_driver(void) |
478 | { | 460 | { |
479 | } | 461 | } |
462 | static 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) | |||
484 | int hdmi_init_platform_driver(void); | 471 | int hdmi_init_platform_driver(void); |
485 | void hdmi_uninit_platform_driver(void); | 472 | void hdmi_uninit_platform_driver(void); |
486 | int hdmi_init_display(struct omap_dss_device *dssdev); | 473 | int hdmi_init_display(struct omap_dss_device *dssdev); |
474 | unsigned long hdmi_get_pixel_clock(void); | ||
475 | void hdmi_dump_regs(struct seq_file *s); | ||
487 | #else | 476 | #else |
488 | static inline int hdmi_init_display(struct omap_dss_device *dssdev) | 477 | static inline int hdmi_init_display(struct omap_dss_device *dssdev) |
489 | { | 478 | { |
@@ -496,12 +485,19 @@ static inline int hdmi_init_platform_driver(void) | |||
496 | static inline void hdmi_uninit_platform_driver(void) | 485 | static inline void hdmi_uninit_platform_driver(void) |
497 | { | 486 | { |
498 | } | 487 | } |
488 | static 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 |
500 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); | 494 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); |
501 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); | 495 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); |
502 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); | 496 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); |
503 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 497 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, |
504 | struct omap_video_timings *timings); | 498 | struct omap_video_timings *timings); |
499 | int omapdss_hdmi_read_edid(u8 *buf, int len); | ||
500 | bool omapdss_hdmi_detect(void); | ||
505 | int hdmi_panel_init(void); | 501 | int hdmi_panel_init(void); |
506 | void hdmi_panel_exit(void); | 502 | void 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 | |||
225 | static 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 | |||
236 | static 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 | |||
247 | static 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 | |||
259 | static 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 | ||
214 | static const char * const omap2_dss_clk_source_names[] = { | 277 | static const char * const omap2_dss_clk_source_names[] = { |
@@ -233,32 +296,38 @@ static const char * const omap4_dss_clk_source_names[] = { | |||
233 | 296 | ||
234 | static const struct dss_param_range omap2_dss_param_range[] = { | 297 | static 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 | ||
244 | static const struct dss_param_range omap3_dss_param_range[] = { | 309 | static 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 | ||
254 | static const struct dss_param_range omap4_dss_param_range[] = { | 321 | static 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*/ | ||
454 | static 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 | |||
471 | void 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 */ |
380 | int dss_feat_get_num_mgrs(void) | 479 | int 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 | ||
509 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane) | ||
510 | { | ||
511 | return omap_current_dss_features->overlay_caps[plane]; | ||
512 | } | ||
513 | |||
410 | bool dss_feat_color_mode_supported(enum omap_plane plane, | 514 | bool 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 */ |
29 | enum dss_feat_id { | 33 | enum 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 | ||
76 | enum dss_range_param { | 79 | enum 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); | |||
90 | unsigned long dss_feat_get_param_max(enum dss_range_param param); | 95 | unsigned long dss_feat_get_param_max(enum dss_range_param param); |
91 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); | 96 | enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); |
92 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); | 97 | enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); |
98 | enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); | ||
93 | bool dss_feat_color_mode_supported(enum omap_plane plane, | 99 | bool dss_feat_color_mode_supported(enum omap_plane plane, |
94 | enum omap_color_mode color_mode); | 100 | enum omap_color_mode color_mode); |
95 | const char *dss_feat_get_clk_source_name(enum omap_dss_clk_source id); | 101 | const 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 */ | |||
100 | bool dss_has_feature(enum dss_feat_id id); | 106 | bool dss_has_feature(enum dss_feat_id id); |
101 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); | 107 | void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); |
102 | void dss_features_init(void); | 108 | void dss_features_init(void); |
109 | #if defined(CONFIG_OMAP4_DSS_HDMI) | ||
110 | void 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 | |||
46 | static struct { | 66 | static 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 | ||
147 | static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0}; | ||
148 | |||
149 | static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val) | ||
150 | { | ||
151 | __raw_writel(val, hdmi.base_wp + idx.idx); | ||
152 | } | ||
153 | |||
154 | static inline u32 hdmi_read_reg(const struct hdmi_reg idx) | ||
155 | { | ||
156 | return __raw_readl(hdmi.base_wp + idx.idx); | ||
157 | } | ||
158 | |||
159 | static 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 | |||
171 | static int hdmi_runtime_get(void) | 162 | static 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 | |||
199 | static 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 */ | ||
262 | static 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 */ | ||
277 | static 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 | |||
291 | static 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 | |||
305 | static 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 | |||
341 | static 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 | |||
367 | static void hdmi_phy_off(void) | ||
368 | { | ||
369 | hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF); | ||
370 | } | ||
371 | |||
372 | static 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 | |||
468 | static 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 | ||
559 | static 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 */ | ||
597 | static 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 | |||
652 | static 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 | |||
682 | static 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 | |||
726 | static 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 | |||
732 | static 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 | |||
738 | static 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 */ | ||
745 | static 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 | |||
784 | static 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 | |||
858 | static 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 | |||
876 | static 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 | |||
901 | static void hdmi_wp_video_start(bool start) | ||
902 | { | ||
903 | REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31); | ||
904 | } | ||
905 | |||
906 | static 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 | |||
922 | static 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 | |||
934 | static 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 | |||
948 | static 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 | |||
967 | static 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 | |||
1053 | static void update_hdmi_timings(struct hdmi_config *cfg, | 253 | static 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 | ||
269 | unsigned 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 | |||
1069 | static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, | 275 | static 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, | |||
1109 | static int hdmi_power_on(struct omap_dss_device *dssdev) | 326 | static 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; |
1182 | err: | 393 | err: |
@@ -1186,14 +397,12 @@ err: | |||
1186 | 397 | ||
1187 | static void hdmi_power_off(struct omap_dss_device *dssdev) | 398 | static 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 | ||
1199 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 408 | int 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 | |||
441 | void 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 | |||
457 | int 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 | |||
474 | bool 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 | ||
1226 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) | 491 | int 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) |
1285 | static 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 | |||
1304 | static 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 | |||
1321 | static 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 | |||
1391 | static 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; | 557 | static 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 | |||
1441 | static 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 | |||
1497 | static 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 | ||
1630 | static 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 | |||
1656 | static int hdmi_audio_startup(struct snd_pcm_substream *substream, | 691 | static 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 | ||
1787 | static int hdmi_runtime_suspend(struct device *dev) | 817 | static 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 | |||
179 | static 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); | ||
196 | err: | ||
197 | mutex_unlock(&hdmi.hdmi_lock); | ||
198 | |||
199 | return r; | ||
200 | } | ||
201 | |||
202 | static 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); | ||
188 | err: | 219 | err: |
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: | |||
106 | static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, | 106 | static 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 | ||
112 | static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, | 112 | static 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, | |||
184 | static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, | 185 | static 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 | ||
190 | static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, | 191 | static 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, | |||
246 | static ssize_t manager_alpha_blending_enabled_show( | 249 | static 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 | ||
252 | static ssize_t manager_alpha_blending_enabled_store( | 258 | static 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 | ||
1485 | static int dss_check_manager(struct omap_overlay_manager *mgr) | 1487 | static 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 | ||
1523 | static int dss_mgr_enable(struct omap_overlay_manager *mgr) | 1530 | static 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 | ||
1529 | static int dss_mgr_disable(struct omap_overlay_manager *mgr) | 1536 | static 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) | |||
211 | static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, | 211 | static 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 | |||
314 | static 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 | |||
319 | static 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, | |||
347 | static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR, | 373 | static 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); |
376 | static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR, | ||
377 | overlay_zorder_show, overlay_zorder_store); | ||
350 | 378 | ||
351 | static struct attribute *overlay_sysfs_attrs[] = { | 379 | static 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 | ||
537 | static int omap_dss_unset_manager(struct omap_overlay *ovl) | 592 | static 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 | } |
817 | EXPORT_SYMBOL(omap_rfbi_update); | 800 | EXPORT_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 { | |||
35 | static void sdi_basic_init(struct omap_dss_device *dssdev) | 35 | static 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 | |||
24 | struct hdmi_ip_data; | ||
25 | |||
26 | enum 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 | |||
33 | enum hdmi_core_hdmi_dvi { | ||
34 | HDMI_DVI = 0, | ||
35 | HDMI_HDMI = 1 | ||
36 | }; | ||
37 | |||
38 | enum 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 | |||
45 | struct 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 */ | ||
59 | struct hdmi_timings { | ||
60 | struct hdmi_video_timings timings; | ||
61 | int vsync_pol; | ||
62 | int hsync_pol; | ||
63 | }; | ||
64 | |||
65 | struct hdmi_cm { | ||
66 | int code; | ||
67 | int mode; | ||
68 | }; | ||
69 | |||
70 | struct hdmi_config { | ||
71 | struct hdmi_timings timings; | ||
72 | u16 interlace; | ||
73 | struct hdmi_cm cm; | ||
74 | }; | ||
75 | |||
76 | /* HDMI PLL structure */ | ||
77 | struct 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 | |||
87 | struct 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 | |||
115 | struct 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 | }; | ||
125 | int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); | ||
126 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); | ||
127 | int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); | ||
128 | bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data); | ||
129 | void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); | ||
130 | int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); | ||
131 | void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); | ||
132 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); | ||
133 | void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | ||
134 | void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | ||
135 | void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | ||
136 | void 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 | |||
35 | static 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 | |||
41 | static inline u32 hdmi_read_reg(void __iomem *base_addr, | ||
42 | const u16 idx) | ||
43 | { | ||
44 | return __raw_readl(base_addr + idx); | ||
45 | } | ||
46 | |||
47 | static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data) | ||
48 | { | ||
49 | return ip_data->base_wp; | ||
50 | } | ||
51 | |||
52 | static 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 | |||
57 | static 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 | |||
62 | static 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 | |||
67 | static 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 | |||
72 | static 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 | |||
85 | static 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 */ | ||
152 | static 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 */ | ||
168 | static 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 | |||
183 | static 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 | |||
198 | int 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 | |||
221 | void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data) | ||
222 | { | ||
223 | hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); | ||
224 | } | ||
225 | |||
226 | int 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 | |||
263 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) | ||
264 | { | ||
265 | hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); | ||
266 | } | ||
267 | |||
268 | static 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 | |||
310 | static 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 | |||
392 | int 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 | |||
420 | bool 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 | |||
432 | static 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 | |||
476 | static 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 | |||
482 | static 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 | |||
488 | static 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 */ | ||
495 | static 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 | |||
537 | static 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 | |||
613 | static 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 | |||
631 | static 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 | |||
656 | void 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 | |||
661 | static 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 | |||
677 | static 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 | |||
690 | static 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 | |||
704 | static 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 | |||
723 | void 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 | |||
809 | void 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 | |||
831 | void 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 | |||
845 | void 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 | |||
970 | void 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) | ||
983 | void 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 | |||
1002 | void 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 | |||
1020 | void 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 | |||
1098 | void 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 | |||
1150 | int 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 | |||
1207 | int 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 | |||
33 | struct 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 */ | ||
212 | struct hdmi_timings { | ||
213 | struct omap_video_timings timings; | ||
214 | int vsync_pol; | ||
215 | int hsync_pol; | ||
216 | }; | ||
217 | 192 | ||
218 | enum hdmi_phy_pwr { | 193 | enum 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 | ||
224 | enum 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 | |||
231 | enum 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 | |||
238 | enum hdmi_core_inputbus_width { | 199 | enum 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 | ||
266 | enum hdmi_core_hdmi_dvi { | ||
267 | HDMI_DVI = 0, | ||
268 | HDMI_HDMI = 1 | ||
269 | }; | ||
270 | |||
271 | enum hdmi_core_tclkselclkmult { | 227 | enum 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 | */ |
497 | struct hdmi_core_infoframe_avi { | 453 | struct 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 | ||
571 | struct hdmi_cm { | ||
572 | int code; | ||
573 | int mode; | ||
574 | }; | ||
575 | |||
576 | struct hdmi_config { | ||
577 | struct hdmi_timings timings; | ||
578 | u16 interlace; | ||
579 | struct hdmi_cm cm; | ||
580 | }; | ||
581 | |||
582 | struct hdmi_audio_format { | 527 | struct 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) | ||
579 | int hdmi_audio_trigger(struct hdmi_ip_data *ip_data, | ||
580 | struct snd_pcm_substream *substream, int cmd, | ||
581 | struct snd_soc_dai *dai); | ||
582 | int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, | ||
583 | u32 sample_freq, u32 *n, u32 *cts); | ||
584 | void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data, | ||
585 | struct hdmi_core_infoframe_audio *info_aud); | ||
586 | void hdmi_core_audio_config(struct hdmi_ip_data *ip_data, | ||
587 | struct hdmi_core_audio_config *cfg); | ||
588 | void hdmi_wp_audio_config_dma(struct hdmi_ip_data *ip_data, | ||
589 | struct hdmi_audio_dma *aud_dma); | ||
590 | void 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 | 466 | unsigned 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 */ |
472 | static int venc_panel_probe(struct omap_dss_device *dssdev) | 473 | static 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 | ||
762 | static void venc_put_clocks(void) | 751 | static 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 @@ | |||
1 | menuconfig FB_OMAP2 | 1 | menuconfig 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, | |||
808 | static void omapfb_calc_addr(const struct omapfb_info *ofbi, | 808 | static 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 | ||
2270 | static 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 | |||
2284 | static 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 | |||
2342 | err2: | ||
2343 | fb_destroy_modedb(specs->modedb); | ||
2344 | kfree(specs); | ||
2345 | err1: | ||
2346 | kfree(edid); | ||
2347 | |||
2348 | return r; | ||
2349 | } | ||
2350 | |||
2279 | static int omapfb_init_display(struct omapfb2_device *fbdev, | 2351 | static 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 | ||