diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-03-13 06:44:14 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-05-09 08:11:30 -0400 |
commit | f5bab22291908dc395c018f12c8485ef5fc9b90a (patch) | |
tree | c06e73ad21ffe4cbbaffa42656db6e52bebc5757 /drivers/video | |
parent | 2d64b1b314bb52463b444e9c5aa1a2d399e694d2 (diff) |
OMAPDSS: HDMI: Add OMAP5 HDMI support
This adds a new driver to omapdss for OMAP5 HDMI. However, the new
driver uses common HDMI files which are shared with OMAP4 HDMI driver.
OMAP5 HDMI has a different HDMI core IP compared to OMAP4, but has very
similar PLL and PHY IPs which can be handled with common code.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/omap2/dss/Kconfig | 13 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/core.c | 6 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/dss.h | 3 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi.h | 2 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5.c | 829 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5_core.c | 922 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5_core.h | 306 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_wp.c | 2 |
9 files changed, 2082 insertions, 2 deletions
diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig index 36de3d5d2896..8921a7a76a15 100644 --- a/drivers/video/fbdev/omap2/dss/Kconfig +++ b/drivers/video/fbdev/omap2/dss/Kconfig | |||
@@ -72,6 +72,19 @@ config OMAP4_DSS_HDMI | |||
72 | config OMAP4_DSS_HDMI_AUDIO | 72 | config OMAP4_DSS_HDMI_AUDIO |
73 | bool | 73 | bool |
74 | 74 | ||
75 | config OMAP5_DSS_HDMI | ||
76 | bool "HDMI support for OMAP5" | ||
77 | default n | ||
78 | select OMAP2_DSS_HDMI_COMMON | ||
79 | help | ||
80 | HDMI Interface for OMAP5 and similar cores. This adds the High | ||
81 | Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI | ||
82 | specification. | ||
83 | |||
84 | config OMAP5_DSS_HDMI_AUDIO | ||
85 | depends on OMAP5_DSS_HDMI | ||
86 | bool | ||
87 | |||
75 | config OMAP2_DSS_SDI | 88 | config OMAP2_DSS_SDI |
76 | bool "SDI support" | 89 | bool "SDI support" |
77 | default n | 90 | default n |
diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile index 4cbe7ce406f9..390ab746bdc0 100644 --- a/drivers/video/fbdev/omap2/dss/Makefile +++ b/drivers/video/fbdev/omap2/dss/Makefile | |||
@@ -13,4 +13,5 @@ omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | |||
13 | omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ | 13 | omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ |
14 | hdmi_phy.o | 14 | hdmi_phy.o |
15 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o | 15 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o |
16 | omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o | ||
16 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG | 17 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG |
diff --git a/drivers/video/fbdev/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c index ffa45c894cd4..6b74f73fb524 100644 --- a/drivers/video/fbdev/omap2/dss/core.c +++ b/drivers/video/fbdev/omap2/dss/core.c | |||
@@ -268,6 +268,9 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { | |||
268 | #ifdef CONFIG_OMAP4_DSS_HDMI | 268 | #ifdef CONFIG_OMAP4_DSS_HDMI |
269 | hdmi4_init_platform_driver, | 269 | hdmi4_init_platform_driver, |
270 | #endif | 270 | #endif |
271 | #ifdef CONFIG_OMAP5_DSS_HDMI | ||
272 | hdmi5_init_platform_driver, | ||
273 | #endif | ||
271 | }; | 274 | }; |
272 | 275 | ||
273 | static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { | 276 | static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { |
@@ -289,6 +292,9 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { | |||
289 | #ifdef CONFIG_OMAP4_DSS_HDMI | 292 | #ifdef CONFIG_OMAP4_DSS_HDMI |
290 | hdmi4_uninit_platform_driver, | 293 | hdmi4_uninit_platform_driver, |
291 | #endif | 294 | #endif |
295 | #ifdef CONFIG_OMAP5_DSS_HDMI | ||
296 | hdmi5_uninit_platform_driver, | ||
297 | #endif | ||
292 | }; | 298 | }; |
293 | 299 | ||
294 | static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; | 300 | static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; |
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index 560078fcb198..8ff22c134c62 100644 --- a/drivers/video/fbdev/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h | |||
@@ -419,6 +419,9 @@ void venc_uninit_platform_driver(void) __exit; | |||
419 | int hdmi4_init_platform_driver(void) __init; | 419 | int hdmi4_init_platform_driver(void) __init; |
420 | void hdmi4_uninit_platform_driver(void) __exit; | 420 | void hdmi4_uninit_platform_driver(void) __exit; |
421 | 421 | ||
422 | int hdmi5_init_platform_driver(void) __init; | ||
423 | void hdmi5_uninit_platform_driver(void) __exit; | ||
424 | |||
422 | /* RFBI */ | 425 | /* RFBI */ |
423 | int rfbi_init_platform_driver(void) __init; | 426 | int rfbi_init_platform_driver(void) __init; |
424 | void rfbi_uninit_platform_driver(void) __exit; | 427 | void rfbi_uninit_platform_driver(void) __exit; |
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 1819f93cd49e..fbee07816337 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h | |||
@@ -431,7 +431,7 @@ struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing); | |||
431 | int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, | 431 | int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, |
432 | struct hdmi_phy_data *phy); | 432 | struct hdmi_phy_data *phy); |
433 | 433 | ||
434 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 434 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) |
435 | int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); | 435 | int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); |
436 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); | 436 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); |
437 | int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); | 437 | int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); |
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c new file mode 100644 index 000000000000..c468b9e1f295 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c | |||
@@ -0,0 +1,829 @@ | |||
1 | /* | ||
2 | * HDMI driver for OMAP5 | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments Incorporated | ||
5 | * | ||
6 | * Authors: | ||
7 | * Yong Zhi | ||
8 | * Mythri pk | ||
9 | * Archit Taneja <archit@ti.com> | ||
10 | * Tomi Valkeinen <tomi.valkeinen@ti.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License version 2 as published by | ||
14 | * the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | */ | ||
24 | |||
25 | #define DSS_SUBSYS_NAME "HDMI" | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/pm_runtime.h> | ||
37 | #include <linux/clk.h> | ||
38 | #include <linux/gpio.h> | ||
39 | #include <linux/regulator/consumer.h> | ||
40 | #include <video/omapdss.h> | ||
41 | |||
42 | #include "hdmi5_core.h" | ||
43 | #include "dss.h" | ||
44 | #include "dss_features.h" | ||
45 | |||
46 | static struct { | ||
47 | struct mutex lock; | ||
48 | struct platform_device *pdev; | ||
49 | |||
50 | struct hdmi_wp_data wp; | ||
51 | struct hdmi_pll_data pll; | ||
52 | struct hdmi_phy_data phy; | ||
53 | struct hdmi_core_data core; | ||
54 | |||
55 | struct hdmi_config cfg; | ||
56 | |||
57 | struct clk *sys_clk; | ||
58 | struct regulator *vdda_reg; | ||
59 | |||
60 | bool core_enabled; | ||
61 | |||
62 | struct omap_dss_device output; | ||
63 | } hdmi; | ||
64 | |||
65 | static int hdmi_runtime_get(void) | ||
66 | { | ||
67 | int r; | ||
68 | |||
69 | DSSDBG("hdmi_runtime_get\n"); | ||
70 | |||
71 | r = pm_runtime_get_sync(&hdmi.pdev->dev); | ||
72 | WARN_ON(r < 0); | ||
73 | if (r < 0) | ||
74 | return r; | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static void hdmi_runtime_put(void) | ||
80 | { | ||
81 | int r; | ||
82 | |||
83 | DSSDBG("hdmi_runtime_put\n"); | ||
84 | |||
85 | r = pm_runtime_put_sync(&hdmi.pdev->dev); | ||
86 | WARN_ON(r < 0 && r != -ENOSYS); | ||
87 | } | ||
88 | |||
89 | static irqreturn_t hdmi_irq_handler(int irq, void *data) | ||
90 | { | ||
91 | struct hdmi_wp_data *wp = data; | ||
92 | u32 irqstatus; | ||
93 | |||
94 | irqstatus = hdmi_wp_get_irqstatus(wp); | ||
95 | hdmi_wp_set_irqstatus(wp, irqstatus); | ||
96 | |||
97 | if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && | ||
98 | irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
99 | u32 v; | ||
100 | /* | ||
101 | * If we get both connect and disconnect interrupts at the same | ||
102 | * time, turn off the PHY, clear interrupts, and restart, which | ||
103 | * raises connect interrupt if a cable is connected, or nothing | ||
104 | * if cable is not connected. | ||
105 | */ | ||
106 | |||
107 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); | ||
108 | |||
109 | /* | ||
110 | * We always get bogus CONNECT & DISCONNECT interrupts when | ||
111 | * setting the PHY to LDOON. To ignore those, we force the RXDET | ||
112 | * line to 0 until the PHY power state has been changed. | ||
113 | */ | ||
114 | v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); | ||
115 | v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ | ||
116 | v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ | ||
117 | hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); | ||
118 | |||
119 | hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | | ||
120 | HDMI_IRQ_LINK_DISCONNECT); | ||
121 | |||
122 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); | ||
123 | |||
124 | REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); | ||
125 | |||
126 | } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { | ||
127 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); | ||
128 | } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
129 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); | ||
130 | } | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static int hdmi_init_regulator(void) | ||
136 | { | ||
137 | int r; | ||
138 | struct regulator *reg; | ||
139 | |||
140 | if (hdmi.vdda_reg != NULL) | ||
141 | return 0; | ||
142 | |||
143 | reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); | ||
144 | if (IS_ERR(reg)) { | ||
145 | DSSERR("can't get VDDA regulator\n"); | ||
146 | return PTR_ERR(reg); | ||
147 | } | ||
148 | |||
149 | if (regulator_can_change_voltage(reg)) { | ||
150 | r = regulator_set_voltage(reg, 1800000, 1800000); | ||
151 | if (r) { | ||
152 | devm_regulator_put(reg); | ||
153 | DSSWARN("can't set the regulator voltage\n"); | ||
154 | return r; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | hdmi.vdda_reg = reg; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int hdmi_power_on_core(struct omap_dss_device *dssdev) | ||
164 | { | ||
165 | int r; | ||
166 | |||
167 | r = regulator_enable(hdmi.vdda_reg); | ||
168 | if (r) | ||
169 | return r; | ||
170 | |||
171 | r = hdmi_runtime_get(); | ||
172 | if (r) | ||
173 | goto err_runtime_get; | ||
174 | |||
175 | /* Make selection of HDMI in DSS */ | ||
176 | dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); | ||
177 | |||
178 | hdmi.core_enabled = true; | ||
179 | |||
180 | return 0; | ||
181 | |||
182 | err_runtime_get: | ||
183 | regulator_disable(hdmi.vdda_reg); | ||
184 | |||
185 | return r; | ||
186 | } | ||
187 | |||
188 | static void hdmi_power_off_core(struct omap_dss_device *dssdev) | ||
189 | { | ||
190 | hdmi.core_enabled = false; | ||
191 | |||
192 | hdmi_runtime_put(); | ||
193 | regulator_disable(hdmi.vdda_reg); | ||
194 | } | ||
195 | |||
196 | static int hdmi_power_on_full(struct omap_dss_device *dssdev) | ||
197 | { | ||
198 | int r; | ||
199 | struct omap_video_timings *p; | ||
200 | struct omap_overlay_manager *mgr = hdmi.output.manager; | ||
201 | unsigned long phy; | ||
202 | |||
203 | r = hdmi_power_on_core(dssdev); | ||
204 | if (r) | ||
205 | return r; | ||
206 | |||
207 | p = &hdmi.cfg.timings; | ||
208 | |||
209 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); | ||
210 | |||
211 | /* the functions below use kHz pixel clock. TODO: change to Hz */ | ||
212 | phy = p->pixelclock / 1000; | ||
213 | |||
214 | hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy); | ||
215 | |||
216 | /* disable and clear irqs */ | ||
217 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); | ||
218 | hdmi_wp_set_irqstatus(&hdmi.wp, | ||
219 | hdmi_wp_get_irqstatus(&hdmi.wp)); | ||
220 | |||
221 | /* config the PLL and PHY hdmi_set_pll_pwrfirst */ | ||
222 | r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp); | ||
223 | if (r) { | ||
224 | DSSDBG("Failed to lock PLL\n"); | ||
225 | goto err_pll_enable; | ||
226 | } | ||
227 | |||
228 | r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); | ||
229 | if (r) { | ||
230 | DSSDBG("Failed to start PHY\n"); | ||
231 | goto err_phy_cfg; | ||
232 | } | ||
233 | |||
234 | r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); | ||
235 | if (r) | ||
236 | goto err_phy_pwr; | ||
237 | |||
238 | hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); | ||
239 | |||
240 | /* bypass TV gamma table */ | ||
241 | dispc_enable_gamma_table(0); | ||
242 | |||
243 | /* tv size */ | ||
244 | dss_mgr_set_timings(mgr, p); | ||
245 | |||
246 | r = hdmi_wp_video_start(&hdmi.wp); | ||
247 | if (r) | ||
248 | goto err_vid_enable; | ||
249 | |||
250 | r = dss_mgr_enable(mgr); | ||
251 | if (r) | ||
252 | goto err_mgr_enable; | ||
253 | |||
254 | hdmi_wp_set_irqenable(&hdmi.wp, | ||
255 | HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); | ||
256 | |||
257 | return 0; | ||
258 | |||
259 | err_mgr_enable: | ||
260 | hdmi_wp_video_stop(&hdmi.wp); | ||
261 | err_vid_enable: | ||
262 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); | ||
263 | err_phy_pwr: | ||
264 | err_phy_cfg: | ||
265 | hdmi_pll_disable(&hdmi.pll, &hdmi.wp); | ||
266 | err_pll_enable: | ||
267 | hdmi_power_off_core(dssdev); | ||
268 | return -EIO; | ||
269 | } | ||
270 | |||
271 | static void hdmi_power_off_full(struct omap_dss_device *dssdev) | ||
272 | { | ||
273 | struct omap_overlay_manager *mgr = hdmi.output.manager; | ||
274 | |||
275 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); | ||
276 | |||
277 | dss_mgr_disable(mgr); | ||
278 | |||
279 | hdmi_wp_video_stop(&hdmi.wp); | ||
280 | |||
281 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); | ||
282 | |||
283 | hdmi_pll_disable(&hdmi.pll, &hdmi.wp); | ||
284 | |||
285 | hdmi_power_off_core(dssdev); | ||
286 | } | ||
287 | |||
288 | static int hdmi_display_check_timing(struct omap_dss_device *dssdev, | ||
289 | struct omap_video_timings *timings) | ||
290 | { | ||
291 | struct omap_dss_device *out = &hdmi.output; | ||
292 | |||
293 | if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) | ||
294 | return -EINVAL; | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static void hdmi_display_set_timing(struct omap_dss_device *dssdev, | ||
300 | struct omap_video_timings *timings) | ||
301 | { | ||
302 | struct hdmi_cm cm; | ||
303 | const struct hdmi_config *t; | ||
304 | |||
305 | mutex_lock(&hdmi.lock); | ||
306 | |||
307 | cm = hdmi_get_code(timings); | ||
308 | hdmi.cfg.cm = cm; | ||
309 | |||
310 | t = hdmi_get_timings(cm.mode, cm.code); | ||
311 | if (t != NULL) { | ||
312 | hdmi.cfg = *t; | ||
313 | |||
314 | dispc_set_tv_pclk(t->timings.pixelclock); | ||
315 | } else { | ||
316 | hdmi.cfg.timings = *timings; | ||
317 | hdmi.cfg.cm.code = 0; | ||
318 | hdmi.cfg.cm.mode = HDMI_DVI; | ||
319 | |||
320 | dispc_set_tv_pclk(timings->pixelclock); | ||
321 | } | ||
322 | |||
323 | DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? | ||
324 | "DVI" : "HDMI", hdmi.cfg.cm.code); | ||
325 | |||
326 | mutex_unlock(&hdmi.lock); | ||
327 | } | ||
328 | |||
329 | static void hdmi_display_get_timings(struct omap_dss_device *dssdev, | ||
330 | struct omap_video_timings *timings) | ||
331 | { | ||
332 | const struct hdmi_config *cfg; | ||
333 | struct hdmi_cm cm = hdmi.cfg.cm; | ||
334 | |||
335 | cfg = hdmi_get_timings(cm.mode, cm.code); | ||
336 | if (cfg == NULL) | ||
337 | cfg = hdmi_default_timing(); | ||
338 | |||
339 | memcpy(timings, &cfg->timings, sizeof(cfg->timings)); | ||
340 | } | ||
341 | |||
342 | static void hdmi_dump_regs(struct seq_file *s) | ||
343 | { | ||
344 | mutex_lock(&hdmi.lock); | ||
345 | |||
346 | if (hdmi_runtime_get()) { | ||
347 | mutex_unlock(&hdmi.lock); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | hdmi_wp_dump(&hdmi.wp, s); | ||
352 | hdmi_pll_dump(&hdmi.pll, s); | ||
353 | hdmi_phy_dump(&hdmi.phy, s); | ||
354 | hdmi5_core_dump(&hdmi.core, s); | ||
355 | |||
356 | hdmi_runtime_put(); | ||
357 | mutex_unlock(&hdmi.lock); | ||
358 | } | ||
359 | |||
360 | static int read_edid(u8 *buf, int len) | ||
361 | { | ||
362 | int r; | ||
363 | int idlemode; | ||
364 | |||
365 | mutex_lock(&hdmi.lock); | ||
366 | |||
367 | r = hdmi_runtime_get(); | ||
368 | BUG_ON(r); | ||
369 | |||
370 | idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); | ||
371 | /* No-idle mode */ | ||
372 | REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); | ||
373 | |||
374 | r = hdmi5_read_edid(&hdmi.core, buf, len); | ||
375 | |||
376 | REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); | ||
377 | |||
378 | hdmi_runtime_put(); | ||
379 | mutex_unlock(&hdmi.lock); | ||
380 | |||
381 | return r; | ||
382 | } | ||
383 | |||
384 | static int hdmi_display_enable(struct omap_dss_device *dssdev) | ||
385 | { | ||
386 | struct omap_dss_device *out = &hdmi.output; | ||
387 | int r = 0; | ||
388 | |||
389 | DSSDBG("ENTER hdmi_display_enable\n"); | ||
390 | |||
391 | mutex_lock(&hdmi.lock); | ||
392 | |||
393 | if (out == NULL || out->manager == NULL) { | ||
394 | DSSERR("failed to enable display: no output/manager\n"); | ||
395 | r = -ENODEV; | ||
396 | goto err0; | ||
397 | } | ||
398 | |||
399 | r = hdmi_power_on_full(dssdev); | ||
400 | if (r) { | ||
401 | DSSERR("failed to power on device\n"); | ||
402 | goto err0; | ||
403 | } | ||
404 | |||
405 | mutex_unlock(&hdmi.lock); | ||
406 | return 0; | ||
407 | |||
408 | err0: | ||
409 | mutex_unlock(&hdmi.lock); | ||
410 | return r; | ||
411 | } | ||
412 | |||
413 | static void hdmi_display_disable(struct omap_dss_device *dssdev) | ||
414 | { | ||
415 | DSSDBG("Enter hdmi_display_disable\n"); | ||
416 | |||
417 | mutex_lock(&hdmi.lock); | ||
418 | |||
419 | hdmi_power_off_full(dssdev); | ||
420 | |||
421 | mutex_unlock(&hdmi.lock); | ||
422 | } | ||
423 | |||
424 | static int hdmi_core_enable(struct omap_dss_device *dssdev) | ||
425 | { | ||
426 | int r = 0; | ||
427 | |||
428 | DSSDBG("ENTER omapdss_hdmi_core_enable\n"); | ||
429 | |||
430 | mutex_lock(&hdmi.lock); | ||
431 | |||
432 | r = hdmi_power_on_core(dssdev); | ||
433 | if (r) { | ||
434 | DSSERR("failed to power on device\n"); | ||
435 | goto err0; | ||
436 | } | ||
437 | |||
438 | mutex_unlock(&hdmi.lock); | ||
439 | return 0; | ||
440 | |||
441 | err0: | ||
442 | mutex_unlock(&hdmi.lock); | ||
443 | return r; | ||
444 | } | ||
445 | |||
446 | static void hdmi_core_disable(struct omap_dss_device *dssdev) | ||
447 | { | ||
448 | DSSDBG("Enter omapdss_hdmi_core_disable\n"); | ||
449 | |||
450 | mutex_lock(&hdmi.lock); | ||
451 | |||
452 | hdmi_power_off_core(dssdev); | ||
453 | |||
454 | mutex_unlock(&hdmi.lock); | ||
455 | } | ||
456 | |||
457 | static int hdmi_get_clocks(struct platform_device *pdev) | ||
458 | { | ||
459 | struct clk *clk; | ||
460 | |||
461 | clk = devm_clk_get(&pdev->dev, "sys_clk"); | ||
462 | if (IS_ERR(clk)) { | ||
463 | DSSERR("can't get sys_clk\n"); | ||
464 | return PTR_ERR(clk); | ||
465 | } | ||
466 | |||
467 | hdmi.sys_clk = clk; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int hdmi_connect(struct omap_dss_device *dssdev, | ||
473 | struct omap_dss_device *dst) | ||
474 | { | ||
475 | struct omap_overlay_manager *mgr; | ||
476 | int r; | ||
477 | |||
478 | r = hdmi_init_regulator(); | ||
479 | if (r) | ||
480 | return r; | ||
481 | |||
482 | mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); | ||
483 | if (!mgr) | ||
484 | return -ENODEV; | ||
485 | |||
486 | r = dss_mgr_connect(mgr, dssdev); | ||
487 | if (r) | ||
488 | return r; | ||
489 | |||
490 | r = omapdss_output_set_device(dssdev, dst); | ||
491 | if (r) { | ||
492 | DSSERR("failed to connect output to new device: %s\n", | ||
493 | dst->name); | ||
494 | dss_mgr_disconnect(mgr, dssdev); | ||
495 | return r; | ||
496 | } | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static void hdmi_disconnect(struct omap_dss_device *dssdev, | ||
502 | struct omap_dss_device *dst) | ||
503 | { | ||
504 | WARN_ON(dst != dssdev->dst); | ||
505 | |||
506 | if (dst != dssdev->dst) | ||
507 | return; | ||
508 | |||
509 | omapdss_output_unset_device(dssdev); | ||
510 | |||
511 | if (dssdev->manager) | ||
512 | dss_mgr_disconnect(dssdev->manager, dssdev); | ||
513 | } | ||
514 | |||
515 | static int hdmi_read_edid(struct omap_dss_device *dssdev, | ||
516 | u8 *edid, int len) | ||
517 | { | ||
518 | bool need_enable; | ||
519 | int r; | ||
520 | |||
521 | need_enable = hdmi.core_enabled == false; | ||
522 | |||
523 | if (need_enable) { | ||
524 | r = hdmi_core_enable(dssdev); | ||
525 | if (r) | ||
526 | return r; | ||
527 | } | ||
528 | |||
529 | r = read_edid(edid, len); | ||
530 | |||
531 | if (need_enable) | ||
532 | hdmi_core_disable(dssdev); | ||
533 | |||
534 | return r; | ||
535 | } | ||
536 | |||
537 | #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) | ||
538 | static int hdmi_audio_enable(struct omap_dss_device *dssdev) | ||
539 | { | ||
540 | int r; | ||
541 | |||
542 | mutex_lock(&hdmi.lock); | ||
543 | |||
544 | if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { | ||
545 | r = -EPERM; | ||
546 | goto err; | ||
547 | } | ||
548 | |||
549 | r = hdmi_wp_audio_enable(&hdmi.wp, true); | ||
550 | if (r) | ||
551 | goto err; | ||
552 | |||
553 | mutex_unlock(&hdmi.lock); | ||
554 | return 0; | ||
555 | |||
556 | err: | ||
557 | mutex_unlock(&hdmi.lock); | ||
558 | return r; | ||
559 | } | ||
560 | |||
561 | static void hdmi_audio_disable(struct omap_dss_device *dssdev) | ||
562 | { | ||
563 | hdmi_wp_audio_enable(&hdmi.wp, false); | ||
564 | } | ||
565 | |||
566 | static int hdmi_audio_start(struct omap_dss_device *dssdev) | ||
567 | { | ||
568 | return hdmi_wp_audio_core_req_enable(&hdmi.wp, true); | ||
569 | } | ||
570 | |||
571 | static void hdmi_audio_stop(struct omap_dss_device *dssdev) | ||
572 | { | ||
573 | hdmi_wp_audio_core_req_enable(&hdmi.wp, false); | ||
574 | } | ||
575 | |||
576 | static bool hdmi_audio_supported(struct omap_dss_device *dssdev) | ||
577 | { | ||
578 | bool r; | ||
579 | |||
580 | mutex_lock(&hdmi.lock); | ||
581 | |||
582 | r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); | ||
583 | |||
584 | mutex_unlock(&hdmi.lock); | ||
585 | return r; | ||
586 | } | ||
587 | |||
588 | static int hdmi_audio_config(struct omap_dss_device *dssdev, | ||
589 | struct omap_dss_audio *audio) | ||
590 | { | ||
591 | int r; | ||
592 | u32 pclk = hdmi.cfg.timings.pixelclock; | ||
593 | |||
594 | mutex_lock(&hdmi.lock); | ||
595 | |||
596 | if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { | ||
597 | r = -EPERM; | ||
598 | goto err; | ||
599 | } | ||
600 | |||
601 | r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); | ||
602 | if (r) | ||
603 | goto err; | ||
604 | |||
605 | mutex_unlock(&hdmi.lock); | ||
606 | return 0; | ||
607 | |||
608 | err: | ||
609 | mutex_unlock(&hdmi.lock); | ||
610 | return r; | ||
611 | } | ||
612 | #else | ||
613 | static int hdmi_audio_enable(struct omap_dss_device *dssdev) | ||
614 | { | ||
615 | return -EPERM; | ||
616 | } | ||
617 | |||
618 | static void hdmi_audio_disable(struct omap_dss_device *dssdev) | ||
619 | { | ||
620 | } | ||
621 | |||
622 | static int hdmi_audio_start(struct omap_dss_device *dssdev) | ||
623 | { | ||
624 | return -EPERM; | ||
625 | } | ||
626 | |||
627 | static void hdmi_audio_stop(struct omap_dss_device *dssdev) | ||
628 | { | ||
629 | } | ||
630 | |||
631 | static bool hdmi_audio_supported(struct omap_dss_device *dssdev) | ||
632 | { | ||
633 | return false; | ||
634 | } | ||
635 | |||
636 | static int hdmi_audio_config(struct omap_dss_device *dssdev, | ||
637 | struct omap_dss_audio *audio) | ||
638 | { | ||
639 | return -EPERM; | ||
640 | } | ||
641 | #endif | ||
642 | |||
643 | static const struct omapdss_hdmi_ops hdmi_ops = { | ||
644 | .connect = hdmi_connect, | ||
645 | .disconnect = hdmi_disconnect, | ||
646 | |||
647 | .enable = hdmi_display_enable, | ||
648 | .disable = hdmi_display_disable, | ||
649 | |||
650 | .check_timings = hdmi_display_check_timing, | ||
651 | .set_timings = hdmi_display_set_timing, | ||
652 | .get_timings = hdmi_display_get_timings, | ||
653 | |||
654 | .read_edid = hdmi_read_edid, | ||
655 | |||
656 | .audio_enable = hdmi_audio_enable, | ||
657 | .audio_disable = hdmi_audio_disable, | ||
658 | .audio_start = hdmi_audio_start, | ||
659 | .audio_stop = hdmi_audio_stop, | ||
660 | .audio_supported = hdmi_audio_supported, | ||
661 | .audio_config = hdmi_audio_config, | ||
662 | }; | ||
663 | |||
664 | static void hdmi_init_output(struct platform_device *pdev) | ||
665 | { | ||
666 | struct omap_dss_device *out = &hdmi.output; | ||
667 | |||
668 | out->dev = &pdev->dev; | ||
669 | out->id = OMAP_DSS_OUTPUT_HDMI; | ||
670 | out->output_type = OMAP_DISPLAY_TYPE_HDMI; | ||
671 | out->name = "hdmi.0"; | ||
672 | out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; | ||
673 | out->ops.hdmi = &hdmi_ops; | ||
674 | out->owner = THIS_MODULE; | ||
675 | |||
676 | omapdss_register_output(out); | ||
677 | } | ||
678 | |||
679 | static void __exit hdmi_uninit_output(struct platform_device *pdev) | ||
680 | { | ||
681 | struct omap_dss_device *out = &hdmi.output; | ||
682 | |||
683 | omapdss_unregister_output(out); | ||
684 | } | ||
685 | |||
686 | static int hdmi_probe_of(struct platform_device *pdev) | ||
687 | { | ||
688 | struct device_node *node = pdev->dev.of_node; | ||
689 | struct device_node *ep; | ||
690 | int r; | ||
691 | |||
692 | ep = omapdss_of_get_first_endpoint(node); | ||
693 | if (!ep) | ||
694 | return 0; | ||
695 | |||
696 | r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); | ||
697 | if (r) | ||
698 | goto err; | ||
699 | |||
700 | of_node_put(ep); | ||
701 | return 0; | ||
702 | |||
703 | err: | ||
704 | of_node_put(ep); | ||
705 | return r; | ||
706 | } | ||
707 | |||
708 | /* HDMI HW IP initialisation */ | ||
709 | static int omapdss_hdmihw_probe(struct platform_device *pdev) | ||
710 | { | ||
711 | int r; | ||
712 | int irq; | ||
713 | |||
714 | hdmi.pdev = pdev; | ||
715 | |||
716 | mutex_init(&hdmi.lock); | ||
717 | |||
718 | if (pdev->dev.of_node) { | ||
719 | r = hdmi_probe_of(pdev); | ||
720 | if (r) | ||
721 | return r; | ||
722 | } | ||
723 | |||
724 | r = hdmi_wp_init(pdev, &hdmi.wp); | ||
725 | if (r) | ||
726 | return r; | ||
727 | |||
728 | r = hdmi_pll_init(pdev, &hdmi.pll); | ||
729 | if (r) | ||
730 | return r; | ||
731 | |||
732 | r = hdmi_phy_init(pdev, &hdmi.phy); | ||
733 | if (r) | ||
734 | return r; | ||
735 | |||
736 | r = hdmi5_core_init(pdev, &hdmi.core); | ||
737 | if (r) | ||
738 | return r; | ||
739 | |||
740 | r = hdmi_get_clocks(pdev); | ||
741 | if (r) { | ||
742 | DSSERR("can't get clocks\n"); | ||
743 | return r; | ||
744 | } | ||
745 | |||
746 | irq = platform_get_irq(pdev, 0); | ||
747 | if (irq < 0) { | ||
748 | DSSERR("platform_get_irq failed\n"); | ||
749 | return -ENODEV; | ||
750 | } | ||
751 | |||
752 | r = devm_request_threaded_irq(&pdev->dev, irq, | ||
753 | NULL, hdmi_irq_handler, | ||
754 | IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); | ||
755 | if (r) { | ||
756 | DSSERR("HDMI IRQ request failed\n"); | ||
757 | return r; | ||
758 | } | ||
759 | |||
760 | pm_runtime_enable(&pdev->dev); | ||
761 | |||
762 | hdmi_init_output(pdev); | ||
763 | |||
764 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); | ||
765 | |||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | ||
770 | { | ||
771 | hdmi_uninit_output(pdev); | ||
772 | |||
773 | pm_runtime_disable(&pdev->dev); | ||
774 | |||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | static int hdmi_runtime_suspend(struct device *dev) | ||
779 | { | ||
780 | clk_disable_unprepare(hdmi.sys_clk); | ||
781 | |||
782 | dispc_runtime_put(); | ||
783 | |||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | static int hdmi_runtime_resume(struct device *dev) | ||
788 | { | ||
789 | int r; | ||
790 | |||
791 | r = dispc_runtime_get(); | ||
792 | if (r < 0) | ||
793 | return r; | ||
794 | |||
795 | clk_prepare_enable(hdmi.sys_clk); | ||
796 | |||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | static const struct dev_pm_ops hdmi_pm_ops = { | ||
801 | .runtime_suspend = hdmi_runtime_suspend, | ||
802 | .runtime_resume = hdmi_runtime_resume, | ||
803 | }; | ||
804 | |||
805 | static const struct of_device_id hdmi_of_match[] = { | ||
806 | { .compatible = "ti,omap5-hdmi", }, | ||
807 | {}, | ||
808 | }; | ||
809 | |||
810 | static struct platform_driver omapdss_hdmihw_driver = { | ||
811 | .probe = omapdss_hdmihw_probe, | ||
812 | .remove = __exit_p(omapdss_hdmihw_remove), | ||
813 | .driver = { | ||
814 | .name = "omapdss_hdmi5", | ||
815 | .owner = THIS_MODULE, | ||
816 | .pm = &hdmi_pm_ops, | ||
817 | .of_match_table = hdmi_of_match, | ||
818 | }, | ||
819 | }; | ||
820 | |||
821 | int __init hdmi5_init_platform_driver(void) | ||
822 | { | ||
823 | return platform_driver_register(&omapdss_hdmihw_driver); | ||
824 | } | ||
825 | |||
826 | void __exit hdmi5_uninit_platform_driver(void) | ||
827 | { | ||
828 | platform_driver_unregister(&omapdss_hdmihw_driver); | ||
829 | } | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c new file mode 100644 index 000000000000..270ebdd803d8 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c | |||
@@ -0,0 +1,922 @@ | |||
1 | /* | ||
2 | * OMAP5 HDMI CORE IP driver library | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments Incorporated | ||
5 | * | ||
6 | * Authors: | ||
7 | * Yong Zhi | ||
8 | * Mythri pk | ||
9 | * Archit Taneja <archit@ti.com> | ||
10 | * Tomi Valkeinen <tomi.valkeinen@ti.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License version 2 as published by | ||
14 | * the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/string.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <drm/drm_edid.h> | ||
33 | #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) | ||
34 | #include <sound/asound.h> | ||
35 | #include <sound/asoundef.h> | ||
36 | #endif | ||
37 | |||
38 | #include "hdmi5_core.h" | ||
39 | |||
40 | /* only 24 bit color depth used for now */ | ||
41 | static const struct csc_table csc_table_deepcolor[] = { | ||
42 | /* HDMI_DEEP_COLOR_24BIT */ | ||
43 | [0] = { 7036, 0, 0, 32, 0, 7036, 0, 32, 0, 0, 7036, 32, }, | ||
44 | /* HDMI_DEEP_COLOR_30BIT */ | ||
45 | [1] = { 7015, 0, 0, 128, 0, 7015, 0, 128, 0, 0, 7015, 128, }, | ||
46 | /* HDMI_DEEP_COLOR_36BIT */ | ||
47 | [2] = { 7010, 0, 0, 512, 0, 7010, 0, 512, 0, 0, 7010, 512, }, | ||
48 | /* FULL RANGE */ | ||
49 | [3] = { 8192, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 8192, 0, }, | ||
50 | }; | ||
51 | |||
52 | static void hdmi_core_ddc_init(struct hdmi_core_data *core) | ||
53 | { | ||
54 | void __iomem *base = core->base; | ||
55 | const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ | ||
56 | const unsigned ss_scl_high = 4000; /* ns */ | ||
57 | const unsigned ss_scl_low = 4700; /* ns */ | ||
58 | const unsigned fs_scl_high = 600; /* ns */ | ||
59 | const unsigned fs_scl_low = 1300; /* ns */ | ||
60 | const unsigned sda_hold = 300; /* ns */ | ||
61 | const unsigned sfr_div = 10; | ||
62 | unsigned long long sfr; | ||
63 | unsigned v; | ||
64 | |||
65 | sfr = iclk / sfr_div; /* SFR_DIV */ | ||
66 | sfr /= 1000; /* SFR clock in kHz */ | ||
67 | |||
68 | /* Reset */ | ||
69 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SOFTRSTZ, 0, 0, 0); | ||
70 | if (hdmi_wait_for_bit_change(base, HDMI_CORE_I2CM_SOFTRSTZ, | ||
71 | 0, 0, 1) != 1) | ||
72 | DSSERR("HDMI I2CM reset failed\n"); | ||
73 | |||
74 | /* Standard (0) or Fast (1) Mode */ | ||
75 | REG_FLD_MOD(base, HDMI_CORE_I2CM_DIV, 0, 3, 3); | ||
76 | |||
77 | /* Standard Mode SCL High counter */ | ||
78 | v = DIV_ROUND_UP_ULL(ss_scl_high * sfr, 1000000); | ||
79 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR, | ||
80 | (v >> 8) & 0xff, 7, 0); | ||
81 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR, | ||
82 | v & 0xff, 7, 0); | ||
83 | |||
84 | /* Standard Mode SCL Low counter */ | ||
85 | v = DIV_ROUND_UP_ULL(ss_scl_low * sfr, 1000000); | ||
86 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR, | ||
87 | (v >> 8) & 0xff, 7, 0); | ||
88 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR, | ||
89 | v & 0xff, 7, 0); | ||
90 | |||
91 | /* Fast Mode SCL High Counter */ | ||
92 | v = DIV_ROUND_UP_ULL(fs_scl_high * sfr, 1000000); | ||
93 | REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR, | ||
94 | (v >> 8) & 0xff, 7, 0); | ||
95 | REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR, | ||
96 | v & 0xff, 7, 0); | ||
97 | |||
98 | /* Fast Mode SCL Low Counter */ | ||
99 | v = DIV_ROUND_UP_ULL(fs_scl_low * sfr, 1000000); | ||
100 | REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR, | ||
101 | (v >> 8) & 0xff, 7, 0); | ||
102 | REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR, | ||
103 | v & 0xff, 7, 0); | ||
104 | |||
105 | /* SDA Hold Time */ | ||
106 | v = DIV_ROUND_UP_ULL(sda_hold * sfr, 1000000); | ||
107 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SDA_HOLD_ADDR, v & 0xff, 7, 0); | ||
108 | |||
109 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SLAVE, 0x50, 6, 0); | ||
110 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGADDR, 0x30, 6, 0); | ||
111 | |||
112 | /* NACK_POL to high */ | ||
113 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 7, 7); | ||
114 | |||
115 | /* NACK_MASK to unmasked */ | ||
116 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 6, 6); | ||
117 | |||
118 | /* ARBITRATION_POL to high */ | ||
119 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 3, 3); | ||
120 | |||
121 | /* ARBITRATION_MASK to unmasked */ | ||
122 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 2, 2); | ||
123 | |||
124 | /* DONE_POL to high */ | ||
125 | REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 3, 3); | ||
126 | |||
127 | /* DONE_MASK to unmasked */ | ||
128 | REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x0, 2, 2); | ||
129 | } | ||
130 | |||
131 | static void hdmi_core_ddc_uninit(struct hdmi_core_data *core) | ||
132 | { | ||
133 | void __iomem *base = core->base; | ||
134 | |||
135 | /* Mask I2C interrupts */ | ||
136 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); | ||
137 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); | ||
138 | REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); | ||
139 | } | ||
140 | |||
141 | static int hdmi_core_ddc_edid(struct hdmi_core_data *core, u8 *pedid, u8 ext) | ||
142 | { | ||
143 | void __iomem *base = core->base; | ||
144 | u8 cur_addr; | ||
145 | char checksum = 0; | ||
146 | const int retries = 1000; | ||
147 | u8 seg_ptr = ext / 2; | ||
148 | u8 edidbase = ((ext % 2) * 0x80); | ||
149 | |||
150 | REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGPTR, seg_ptr, 7, 0); | ||
151 | |||
152 | /* | ||
153 | * TODO: We use polling here, although we probably should use proper | ||
154 | * interrupts. | ||
155 | */ | ||
156 | for (cur_addr = 0; cur_addr < 128; ++cur_addr) { | ||
157 | int i; | ||
158 | |||
159 | /* clear ERROR and DONE */ | ||
160 | REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); | ||
161 | |||
162 | REG_FLD_MOD(base, HDMI_CORE_I2CM_ADDRESS, | ||
163 | edidbase + cur_addr, 7, 0); | ||
164 | |||
165 | if (seg_ptr) | ||
166 | REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 1, 1); | ||
167 | else | ||
168 | REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 0, 0); | ||
169 | |||
170 | for (i = 0; i < retries; ++i) { | ||
171 | u32 stat; | ||
172 | |||
173 | stat = REG_GET(base, HDMI_CORE_IH_I2CM_STAT0, 1, 0); | ||
174 | |||
175 | /* I2CM_ERROR */ | ||
176 | if (stat & 1) { | ||
177 | DSSERR("HDMI I2C Master Error\n"); | ||
178 | return -EIO; | ||
179 | } | ||
180 | |||
181 | /* I2CM_DONE */ | ||
182 | if (stat & (1 << 1)) | ||
183 | break; | ||
184 | |||
185 | usleep_range(250, 1000); | ||
186 | } | ||
187 | |||
188 | if (i == retries) { | ||
189 | DSSERR("HDMI I2C timeout reading EDID\n"); | ||
190 | return -EIO; | ||
191 | } | ||
192 | |||
193 | pedid[cur_addr] = REG_GET(base, HDMI_CORE_I2CM_DATAI, 7, 0); | ||
194 | checksum += pedid[cur_addr]; | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | |||
199 | } | ||
200 | |||
201 | int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len) | ||
202 | { | ||
203 | int r, n, i; | ||
204 | int max_ext_blocks = (len / 128) - 1; | ||
205 | |||
206 | if (len < 128) | ||
207 | return -EINVAL; | ||
208 | |||
209 | hdmi_core_ddc_init(core); | ||
210 | |||
211 | r = hdmi_core_ddc_edid(core, edid, 0); | ||
212 | if (r) | ||
213 | goto out; | ||
214 | |||
215 | n = edid[0x7e]; | ||
216 | |||
217 | if (n > max_ext_blocks) | ||
218 | n = max_ext_blocks; | ||
219 | |||
220 | for (i = 1; i <= n; i++) { | ||
221 | r = hdmi_core_ddc_edid(core, edid + i * EDID_LENGTH, i); | ||
222 | if (r) | ||
223 | goto out; | ||
224 | } | ||
225 | |||
226 | out: | ||
227 | hdmi_core_ddc_uninit(core); | ||
228 | |||
229 | return r ? r : len; | ||
230 | } | ||
231 | |||
232 | void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s) | ||
233 | { | ||
234 | |||
235 | #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ | ||
236 | hdmi_read_reg(core->base, r)) | ||
237 | |||
238 | DUMPCORE(HDMI_CORE_FC_INVIDCONF); | ||
239 | DUMPCORE(HDMI_CORE_FC_INHACTIV0); | ||
240 | DUMPCORE(HDMI_CORE_FC_INHACTIV1); | ||
241 | DUMPCORE(HDMI_CORE_FC_INHBLANK0); | ||
242 | DUMPCORE(HDMI_CORE_FC_INHBLANK1); | ||
243 | DUMPCORE(HDMI_CORE_FC_INVACTIV0); | ||
244 | DUMPCORE(HDMI_CORE_FC_INVACTIV1); | ||
245 | DUMPCORE(HDMI_CORE_FC_INVBLANK); | ||
246 | DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY0); | ||
247 | DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY1); | ||
248 | DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH0); | ||
249 | DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH1); | ||
250 | DUMPCORE(HDMI_CORE_FC_VSYNCINDELAY); | ||
251 | DUMPCORE(HDMI_CORE_FC_VSYNCINWIDTH); | ||
252 | DUMPCORE(HDMI_CORE_FC_CTRLDUR); | ||
253 | DUMPCORE(HDMI_CORE_FC_EXCTRLDUR); | ||
254 | DUMPCORE(HDMI_CORE_FC_EXCTRLSPAC); | ||
255 | DUMPCORE(HDMI_CORE_FC_CH0PREAM); | ||
256 | DUMPCORE(HDMI_CORE_FC_CH1PREAM); | ||
257 | DUMPCORE(HDMI_CORE_FC_CH2PREAM); | ||
258 | DUMPCORE(HDMI_CORE_FC_AVICONF0); | ||
259 | DUMPCORE(HDMI_CORE_FC_AVICONF1); | ||
260 | DUMPCORE(HDMI_CORE_FC_AVICONF2); | ||
261 | DUMPCORE(HDMI_CORE_FC_AVIVID); | ||
262 | DUMPCORE(HDMI_CORE_FC_PRCONF); | ||
263 | |||
264 | DUMPCORE(HDMI_CORE_MC_CLKDIS); | ||
265 | DUMPCORE(HDMI_CORE_MC_SWRSTZREQ); | ||
266 | DUMPCORE(HDMI_CORE_MC_FLOWCTRL); | ||
267 | DUMPCORE(HDMI_CORE_MC_PHYRSTZ); | ||
268 | DUMPCORE(HDMI_CORE_MC_LOCKONCLOCK); | ||
269 | |||
270 | DUMPCORE(HDMI_CORE_I2CM_SLAVE); | ||
271 | DUMPCORE(HDMI_CORE_I2CM_ADDRESS); | ||
272 | DUMPCORE(HDMI_CORE_I2CM_DATAO); | ||
273 | DUMPCORE(HDMI_CORE_I2CM_DATAI); | ||
274 | DUMPCORE(HDMI_CORE_I2CM_OPERATION); | ||
275 | DUMPCORE(HDMI_CORE_I2CM_INT); | ||
276 | DUMPCORE(HDMI_CORE_I2CM_CTLINT); | ||
277 | DUMPCORE(HDMI_CORE_I2CM_DIV); | ||
278 | DUMPCORE(HDMI_CORE_I2CM_SEGADDR); | ||
279 | DUMPCORE(HDMI_CORE_I2CM_SOFTRSTZ); | ||
280 | DUMPCORE(HDMI_CORE_I2CM_SEGPTR); | ||
281 | DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR); | ||
282 | DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR); | ||
283 | DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR); | ||
284 | DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR); | ||
285 | DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR); | ||
286 | DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR); | ||
287 | DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR); | ||
288 | DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR); | ||
289 | DUMPCORE(HDMI_CORE_I2CM_SDA_HOLD_ADDR); | ||
290 | } | ||
291 | |||
292 | static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, | ||
293 | struct hdmi_core_infoframe_avi *avi_cfg, | ||
294 | struct hdmi_config *cfg) | ||
295 | { | ||
296 | DSSDBG("hdmi_core_init\n"); | ||
297 | |||
298 | /* video core */ | ||
299 | video_cfg->data_enable_pol = 1; /* It is always 1*/ | ||
300 | video_cfg->v_fc_config.timings.hsync_level = cfg->timings.hsync_level; | ||
301 | video_cfg->v_fc_config.timings.x_res = cfg->timings.x_res; | ||
302 | video_cfg->v_fc_config.timings.hsw = cfg->timings.hsw - 1; | ||
303 | video_cfg->v_fc_config.timings.hbp = cfg->timings.hbp; | ||
304 | video_cfg->v_fc_config.timings.hfp = cfg->timings.hfp; | ||
305 | video_cfg->hblank = cfg->timings.hfp + | ||
306 | cfg->timings.hbp + cfg->timings.hsw - 1; | ||
307 | video_cfg->v_fc_config.timings.vsync_level = cfg->timings.vsync_level; | ||
308 | video_cfg->v_fc_config.timings.y_res = cfg->timings.y_res; | ||
309 | video_cfg->v_fc_config.timings.vsw = cfg->timings.vsw; | ||
310 | video_cfg->v_fc_config.timings.vfp = cfg->timings.vfp; | ||
311 | video_cfg->v_fc_config.timings.vbp = cfg->timings.vbp; | ||
312 | video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */ | ||
313 | video_cfg->vblank = cfg->timings.vsw + | ||
314 | cfg->timings.vfp + cfg->timings.vbp; | ||
315 | video_cfg->v_fc_config.cm.mode = cfg->cm.mode; | ||
316 | video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace; | ||
317 | |||
318 | /* info frame */ | ||
319 | avi_cfg->db1_format = 0; | ||
320 | avi_cfg->db1_active_info = 0; | ||
321 | avi_cfg->db1_bar_info_dv = 0; | ||
322 | avi_cfg->db1_scan_info = 0; | ||
323 | avi_cfg->db2_colorimetry = 0; | ||
324 | avi_cfg->db2_aspect_ratio = 0; | ||
325 | avi_cfg->db2_active_fmt_ar = 0; | ||
326 | avi_cfg->db3_itc = 0; | ||
327 | avi_cfg->db3_ec = 0; | ||
328 | avi_cfg->db3_q_range = 0; | ||
329 | avi_cfg->db3_nup_scaling = 0; | ||
330 | avi_cfg->db4_videocode = 0; | ||
331 | avi_cfg->db5_pixel_repeat = 0; | ||
332 | avi_cfg->db6_7_line_eoftop = 0; | ||
333 | avi_cfg->db8_9_line_sofbottom = 0; | ||
334 | avi_cfg->db10_11_pixel_eofleft = 0; | ||
335 | avi_cfg->db12_13_pixel_sofright = 0; | ||
336 | } | ||
337 | |||
338 | /* DSS_HDMI_CORE_VIDEO_CONFIG */ | ||
339 | static void hdmi_core_video_config(struct hdmi_core_data *core, | ||
340 | struct hdmi_core_vid_config *cfg) | ||
341 | { | ||
342 | void __iomem *base = core->base; | ||
343 | unsigned char r = 0; | ||
344 | bool vsync_pol, hsync_pol; | ||
345 | |||
346 | vsync_pol = | ||
347 | cfg->v_fc_config.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; | ||
348 | hsync_pol = | ||
349 | cfg->v_fc_config.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; | ||
350 | |||
351 | /* Set hsync, vsync and data-enable polarity */ | ||
352 | r = hdmi_read_reg(base, HDMI_CORE_FC_INVIDCONF); | ||
353 | r = FLD_MOD(r, vsync_pol, 6, 6); | ||
354 | r = FLD_MOD(r, hsync_pol, 5, 5); | ||
355 | r = FLD_MOD(r, cfg->data_enable_pol, 4, 4); | ||
356 | r = FLD_MOD(r, cfg->vblank_osc, 1, 1); | ||
357 | r = FLD_MOD(r, cfg->v_fc_config.timings.interlace, 0, 0); | ||
358 | hdmi_write_reg(base, HDMI_CORE_FC_INVIDCONF, r); | ||
359 | |||
360 | /* set x resolution */ | ||
361 | REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV1, | ||
362 | cfg->v_fc_config.timings.x_res >> 8, 4, 0); | ||
363 | REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV0, | ||
364 | cfg->v_fc_config.timings.x_res & 0xFF, 7, 0); | ||
365 | |||
366 | /* set y resolution */ | ||
367 | REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV1, | ||
368 | cfg->v_fc_config.timings.y_res >> 8, 4, 0); | ||
369 | REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV0, | ||
370 | cfg->v_fc_config.timings.y_res & 0xFF, 7, 0); | ||
371 | |||
372 | /* set horizontal blanking pixels */ | ||
373 | REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK1, cfg->hblank >> 8, 4, 0); | ||
374 | REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK0, cfg->hblank & 0xFF, 7, 0); | ||
375 | |||
376 | /* set vertial blanking pixels */ | ||
377 | REG_FLD_MOD(base, HDMI_CORE_FC_INVBLANK, cfg->vblank, 7, 0); | ||
378 | |||
379 | /* set horizontal sync offset */ | ||
380 | REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY1, | ||
381 | cfg->v_fc_config.timings.hfp >> 8, 4, 0); | ||
382 | REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY0, | ||
383 | cfg->v_fc_config.timings.hfp & 0xFF, 7, 0); | ||
384 | |||
385 | /* set vertical sync offset */ | ||
386 | REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINDELAY, | ||
387 | cfg->v_fc_config.timings.vfp, 7, 0); | ||
388 | |||
389 | /* set horizontal sync pulse width */ | ||
390 | REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH1, | ||
391 | (cfg->v_fc_config.timings.hsw >> 8), 1, 0); | ||
392 | REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH0, | ||
393 | cfg->v_fc_config.timings.hsw & 0xFF, 7, 0); | ||
394 | |||
395 | /* set vertical sync pulse width */ | ||
396 | REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINWIDTH, | ||
397 | cfg->v_fc_config.timings.vsw, 5, 0); | ||
398 | |||
399 | /* select DVI mode */ | ||
400 | REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF, | ||
401 | cfg->v_fc_config.cm.mode, 3, 3); | ||
402 | } | ||
403 | |||
404 | static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core) | ||
405 | { | ||
406 | void __iomem *base = core->base; | ||
407 | int clr_depth = 0; /* 24 bit color depth */ | ||
408 | |||
409 | /* COLOR_DEPTH */ | ||
410 | REG_FLD_MOD(base, HDMI_CORE_VP_PR_CD, clr_depth, 7, 4); | ||
411 | /* BYPASS_EN */ | ||
412 | REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 1, 6, 6); | ||
413 | /* PP_EN */ | ||
414 | REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 1 : 0, 5, 5); | ||
415 | /* YCC422_EN */ | ||
416 | REG_FLD_MOD(base, HDMI_CORE_VP_CONF, 0, 3, 3); | ||
417 | /* PP_STUFFING */ | ||
418 | REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, clr_depth ? 1 : 0, 1, 1); | ||
419 | /* YCC422_STUFFING */ | ||
420 | REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, 1, 2, 2); | ||
421 | /* OUTPUT_SELECTOR */ | ||
422 | REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 2, 1, 0); | ||
423 | } | ||
424 | |||
425 | static void hdmi_core_config_csc(struct hdmi_core_data *core) | ||
426 | { | ||
427 | int clr_depth = 0; /* 24 bit color depth */ | ||
428 | |||
429 | /* CSC_COLORDEPTH */ | ||
430 | REG_FLD_MOD(core->base, HDMI_CORE_CSC_SCALE, clr_depth, 7, 4); | ||
431 | } | ||
432 | |||
433 | static void hdmi_core_config_video_sampler(struct hdmi_core_data *core) | ||
434 | { | ||
435 | int video_mapping = 1; /* for 24 bit color depth */ | ||
436 | |||
437 | /* VIDEO_MAPPING */ | ||
438 | REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0); | ||
439 | } | ||
440 | |||
441 | static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) | ||
442 | { | ||
443 | void __iomem *base = core->base; | ||
444 | struct hdmi_core_infoframe_avi avi = core->avi_cfg; | ||
445 | |||
446 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0); | ||
447 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6); | ||
448 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2); | ||
449 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4); | ||
450 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6); | ||
451 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4); | ||
452 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0); | ||
453 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7); | ||
454 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4); | ||
455 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2); | ||
456 | REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0); | ||
457 | REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0); | ||
458 | REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0); | ||
459 | } | ||
460 | |||
461 | static void hdmi_core_csc_config(struct hdmi_core_data *core, | ||
462 | struct csc_table csc_coeff) | ||
463 | { | ||
464 | void __iomem *base = core->base; | ||
465 | |||
466 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_MSB, csc_coeff.a1 >> 8 , 6, 0); | ||
467 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_LSB, csc_coeff.a1, 7, 0); | ||
468 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_MSB, csc_coeff.a2 >> 8, 6, 0); | ||
469 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_LSB, csc_coeff.a2, 7, 0); | ||
470 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_MSB, csc_coeff.a3 >> 8, 6, 0); | ||
471 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_LSB, csc_coeff.a3, 7, 0); | ||
472 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_MSB, csc_coeff.a4 >> 8, 6, 0); | ||
473 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_LSB, csc_coeff.a4, 7, 0); | ||
474 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_MSB, csc_coeff.b1 >> 8, 6, 0); | ||
475 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_LSB, csc_coeff.b1, 7, 0); | ||
476 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_MSB, csc_coeff.b2 >> 8, 6, 0); | ||
477 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_LSB, csc_coeff.b2, 7, 0); | ||
478 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_MSB, csc_coeff.b3 >> 8, 6, 0); | ||
479 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_LSB, csc_coeff.b3, 7, 0); | ||
480 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_MSB, csc_coeff.b4 >> 8, 6, 0); | ||
481 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_LSB, csc_coeff.b4, 7, 0); | ||
482 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_MSB, csc_coeff.c1 >> 8, 6, 0); | ||
483 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_LSB, csc_coeff.c1, 7, 0); | ||
484 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_MSB, csc_coeff.c2 >> 8, 6, 0); | ||
485 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_LSB, csc_coeff.c2, 7, 0); | ||
486 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_MSB, csc_coeff.c3 >> 8, 6, 0); | ||
487 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_LSB, csc_coeff.c3, 7, 0); | ||
488 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_MSB, csc_coeff.c4 >> 8, 6, 0); | ||
489 | REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_LSB, csc_coeff.c4, 7, 0); | ||
490 | |||
491 | REG_FLD_MOD(base, HDMI_CORE_MC_FLOWCTRL, 0x1, 0, 0); | ||
492 | } | ||
493 | |||
494 | static void hdmi_core_configure_range(struct hdmi_core_data *core) | ||
495 | { | ||
496 | struct csc_table csc_coeff = { 0 }; | ||
497 | |||
498 | /* support limited range with 24 bit color depth for now */ | ||
499 | csc_coeff = csc_table_deepcolor[0]; | ||
500 | core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR; | ||
501 | |||
502 | hdmi_core_csc_config(core, csc_coeff); | ||
503 | hdmi_core_aux_infoframe_avi_config(core); | ||
504 | } | ||
505 | |||
506 | static void hdmi_core_enable_video_path(struct hdmi_core_data *core) | ||
507 | { | ||
508 | void __iomem *base = core->base; | ||
509 | |||
510 | DSSDBG("hdmi_core_enable_video_path\n"); | ||
511 | |||
512 | REG_FLD_MOD(base, HDMI_CORE_FC_CTRLDUR, 0x0C, 7, 0); | ||
513 | REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLDUR, 0x20, 7, 0); | ||
514 | REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLSPAC, 0x01, 7, 0); | ||
515 | REG_FLD_MOD(base, HDMI_CORE_FC_CH0PREAM, 0x0B, 7, 0); | ||
516 | REG_FLD_MOD(base, HDMI_CORE_FC_CH1PREAM, 0x16, 5, 0); | ||
517 | REG_FLD_MOD(base, HDMI_CORE_FC_CH2PREAM, 0x21, 5, 0); | ||
518 | REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 0, 0); | ||
519 | REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 1, 1); | ||
520 | } | ||
521 | |||
522 | static void hdmi_core_mask_interrupts(struct hdmi_core_data *core) | ||
523 | { | ||
524 | void __iomem *base = core->base; | ||
525 | |||
526 | /* Master IRQ mask */ | ||
527 | REG_FLD_MOD(base, HDMI_CORE_IH_MUTE, 0x3, 1, 0); | ||
528 | |||
529 | /* Mask all the interrupts in HDMI core */ | ||
530 | |||
531 | REG_FLD_MOD(base, HDMI_CORE_VP_MASK, 0xff, 7, 0); | ||
532 | REG_FLD_MOD(base, HDMI_CORE_FC_MASK0, 0xe7, 7, 0); | ||
533 | REG_FLD_MOD(base, HDMI_CORE_FC_MASK1, 0xfb, 7, 0); | ||
534 | REG_FLD_MOD(base, HDMI_CORE_FC_MASK2, 0x3, 1, 0); | ||
535 | |||
536 | REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 0x3, 3, 2); | ||
537 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 0x3, 1, 0); | ||
538 | |||
539 | REG_FLD_MOD(base, HDMI_CORE_CEC_MASK, 0x7f, 6, 0); | ||
540 | |||
541 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); | ||
542 | REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); | ||
543 | REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); | ||
544 | |||
545 | REG_FLD_MOD(base, HDMI_CORE_PHY_MASK0, 0xf3, 7, 0); | ||
546 | |||
547 | REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); | ||
548 | |||
549 | /* Clear all the current interrupt bits */ | ||
550 | |||
551 | REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); | ||
552 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xe7, 7, 0); | ||
553 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xfb, 7, 0); | ||
554 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0x3, 1, 0); | ||
555 | |||
556 | REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0x7, 2, 0); | ||
557 | |||
558 | REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0x7f, 6, 0); | ||
559 | |||
560 | REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); | ||
561 | |||
562 | REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); | ||
563 | } | ||
564 | |||
565 | static void hdmi_core_enable_interrupts(struct hdmi_core_data *core) | ||
566 | { | ||
567 | /* Unmute interrupts */ | ||
568 | REG_FLD_MOD(core->base, HDMI_CORE_IH_MUTE, 0x0, 1, 0); | ||
569 | } | ||
570 | |||
571 | int hdmi5_core_handle_irqs(struct hdmi_core_data *core) | ||
572 | { | ||
573 | void __iomem *base = core->base; | ||
574 | |||
575 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xff, 7, 0); | ||
576 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xff, 7, 0); | ||
577 | REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0xff, 7, 0); | ||
578 | REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0xff, 7, 0); | ||
579 | REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); | ||
580 | REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0xff, 7, 0); | ||
581 | REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0xff, 7, 0); | ||
582 | REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); | ||
583 | REG_FLD_MOD(base, HDMI_CORE_IH_I2CMPHY_STAT0, 0xff, 7, 0); | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | ||
589 | struct hdmi_config *cfg) | ||
590 | { | ||
591 | struct omap_video_timings video_timing; | ||
592 | struct hdmi_video_format video_format; | ||
593 | struct hdmi_core_vid_config v_core_cfg; | ||
594 | struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; | ||
595 | |||
596 | hdmi_core_mask_interrupts(core); | ||
597 | |||
598 | hdmi_core_init(&v_core_cfg, avi_cfg, cfg); | ||
599 | |||
600 | hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); | ||
601 | |||
602 | hdmi_wp_video_config_timing(wp, &video_timing); | ||
603 | |||
604 | /* video config */ | ||
605 | video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; | ||
606 | |||
607 | hdmi_wp_video_config_format(wp, &video_format); | ||
608 | |||
609 | hdmi_wp_video_config_interface(wp, &video_timing); | ||
610 | |||
611 | hdmi_core_configure_range(core); | ||
612 | |||
613 | /* | ||
614 | * configure core video part, set software reset in the core | ||
615 | */ | ||
616 | v_core_cfg.packet_mode = HDMI_PACKETMODE24BITPERPIXEL; | ||
617 | |||
618 | hdmi_core_video_config(core, &v_core_cfg); | ||
619 | |||
620 | hdmi_core_config_video_packetizer(core); | ||
621 | hdmi_core_config_csc(core); | ||
622 | hdmi_core_config_video_sampler(core); | ||
623 | |||
624 | /* | ||
625 | * configure packet info frame video see doc CEA861-D page 65 | ||
626 | */ | ||
627 | avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; | ||
628 | avi_cfg->db1_active_info = | ||
629 | HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; | ||
630 | avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; | ||
631 | avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; | ||
632 | avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; | ||
633 | avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; | ||
634 | avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; | ||
635 | avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; | ||
636 | avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; | ||
637 | avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; | ||
638 | avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; | ||
639 | avi_cfg->db4_videocode = cfg->cm.code; | ||
640 | avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; | ||
641 | avi_cfg->db6_7_line_eoftop = 0; | ||
642 | avi_cfg->db8_9_line_sofbottom = 0; | ||
643 | avi_cfg->db10_11_pixel_eofleft = 0; | ||
644 | avi_cfg->db12_13_pixel_sofright = 0; | ||
645 | |||
646 | hdmi_core_aux_infoframe_avi_config(core); | ||
647 | |||
648 | hdmi_core_enable_video_path(core); | ||
649 | |||
650 | hdmi_core_enable_interrupts(core); | ||
651 | } | ||
652 | |||
653 | |||
654 | #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) | ||
655 | |||
656 | static void hdmi5_core_audio_config(struct hdmi_core_data *core, | ||
657 | struct hdmi_core_audio_config *cfg) | ||
658 | { | ||
659 | void __iomem *base = core->base; | ||
660 | u8 val; | ||
661 | |||
662 | /* Mute audio before configuring */ | ||
663 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0xf, 7, 4); | ||
664 | |||
665 | /* Set the N parameter */ | ||
666 | REG_FLD_MOD(base, HDMI_CORE_AUD_N1, cfg->n, 7, 0); | ||
667 | REG_FLD_MOD(base, HDMI_CORE_AUD_N2, cfg->n >> 8, 7, 0); | ||
668 | REG_FLD_MOD(base, HDMI_CORE_AUD_N3, cfg->n >> 16, 3, 0); | ||
669 | |||
670 | /* | ||
671 | * CTS manual mode. Automatic mode is not supported when using audio | ||
672 | * parallel interface. | ||
673 | */ | ||
674 | REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, 1, 4, 4); | ||
675 | REG_FLD_MOD(base, HDMI_CORE_AUD_CTS1, cfg->cts, 7, 0); | ||
676 | REG_FLD_MOD(base, HDMI_CORE_AUD_CTS2, cfg->cts >> 8, 7, 0); | ||
677 | REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, cfg->cts >> 16, 3, 0); | ||
678 | |||
679 | /* Layout of Audio Sample Packets: 2-channel or multichannels */ | ||
680 | if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) | ||
681 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0, 0, 0); | ||
682 | else | ||
683 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 1, 0, 0); | ||
684 | |||
685 | /* Configure IEC-609580 Validity bits */ | ||
686 | /* Channel 0 is valid */ | ||
687 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 0, 0); | ||
688 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 4, 4); | ||
689 | |||
690 | if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) | ||
691 | val = 1; | ||
692 | else | ||
693 | val = 0; | ||
694 | |||
695 | /* Channels 1, 2 setting */ | ||
696 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 1, 1); | ||
697 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 5, 5); | ||
698 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 2, 2); | ||
699 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 6, 6); | ||
700 | /* Channel 3 setting */ | ||
701 | if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) | ||
702 | val = 1; | ||
703 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 3, 3); | ||
704 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 7, 7); | ||
705 | |||
706 | /* Configure IEC-60958 User bits */ | ||
707 | /* TODO: should be set by user. */ | ||
708 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSU, 0, 7, 0); | ||
709 | |||
710 | /* Configure IEC-60958 Channel Status word */ | ||
711 | /* CGMSA */ | ||
712 | val = cfg->iec60958_cfg->status[5] & IEC958_AES5_CON_CGMSA; | ||
713 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 5, 4); | ||
714 | |||
715 | /* Copyright */ | ||
716 | val = (cfg->iec60958_cfg->status[0] & | ||
717 | IEC958_AES0_CON_NOT_COPYRIGHT) >> 2; | ||
718 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 0, 0); | ||
719 | |||
720 | /* Category */ | ||
721 | hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(1), | ||
722 | cfg->iec60958_cfg->status[1]); | ||
723 | |||
724 | /* PCM audio mode */ | ||
725 | val = (cfg->iec60958_cfg->status[0] & IEC958_AES0_CON_MODE) >> 6; | ||
726 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 6, 4); | ||
727 | |||
728 | /* Source number */ | ||
729 | val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE; | ||
730 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 4); | ||
731 | |||
732 | /* Channel number right 0 */ | ||
733 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0); | ||
734 | /* Channel number right 1*/ | ||
735 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 4, 7, 4); | ||
736 | /* Channel number right 2 */ | ||
737 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 6, 3, 0); | ||
738 | /* Channel number right 3*/ | ||
739 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 8, 7, 4); | ||
740 | /* Channel number left 0 */ | ||
741 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 1, 3, 0); | ||
742 | /* Channel number left 1*/ | ||
743 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 3, 7, 4); | ||
744 | /* Channel number left 2 */ | ||
745 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 5, 3, 0); | ||
746 | /* Channel number left 3*/ | ||
747 | REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 7, 7, 4); | ||
748 | |||
749 | /* Clock accuracy and sample rate */ | ||
750 | hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(7), | ||
751 | cfg->iec60958_cfg->status[3]); | ||
752 | |||
753 | /* Original sample rate and word length */ | ||
754 | hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(8), | ||
755 | cfg->iec60958_cfg->status[4]); | ||
756 | |||
757 | /* Enable FIFO empty and full interrupts */ | ||
758 | REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 3, 3, 2); | ||
759 | |||
760 | /* Configure GPA */ | ||
761 | /* select HBR/SPDIF interfaces */ | ||
762 | if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) { | ||
763 | /* select HBR/SPDIF interfaces */ | ||
764 | REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); | ||
765 | /* enable two channels in GPA */ | ||
766 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 3, 7, 0); | ||
767 | } else if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) { | ||
768 | /* select HBR/SPDIF interfaces */ | ||
769 | REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); | ||
770 | /* enable six channels in GPA */ | ||
771 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0x3F, 7, 0); | ||
772 | } else { | ||
773 | /* select HBR/SPDIF interfaces */ | ||
774 | REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); | ||
775 | /* enable eight channels in GPA */ | ||
776 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0xFF, 7, 0); | ||
777 | } | ||
778 | |||
779 | /* disable HBR */ | ||
780 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 0, 0, 0); | ||
781 | /* enable PCUV */ | ||
782 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 1, 1, 1); | ||
783 | /* enable GPA FIFO full and empty mask */ | ||
784 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 3, 1, 0); | ||
785 | /* set polarity of GPA FIFO empty interrupts */ | ||
786 | REG_FLD_MOD(base, HDMI_CORE_AUD_GP_POL, 1, 0, 0); | ||
787 | |||
788 | /* unmute audio */ | ||
789 | REG_FLD_MOD(core_sys_base, HDMI_CORE_FC_AUDSCONF, 0, 7, 4); | ||
790 | } | ||
791 | |||
792 | static void hdmi5_core_audio_infoframe_cfg(struct hdmi_core_data *core, | ||
793 | struct snd_cea_861_aud_if *info_aud) | ||
794 | { | ||
795 | void __iomem *base = core->base; | ||
796 | |||
797 | /* channel count and coding type fields in AUDICONF0 are swapped */ | ||
798 | hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF0, | ||
799 | (info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) << 4 | | ||
800 | (info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CT) >> 4); | ||
801 | |||
802 | hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss); | ||
803 | hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca); | ||
804 | hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud->db5_dminh_lsv); | ||
805 | } | ||
806 | |||
807 | int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | ||
808 | struct omap_dss_audio *audio, u32 pclk) | ||
809 | { | ||
810 | struct hdmi_audio_format audio_format; | ||
811 | struct hdmi_audio_dma audio_dma; | ||
812 | struct hdmi_core_audio_config core_cfg; | ||
813 | int err, n, cts, channel_count; | ||
814 | unsigned int fs_nr; | ||
815 | bool word_length_16b = false; | ||
816 | |||
817 | if (!audio || !audio->iec || !audio->cea || !core) | ||
818 | return -EINVAL; | ||
819 | |||
820 | core_cfg.iec60958_cfg = audio->iec; | ||
821 | |||
822 | if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) && | ||
823 | (audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16)) | ||
824 | word_length_16b = true; | ||
825 | |||
826 | /* only 16-bit word length supported atm */ | ||
827 | if (!word_length_16b) | ||
828 | return -EINVAL; | ||
829 | |||
830 | switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { | ||
831 | case IEC958_AES3_CON_FS_32000: | ||
832 | fs_nr = 32000; | ||
833 | break; | ||
834 | case IEC958_AES3_CON_FS_44100: | ||
835 | fs_nr = 44100; | ||
836 | break; | ||
837 | case IEC958_AES3_CON_FS_48000: | ||
838 | fs_nr = 48000; | ||
839 | break; | ||
840 | case IEC958_AES3_CON_FS_88200: | ||
841 | fs_nr = 88200; | ||
842 | break; | ||
843 | case IEC958_AES3_CON_FS_96000: | ||
844 | fs_nr = 96000; | ||
845 | break; | ||
846 | case IEC958_AES3_CON_FS_176400: | ||
847 | fs_nr = 176400; | ||
848 | break; | ||
849 | case IEC958_AES3_CON_FS_192000: | ||
850 | fs_nr = 192000; | ||
851 | break; | ||
852 | default: | ||
853 | return -EINVAL; | ||
854 | } | ||
855 | |||
856 | err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); | ||
857 | core_cfg.n = n; | ||
858 | core_cfg.cts = cts; | ||
859 | |||
860 | /* Audio channels settings */ | ||
861 | channel_count = (audio->cea->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) | ||
862 | + 1; | ||
863 | |||
864 | if (channel_count == 2) | ||
865 | core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; | ||
866 | else if (channel_count == 6) | ||
867 | core_cfg.layout = HDMI_AUDIO_LAYOUT_6CH; | ||
868 | else | ||
869 | core_cfg.layout = HDMI_AUDIO_LAYOUT_8CH; | ||
870 | |||
871 | /* DMA settings */ | ||
872 | if (word_length_16b) | ||
873 | audio_dma.transfer_size = 0x10; | ||
874 | else | ||
875 | audio_dma.transfer_size = 0x20; | ||
876 | audio_dma.block_size = 0xC0; | ||
877 | audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; | ||
878 | audio_dma.fifo_threshold = 0x20; /* in number of samples */ | ||
879 | |||
880 | /* audio FIFO format settings for 16-bit samples*/ | ||
881 | audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; | ||
882 | audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; | ||
883 | audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; | ||
884 | |||
885 | /* only LPCM atm */ | ||
886 | audio_format.type = HDMI_AUDIO_TYPE_LPCM; | ||
887 | |||
888 | /* disable start/stop signals of IEC 60958 blocks */ | ||
889 | audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; | ||
890 | |||
891 | /* configure DMA and audio FIFO format*/ | ||
892 | hdmi_wp_audio_config_dma(wp, &audio_dma); | ||
893 | hdmi_wp_audio_config_format(wp, &audio_format); | ||
894 | |||
895 | /* configure the core */ | ||
896 | hdmi5_core_audio_config(core, &core_cfg); | ||
897 | |||
898 | /* configure CEA 861 audio infoframe */ | ||
899 | hdmi5_core_audio_infoframe_cfg(core, audio->cea); | ||
900 | |||
901 | return 0; | ||
902 | } | ||
903 | #endif | ||
904 | |||
905 | int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core) | ||
906 | { | ||
907 | struct resource *res; | ||
908 | |||
909 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); | ||
910 | if (!res) { | ||
911 | DSSERR("can't get CORE IORESOURCE_MEM HDMI\n"); | ||
912 | return -EINVAL; | ||
913 | } | ||
914 | |||
915 | core->base = devm_request_and_ioremap(&pdev->dev, res); | ||
916 | if (!core->base) { | ||
917 | DSSERR("can't ioremap HDMI core\n"); | ||
918 | return -ENOMEM; | ||
919 | } | ||
920 | |||
921 | return 0; | ||
922 | } | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.h b/drivers/video/fbdev/omap2/dss/hdmi5_core.h new file mode 100644 index 000000000000..ce7e9f376f04 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.h | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | * HDMI driver definition for TI OMAP5 processors. | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.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 version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifndef _HDMI5_CORE_H_ | ||
20 | #define _HDMI5_CORE_H_ | ||
21 | |||
22 | #include "hdmi.h" | ||
23 | |||
24 | /* HDMI IP Core System */ | ||
25 | |||
26 | /* HDMI Identification */ | ||
27 | #define HDMI_CORE_DESIGN_ID 0x00000 | ||
28 | #define HDMI_CORE_REVISION_ID 0x00004 | ||
29 | #define HDMI_CORE_PRODUCT_ID0 0x00008 | ||
30 | #define HDMI_CORE_PRODUCT_ID1 0x0000C | ||
31 | #define HDMI_CORE_CONFIG0_ID 0x00010 | ||
32 | #define HDMI_CORE_CONFIG1_ID 0x00014 | ||
33 | #define HDMI_CORE_CONFIG2_ID 0x00018 | ||
34 | #define HDMI_CORE_CONFIG3_ID 0x0001C | ||
35 | |||
36 | /* HDMI Interrupt */ | ||
37 | #define HDMI_CORE_IH_FC_STAT0 0x00400 | ||
38 | #define HDMI_CORE_IH_FC_STAT1 0x00404 | ||
39 | #define HDMI_CORE_IH_FC_STAT2 0x00408 | ||
40 | #define HDMI_CORE_IH_AS_STAT0 0x0040C | ||
41 | #define HDMI_CORE_IH_PHY_STAT0 0x00410 | ||
42 | #define HDMI_CORE_IH_I2CM_STAT0 0x00414 | ||
43 | #define HDMI_CORE_IH_CEC_STAT0 0x00418 | ||
44 | #define HDMI_CORE_IH_VP_STAT0 0x0041C | ||
45 | #define HDMI_CORE_IH_I2CMPHY_STAT0 0x00420 | ||
46 | #define HDMI_CORE_IH_MUTE 0x007FC | ||
47 | |||
48 | /* HDMI Video Sampler */ | ||
49 | #define HDMI_CORE_TX_INVID0 0x00800 | ||
50 | #define HDMI_CORE_TX_INSTUFFING 0x00804 | ||
51 | #define HDMI_CORE_TX_RGYDATA0 0x00808 | ||
52 | #define HDMI_CORE_TX_RGYDATA1 0x0080C | ||
53 | #define HDMI_CORE_TX_RCRDATA0 0x00810 | ||
54 | #define HDMI_CORE_TX_RCRDATA1 0x00814 | ||
55 | #define HDMI_CORE_TX_BCBDATA0 0x00818 | ||
56 | #define HDMI_CORE_TX_BCBDATA1 0x0081C | ||
57 | |||
58 | /* HDMI Video Packetizer */ | ||
59 | #define HDMI_CORE_VP_STATUS 0x02000 | ||
60 | #define HDMI_CORE_VP_PR_CD 0x02004 | ||
61 | #define HDMI_CORE_VP_STUFF 0x02008 | ||
62 | #define HDMI_CORE_VP_REMAP 0x0200C | ||
63 | #define HDMI_CORE_VP_CONF 0x02010 | ||
64 | #define HDMI_CORE_VP_STAT 0x02014 | ||
65 | #define HDMI_CORE_VP_INT 0x02018 | ||
66 | #define HDMI_CORE_VP_MASK 0x0201C | ||
67 | #define HDMI_CORE_VP_POL 0x02020 | ||
68 | |||
69 | /* Frame Composer */ | ||
70 | #define HDMI_CORE_FC_INVIDCONF 0x04000 | ||
71 | #define HDMI_CORE_FC_INHACTIV0 0x04004 | ||
72 | #define HDMI_CORE_FC_INHACTIV1 0x04008 | ||
73 | #define HDMI_CORE_FC_INHBLANK0 0x0400C | ||
74 | #define HDMI_CORE_FC_INHBLANK1 0x04010 | ||
75 | #define HDMI_CORE_FC_INVACTIV0 0x04014 | ||
76 | #define HDMI_CORE_FC_INVACTIV1 0x04018 | ||
77 | #define HDMI_CORE_FC_INVBLANK 0x0401C | ||
78 | #define HDMI_CORE_FC_HSYNCINDELAY0 0x04020 | ||
79 | #define HDMI_CORE_FC_HSYNCINDELAY1 0x04024 | ||
80 | #define HDMI_CORE_FC_HSYNCINWIDTH0 0x04028 | ||
81 | #define HDMI_CORE_FC_HSYNCINWIDTH1 0x0402C | ||
82 | #define HDMI_CORE_FC_VSYNCINDELAY 0x04030 | ||
83 | #define HDMI_CORE_FC_VSYNCINWIDTH 0x04034 | ||
84 | #define HDMI_CORE_FC_INFREQ0 0x04038 | ||
85 | #define HDMI_CORE_FC_INFREQ1 0x0403C | ||
86 | #define HDMI_CORE_FC_INFREQ2 0x04040 | ||
87 | #define HDMI_CORE_FC_CTRLDUR 0x04044 | ||
88 | #define HDMI_CORE_FC_EXCTRLDUR 0x04048 | ||
89 | #define HDMI_CORE_FC_EXCTRLSPAC 0x0404C | ||
90 | #define HDMI_CORE_FC_CH0PREAM 0x04050 | ||
91 | #define HDMI_CORE_FC_CH1PREAM 0x04054 | ||
92 | #define HDMI_CORE_FC_CH2PREAM 0x04058 | ||
93 | #define HDMI_CORE_FC_AVICONF3 0x0405C | ||
94 | #define HDMI_CORE_FC_GCP 0x04060 | ||
95 | #define HDMI_CORE_FC_AVICONF0 0x04064 | ||
96 | #define HDMI_CORE_FC_AVICONF1 0x04068 | ||
97 | #define HDMI_CORE_FC_AVICONF2 0x0406C | ||
98 | #define HDMI_CORE_FC_AVIVID 0x04070 | ||
99 | #define HDMI_CORE_FC_AVIETB0 0x04074 | ||
100 | #define HDMI_CORE_FC_AVIETB1 0x04078 | ||
101 | #define HDMI_CORE_FC_AVISBB0 0x0407C | ||
102 | #define HDMI_CORE_FC_AVISBB1 0x04080 | ||
103 | #define HDMI_CORE_FC_AVIELB0 0x04084 | ||
104 | #define HDMI_CORE_FC_AVIELB1 0x04088 | ||
105 | #define HDMI_CORE_FC_AVISRB0 0x0408C | ||
106 | #define HDMI_CORE_FC_AVISRB1 0x04090 | ||
107 | #define HDMI_CORE_FC_AUDICONF0 0x04094 | ||
108 | #define HDMI_CORE_FC_AUDICONF1 0x04098 | ||
109 | #define HDMI_CORE_FC_AUDICONF2 0x0409C | ||
110 | #define HDMI_CORE_FC_AUDICONF3 0x040A0 | ||
111 | #define HDMI_CORE_FC_VSDIEEEID0 0x040A4 | ||
112 | #define HDMI_CORE_FC_VSDSIZE 0x040A8 | ||
113 | #define HDMI_CORE_FC_VSDIEEEID1 0x040C0 | ||
114 | #define HDMI_CORE_FC_VSDIEEEID2 0x040C4 | ||
115 | #define HDMI_CORE_FC_VSDPAYLOAD(n) (n * 4 + 0x040C8) | ||
116 | #define HDMI_CORE_FC_SPDVENDORNAME(n) (n * 4 + 0x04128) | ||
117 | #define HDMI_CORE_FC_SPDPRODUCTNAME(n) (n * 4 + 0x04148) | ||
118 | #define HDMI_CORE_FC_SPDDEVICEINF 0x04188 | ||
119 | #define HDMI_CORE_FC_AUDSCONF 0x0418C | ||
120 | #define HDMI_CORE_FC_AUDSSTAT 0x04190 | ||
121 | #define HDMI_CORE_FC_AUDSV 0x04194 | ||
122 | #define HDMI_CORE_FC_AUDSU 0x04198 | ||
123 | #define HDMI_CORE_FC_AUDSCHNLS(n) (n * 4 + 0x0419C) | ||
124 | #define HDMI_CORE_FC_CTRLQHIGH 0x041CC | ||
125 | #define HDMI_CORE_FC_CTRLQLOW 0x041D0 | ||
126 | #define HDMI_CORE_FC_ACP0 0x041D4 | ||
127 | #define HDMI_CORE_FC_ACP(n) ((16-n) * 4 + 0x04208) | ||
128 | #define HDMI_CORE_FC_ISCR1_0 0x04248 | ||
129 | #define HDMI_CORE_FC_ISCR1(n) ((16-n) * 4 + 0x0424C) | ||
130 | #define HDMI_CORE_FC_ISCR2(n) ((15-n) * 4 + 0x0428C) | ||
131 | #define HDMI_CORE_FC_DATAUTO0 0x042CC | ||
132 | #define HDMI_CORE_FC_DATAUTO1 0x042D0 | ||
133 | #define HDMI_CORE_FC_DATAUTO2 0x042D4 | ||
134 | #define HDMI_CORE_FC_DATMAN 0x042D8 | ||
135 | #define HDMI_CORE_FC_DATAUTO3 0x042DC | ||
136 | #define HDMI_CORE_FC_RDRB(n) (n * 4 + 0x042E0) | ||
137 | #define HDMI_CORE_FC_STAT0 0x04340 | ||
138 | #define HDMI_CORE_FC_INT0 0x04344 | ||
139 | #define HDMI_CORE_FC_MASK0 0x04348 | ||
140 | #define HDMI_CORE_FC_POL0 0x0434C | ||
141 | #define HDMI_CORE_FC_STAT1 0x04350 | ||
142 | #define HDMI_CORE_FC_INT1 0x04354 | ||
143 | #define HDMI_CORE_FC_MASK1 0x04358 | ||
144 | #define HDMI_CORE_FC_POL1 0x0435C | ||
145 | #define HDMI_CORE_FC_STAT2 0x04360 | ||
146 | #define HDMI_CORE_FC_INT2 0x04364 | ||
147 | #define HDMI_CORE_FC_MASK2 0x04368 | ||
148 | #define HDMI_CORE_FC_POL2 0x0436C | ||
149 | #define HDMI_CORE_FC_PRCONF 0x04380 | ||
150 | #define HDMI_CORE_FC_GMD_STAT 0x04400 | ||
151 | #define HDMI_CORE_FC_GMD_EN 0x04404 | ||
152 | #define HDMI_CORE_FC_GMD_UP 0x04408 | ||
153 | #define HDMI_CORE_FC_GMD_CONF 0x0440C | ||
154 | #define HDMI_CORE_FC_GMD_HB 0x04410 | ||
155 | #define HDMI_CORE_FC_GMD_PB(n) (n * 4 + 0x04414) | ||
156 | #define HDMI_CORE_FC_DBGFORCE 0x04800 | ||
157 | #define HDMI_CORE_FC_DBGAUD0CH0 0x04804 | ||
158 | #define HDMI_CORE_FC_DBGAUD1CH0 0x04808 | ||
159 | #define HDMI_CORE_FC_DBGAUD2CH0 0x0480C | ||
160 | #define HDMI_CORE_FC_DBGAUD0CH1 0x04810 | ||
161 | #define HDMI_CORE_FC_DBGAUD1CH1 0x04814 | ||
162 | #define HDMI_CORE_FC_DBGAUD2CH1 0x04818 | ||
163 | #define HDMI_CORE_FC_DBGAUD0CH2 0x0481C | ||
164 | #define HDMI_CORE_FC_DBGAUD1CH2 0x04820 | ||
165 | #define HDMI_CORE_FC_DBGAUD2CH2 0x04824 | ||
166 | #define HDMI_CORE_FC_DBGAUD0CH3 0x04828 | ||
167 | #define HDMI_CORE_FC_DBGAUD1CH3 0x0482C | ||
168 | #define HDMI_CORE_FC_DBGAUD2CH3 0x04830 | ||
169 | #define HDMI_CORE_FC_DBGAUD0CH4 0x04834 | ||
170 | #define HDMI_CORE_FC_DBGAUD1CH4 0x04838 | ||
171 | #define HDMI_CORE_FC_DBGAUD2CH4 0x0483C | ||
172 | #define HDMI_CORE_FC_DBGAUD0CH5 0x04840 | ||
173 | #define HDMI_CORE_FC_DBGAUD1CH5 0x04844 | ||
174 | #define HDMI_CORE_FC_DBGAUD2CH5 0x04848 | ||
175 | #define HDMI_CORE_FC_DBGAUD0CH6 0x0484C | ||
176 | #define HDMI_CORE_FC_DBGAUD1CH6 0x04850 | ||
177 | #define HDMI_CORE_FC_DBGAUD2CH6 0x04854 | ||
178 | #define HDMI_CORE_FC_DBGAUD0CH7 0x04858 | ||
179 | #define HDMI_CORE_FC_DBGAUD1CH7 0x0485C | ||
180 | #define HDMI_CORE_FC_DBGAUD2CH7 0x04860 | ||
181 | #define HDMI_CORE_FC_DBGTMDS0 0x04864 | ||
182 | #define HDMI_CORE_FC_DBGTMDS1 0x04868 | ||
183 | #define HDMI_CORE_FC_DBGTMDS2 0x0486C | ||
184 | #define HDMI_CORE_PHY_MASK0 0x0C018 | ||
185 | #define HDMI_CORE_PHY_I2CM_INT_ADDR 0x0C09C | ||
186 | #define HDMI_CORE_PHY_I2CM_CTLINT_ADDR 0x0C0A0 | ||
187 | |||
188 | /* HDMI Audio */ | ||
189 | #define HDMI_CORE_AUD_CONF0 0x0C400 | ||
190 | #define HDMI_CORE_AUD_CONF1 0x0C404 | ||
191 | #define HDMI_CORE_AUD_INT 0x0C408 | ||
192 | #define HDMI_CORE_AUD_N1 0x0C800 | ||
193 | #define HDMI_CORE_AUD_N2 0x0C804 | ||
194 | #define HDMI_CORE_AUD_N3 0x0C808 | ||
195 | #define HDMI_CORE_AUD_CTS1 0x0C80C | ||
196 | #define HDMI_CORE_AUD_CTS2 0x0C810 | ||
197 | #define HDMI_CORE_AUD_CTS3 0x0C814 | ||
198 | #define HDMI_CORE_AUD_INCLKFS 0x0C818 | ||
199 | #define HDMI_CORE_AUD_CC08 0x0CC08 | ||
200 | #define HDMI_CORE_AUD_GP_CONF0 0x0D400 | ||
201 | #define HDMI_CORE_AUD_GP_CONF1 0x0D404 | ||
202 | #define HDMI_CORE_AUD_GP_CONF2 0x0D408 | ||
203 | #define HDMI_CORE_AUD_D010 0x0D010 | ||
204 | #define HDMI_CORE_AUD_GP_STAT 0x0D40C | ||
205 | #define HDMI_CORE_AUD_GP_INT 0x0D410 | ||
206 | #define HDMI_CORE_AUD_GP_POL 0x0D414 | ||
207 | #define HDMI_CORE_AUD_GP_MASK 0x0D418 | ||
208 | |||
209 | /* HDMI Main Controller */ | ||
210 | #define HDMI_CORE_MC_CLKDIS 0x10004 | ||
211 | #define HDMI_CORE_MC_SWRSTZREQ 0x10008 | ||
212 | #define HDMI_CORE_MC_FLOWCTRL 0x10010 | ||
213 | #define HDMI_CORE_MC_PHYRSTZ 0x10014 | ||
214 | #define HDMI_CORE_MC_LOCKONCLOCK 0x10018 | ||
215 | |||
216 | /* HDMI COLOR SPACE CONVERTER */ | ||
217 | #define HDMI_CORE_CSC_CFG 0x10400 | ||
218 | #define HDMI_CORE_CSC_SCALE 0x10404 | ||
219 | #define HDMI_CORE_CSC_COEF_A1_MSB 0x10408 | ||
220 | #define HDMI_CORE_CSC_COEF_A1_LSB 0x1040C | ||
221 | #define HDMI_CORE_CSC_COEF_A2_MSB 0x10410 | ||
222 | #define HDMI_CORE_CSC_COEF_A2_LSB 0x10414 | ||
223 | #define HDMI_CORE_CSC_COEF_A3_MSB 0x10418 | ||
224 | #define HDMI_CORE_CSC_COEF_A3_LSB 0x1041C | ||
225 | #define HDMI_CORE_CSC_COEF_A4_MSB 0x10420 | ||
226 | #define HDMI_CORE_CSC_COEF_A4_LSB 0x10424 | ||
227 | #define HDMI_CORE_CSC_COEF_B1_MSB 0x10428 | ||
228 | #define HDMI_CORE_CSC_COEF_B1_LSB 0x1042C | ||
229 | #define HDMI_CORE_CSC_COEF_B2_MSB 0x10430 | ||
230 | #define HDMI_CORE_CSC_COEF_B2_LSB 0x10434 | ||
231 | #define HDMI_CORE_CSC_COEF_B3_MSB 0x10438 | ||
232 | #define HDMI_CORE_CSC_COEF_B3_LSB 0x1043C | ||
233 | #define HDMI_CORE_CSC_COEF_B4_MSB 0x10440 | ||
234 | #define HDMI_CORE_CSC_COEF_B4_LSB 0x10444 | ||
235 | #define HDMI_CORE_CSC_COEF_C1_MSB 0x10448 | ||
236 | #define HDMI_CORE_CSC_COEF_C1_LSB 0x1044C | ||
237 | #define HDMI_CORE_CSC_COEF_C2_MSB 0x10450 | ||
238 | #define HDMI_CORE_CSC_COEF_C2_LSB 0x10454 | ||
239 | #define HDMI_CORE_CSC_COEF_C3_MSB 0x10458 | ||
240 | #define HDMI_CORE_CSC_COEF_C3_LSB 0x1045C | ||
241 | #define HDMI_CORE_CSC_COEF_C4_MSB 0x10460 | ||
242 | #define HDMI_CORE_CSC_COEF_C4_LSB 0x10464 | ||
243 | |||
244 | /* HDMI HDCP */ | ||
245 | #define HDMI_CORE_HDCP_MASK 0x14020 | ||
246 | |||
247 | /* HDMI CEC */ | ||
248 | #define HDMI_CORE_CEC_MASK 0x17408 | ||
249 | |||
250 | /* HDMI I2C Master */ | ||
251 | #define HDMI_CORE_I2CM_SLAVE 0x157C8 | ||
252 | #define HDMI_CORE_I2CM_ADDRESS 0x157CC | ||
253 | #define HDMI_CORE_I2CM_DATAO 0x157D0 | ||
254 | #define HDMI_CORE_I2CM_DATAI 0X157D4 | ||
255 | #define HDMI_CORE_I2CM_OPERATION 0x157D8 | ||
256 | #define HDMI_CORE_I2CM_INT 0x157DC | ||
257 | #define HDMI_CORE_I2CM_CTLINT 0x157E0 | ||
258 | #define HDMI_CORE_I2CM_DIV 0x157E4 | ||
259 | #define HDMI_CORE_I2CM_SEGADDR 0x157E8 | ||
260 | #define HDMI_CORE_I2CM_SOFTRSTZ 0x157EC | ||
261 | #define HDMI_CORE_I2CM_SEGPTR 0x157F0 | ||
262 | #define HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR 0x157F4 | ||
263 | #define HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR 0x157F8 | ||
264 | #define HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR 0x157FC | ||
265 | #define HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR 0x15800 | ||
266 | #define HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR 0x15804 | ||
267 | #define HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR 0x15808 | ||
268 | #define HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR 0x1580C | ||
269 | #define HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR 0x15810 | ||
270 | #define HDMI_CORE_I2CM_SDA_HOLD_ADDR 0x15814 | ||
271 | |||
272 | enum hdmi_core_packet_mode { | ||
273 | HDMI_PACKETMODERESERVEDVALUE = 0, | ||
274 | HDMI_PACKETMODE24BITPERPIXEL = 4, | ||
275 | HDMI_PACKETMODE30BITPERPIXEL = 5, | ||
276 | HDMI_PACKETMODE36BITPERPIXEL = 6, | ||
277 | HDMI_PACKETMODE48BITPERPIXEL = 7, | ||
278 | }; | ||
279 | |||
280 | struct hdmi_core_vid_config { | ||
281 | struct hdmi_config v_fc_config; | ||
282 | enum hdmi_core_packet_mode packet_mode; | ||
283 | int data_enable_pol; | ||
284 | int vblank_osc; | ||
285 | int hblank; | ||
286 | int vblank; | ||
287 | }; | ||
288 | |||
289 | struct csc_table { | ||
290 | u16 a1, a2, a3, a4; | ||
291 | u16 b1, b2, b3, b4; | ||
292 | u16 c1, c2, c3, c4; | ||
293 | }; | ||
294 | |||
295 | int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len); | ||
296 | void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s); | ||
297 | int hdmi5_core_handle_irqs(struct hdmi_core_data *core); | ||
298 | void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | ||
299 | struct hdmi_config *cfg); | ||
300 | int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core); | ||
301 | |||
302 | #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) | ||
303 | int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, | ||
304 | struct omap_dss_audio *audio, u32 pclk); | ||
305 | #endif | ||
306 | #endif | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c index f5f4ccf50d90..a16a190e191d 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c | |||
@@ -185,7 +185,7 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, | |||
185 | timings->interlace = param->timings.interlace; | 185 | timings->interlace = param->timings.interlace; |
186 | } | 186 | } |
187 | 187 | ||
188 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 188 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) |
189 | void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, | 189 | void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, |
190 | struct hdmi_audio_format *aud_fmt) | 190 | struct hdmi_audio_format *aud_fmt) |
191 | { | 191 | { |