Commit 19a82b85245289d95cde2fb7715fe562ae700f59

Authored by Jyri Sarha
1 parent e533720df3

OMAPDSS: HDMI: Do not abort audio playback when display is turned off

Do not abort audio playback when display is turned off. The audio DMA
stops when the display turned off and the audio stream will timeout in
couple of seconds unless the display is enabled again in time. Without
this patch the audio playback is aborted immediately when display is
turned off.

Signed-off-by: Jyri Sarha <jsarha@ti.com>

Showing 2 changed files with 4 additions and 4 deletions Inline Diff

drivers/video/fbdev/omap2/dss/hdmi4.c
1 /* 1 /*
2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs. 2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs.
3 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ 3 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
4 * Authors: Yong Zhi 4 * Authors: Yong Zhi
5 * Mythri pk <mythripk@ti.com> 5 * Mythri pk <mythripk@ti.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 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 8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT 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 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details. 14 * more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along with 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/>. 17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20 #define DSS_SUBSYS_NAME "HDMI" 20 #define DSS_SUBSYS_NAME "HDMI"
21 21
22 #include <linux/kernel.h> 22 #include <linux/kernel.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/err.h> 24 #include <linux/err.h>
25 #include <linux/io.h> 25 #include <linux/io.h>
26 #include <linux/interrupt.h> 26 #include <linux/interrupt.h>
27 #include <linux/mutex.h> 27 #include <linux/mutex.h>
28 #include <linux/delay.h> 28 #include <linux/delay.h>
29 #include <linux/string.h> 29 #include <linux/string.h>
30 #include <linux/platform_device.h> 30 #include <linux/platform_device.h>
31 #include <linux/pm_runtime.h> 31 #include <linux/pm_runtime.h>
32 #include <linux/clk.h> 32 #include <linux/clk.h>
33 #include <linux/gpio.h> 33 #include <linux/gpio.h>
34 #include <linux/regulator/consumer.h> 34 #include <linux/regulator/consumer.h>
35 #include <video/omapdss.h> 35 #include <video/omapdss.h>
36 #include <sound/omap-hdmi-audio.h> 36 #include <sound/omap-hdmi-audio.h>
37 37
38 #include "hdmi4_core.h" 38 #include "hdmi4_core.h"
39 #include "dss.h" 39 #include "dss.h"
40 #include "dss_features.h" 40 #include "dss_features.h"
41 #include "hdmi.h" 41 #include "hdmi.h"
42 42
43 static struct omap_hdmi hdmi; 43 static struct omap_hdmi hdmi;
44 44
45 static int hdmi_runtime_get(void) 45 static int hdmi_runtime_get(void)
46 { 46 {
47 int r; 47 int r;
48 48
49 DSSDBG("hdmi_runtime_get\n"); 49 DSSDBG("hdmi_runtime_get\n");
50 50
51 r = pm_runtime_get_sync(&hdmi.pdev->dev); 51 r = pm_runtime_get_sync(&hdmi.pdev->dev);
52 WARN_ON(r < 0); 52 WARN_ON(r < 0);
53 if (r < 0) 53 if (r < 0)
54 return r; 54 return r;
55 55
56 return 0; 56 return 0;
57 } 57 }
58 58
59 static void hdmi_runtime_put(void) 59 static void hdmi_runtime_put(void)
60 { 60 {
61 int r; 61 int r;
62 62
63 DSSDBG("hdmi_runtime_put\n"); 63 DSSDBG("hdmi_runtime_put\n");
64 64
65 r = pm_runtime_put_sync(&hdmi.pdev->dev); 65 r = pm_runtime_put_sync(&hdmi.pdev->dev);
66 WARN_ON(r < 0 && r != -ENOSYS); 66 WARN_ON(r < 0 && r != -ENOSYS);
67 } 67 }
68 68
69 static irqreturn_t hdmi_irq_handler(int irq, void *data) 69 static irqreturn_t hdmi_irq_handler(int irq, void *data)
70 { 70 {
71 struct hdmi_wp_data *wp = data; 71 struct hdmi_wp_data *wp = data;
72 u32 irqstatus; 72 u32 irqstatus;
73 73
74 irqstatus = hdmi_wp_get_irqstatus(wp); 74 irqstatus = hdmi_wp_get_irqstatus(wp);
75 hdmi_wp_set_irqstatus(wp, irqstatus); 75 hdmi_wp_set_irqstatus(wp, irqstatus);
76 76
77 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 77 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
78 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 78 irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
79 /* 79 /*
80 * If we get both connect and disconnect interrupts at the same 80 * If we get both connect and disconnect interrupts at the same
81 * time, turn off the PHY, clear interrupts, and restart, which 81 * time, turn off the PHY, clear interrupts, and restart, which
82 * raises connect interrupt if a cable is connected, or nothing 82 * raises connect interrupt if a cable is connected, or nothing
83 * if cable is not connected. 83 * if cable is not connected.
84 */ 84 */
85 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 85 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
86 86
87 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 87 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
88 HDMI_IRQ_LINK_DISCONNECT); 88 HDMI_IRQ_LINK_DISCONNECT);
89 89
90 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 90 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
91 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 91 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
92 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 92 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
93 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 93 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
94 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 94 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
95 } 95 }
96 96
97 return IRQ_HANDLED; 97 return IRQ_HANDLED;
98 } 98 }
99 99
100 static int hdmi_init_regulator(void) 100 static int hdmi_init_regulator(void)
101 { 101 {
102 int r; 102 int r;
103 struct regulator *reg; 103 struct regulator *reg;
104 104
105 if (hdmi.vdda_reg != NULL) 105 if (hdmi.vdda_reg != NULL)
106 return 0; 106 return 0;
107 107
108 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 108 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
109 109
110 if (IS_ERR(reg)) { 110 if (IS_ERR(reg)) {
111 if (PTR_ERR(reg) != -EPROBE_DEFER) 111 if (PTR_ERR(reg) != -EPROBE_DEFER)
112 DSSERR("can't get VDDA regulator\n"); 112 DSSERR("can't get VDDA regulator\n");
113 return PTR_ERR(reg); 113 return PTR_ERR(reg);
114 } 114 }
115 115
116 if (regulator_can_change_voltage(reg)) { 116 if (regulator_can_change_voltage(reg)) {
117 r = regulator_set_voltage(reg, 1800000, 1800000); 117 r = regulator_set_voltage(reg, 1800000, 1800000);
118 if (r) { 118 if (r) {
119 devm_regulator_put(reg); 119 devm_regulator_put(reg);
120 DSSWARN("can't set the regulator voltage\n"); 120 DSSWARN("can't set the regulator voltage\n");
121 return r; 121 return r;
122 } 122 }
123 } 123 }
124 124
125 hdmi.vdda_reg = reg; 125 hdmi.vdda_reg = reg;
126 126
127 return 0; 127 return 0;
128 } 128 }
129 129
130 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp, 130 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp,
131 struct pll_params *p) 131 struct pll_params *p)
132 { 132 {
133 u16 r = 0; 133 u16 r = 0;
134 134
135 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 135 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
136 if (r) 136 if (r)
137 return r; 137 return r;
138 138
139 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 139 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
140 if (r) 140 if (r)
141 return r; 141 return r;
142 142
143 pll_sysreset(pll); 143 pll_sysreset(pll);
144 144
145 r = pll_wait_reset(pll); 145 r = pll_wait_reset(pll);
146 if (r) 146 if (r)
147 return r; 147 return r;
148 148
149 r = pll_calc_and_check_clock_rates(pll, p); 149 r = pll_calc_and_check_clock_rates(pll, p);
150 if (r) 150 if (r)
151 return r; 151 return r;
152 152
153 r = pll_set_clock_div(pll, p); 153 r = pll_set_clock_div(pll, p);
154 if (r) 154 if (r)
155 return r; 155 return r;
156 156
157 return 0; 157 return 0;
158 } 158 }
159 159
160 static void hdmi_pll_disable(struct hdmi_wp_data *wp) 160 static void hdmi_pll_disable(struct hdmi_wp_data *wp)
161 { 161 {
162 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 162 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
163 } 163 }
164 164
165 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 165 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
166 { 166 {
167 int r; 167 int r;
168 168
169 r = regulator_enable(hdmi.vdda_reg); 169 r = regulator_enable(hdmi.vdda_reg);
170 if (r) 170 if (r)
171 return r; 171 return r;
172 172
173 r = hdmi_runtime_get(); 173 r = hdmi_runtime_get();
174 if (r) 174 if (r)
175 goto err_runtime_get; 175 goto err_runtime_get;
176 176
177 /* Make selection of HDMI in DSS */ 177 /* Make selection of HDMI in DSS */
178 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 178 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
179 179
180 hdmi.core_enabled = true; 180 hdmi.core_enabled = true;
181 181
182 return 0; 182 return 0;
183 183
184 err_runtime_get: 184 err_runtime_get:
185 regulator_disable(hdmi.vdda_reg); 185 regulator_disable(hdmi.vdda_reg);
186 186
187 return r; 187 return r;
188 } 188 }
189 189
190 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 190 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
191 { 191 {
192 hdmi.core_enabled = false; 192 hdmi.core_enabled = false;
193 193
194 hdmi_runtime_put(); 194 hdmi_runtime_put();
195 regulator_disable(hdmi.vdda_reg); 195 regulator_disable(hdmi.vdda_reg);
196 } 196 }
197 197
198 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 198 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
199 { 199 {
200 int r; 200 int r;
201 struct omap_video_timings *p; 201 struct omap_video_timings *p;
202 struct omap_overlay_manager *mgr = hdmi.output.manager; 202 struct omap_overlay_manager *mgr = hdmi.output.manager;
203 unsigned long phy; 203 unsigned long phy;
204 struct hdmi_wp_data *wp = &hdmi.wp; 204 struct hdmi_wp_data *wp = &hdmi.wp;
205 struct pll_params param; 205 struct pll_params param;
206 bool ok; 206 bool ok;
207 207
208 r = hdmi_power_on_core(dssdev); 208 r = hdmi_power_on_core(dssdev);
209 if (r) 209 if (r)
210 return r; 210 return r;
211 211
212 /* disable and clear irqs */ 212 /* disable and clear irqs */
213 hdmi_wp_clear_irqenable(wp, 0xffffffff); 213 hdmi_wp_clear_irqenable(wp, 0xffffffff);
214 hdmi_wp_set_irqstatus(wp, 0xffffffff); 214 hdmi_wp_set_irqstatus(wp, 0xffffffff);
215 215
216 p = &hdmi.cfg.timings; 216 p = &hdmi.cfg.timings;
217 217
218 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 218 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
219 219
220 phy = p->pixelclock * 10; 220 phy = p->pixelclock * 10;
221 221
222 memset(&param, 0, sizeof(param)); 222 memset(&param, 0, sizeof(param));
223 223
224 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param); 224 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param);
225 if (!ok) { 225 if (!ok) {
226 DSSDBG("Failed to calculate PLL settings\n"); 226 DSSDBG("Failed to calculate PLL settings\n");
227 goto err_pll_enable; 227 goto err_pll_enable;
228 } 228 }
229 229
230 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 230 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
231 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param); 231 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param);
232 if (r) { 232 if (r) {
233 DSSDBG("Failed to lock PLL\n"); 233 DSSDBG("Failed to lock PLL\n");
234 goto err_pll_enable; 234 goto err_pll_enable;
235 } 235 }
236 236
237 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 237 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
238 if (r) { 238 if (r) {
239 DSSDBG("Failed to configure PHY\n"); 239 DSSDBG("Failed to configure PHY\n");
240 goto err_phy_cfg; 240 goto err_phy_cfg;
241 } 241 }
242 242
243 r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 243 r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
244 if (r) 244 if (r)
245 goto err_phy_pwr; 245 goto err_phy_pwr;
246 246
247 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 247 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
248 248
249 /* bypass TV gamma table */ 249 /* bypass TV gamma table */
250 dispc_enable_gamma_table(0); 250 dispc_enable_gamma_table(0);
251 251
252 /* tv size */ 252 /* tv size */
253 dss_mgr_set_timings(mgr, p); 253 dss_mgr_set_timings(mgr, p);
254 254
255 r = dss_mgr_enable(mgr); 255 r = dss_mgr_enable(mgr);
256 if (r) 256 if (r)
257 goto err_mgr_enable; 257 goto err_mgr_enable;
258 258
259 r = hdmi_wp_video_start(&hdmi.wp); 259 r = hdmi_wp_video_start(&hdmi.wp);
260 if (r) 260 if (r)
261 goto err_vid_enable; 261 goto err_vid_enable;
262 262
263 hdmi_wp_set_irqenable(wp, 263 hdmi_wp_set_irqenable(wp,
264 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 264 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
265 265
266 return 0; 266 return 0;
267 267
268 err_vid_enable: 268 err_vid_enable:
269 dss_mgr_disable(mgr); 269 dss_mgr_disable(mgr);
270 err_mgr_enable: 270 err_mgr_enable:
271 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 271 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
272 err_phy_pwr: 272 err_phy_pwr:
273 err_phy_cfg: 273 err_phy_cfg:
274 hdmi_pll_disable(&hdmi.wp); 274 hdmi_pll_disable(&hdmi.wp);
275 err_pll_enable: 275 err_pll_enable:
276 hdmi_power_off_core(dssdev); 276 hdmi_power_off_core(dssdev);
277 return -EIO; 277 return -EIO;
278 } 278 }
279 279
280 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 280 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
281 { 281 {
282 struct omap_overlay_manager *mgr = hdmi.output.manager; 282 struct omap_overlay_manager *mgr = hdmi.output.manager;
283 283
284 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 284 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
285 285
286 hdmi_wp_video_stop(&hdmi.wp); 286 hdmi_wp_video_stop(&hdmi.wp);
287 287
288 dss_mgr_disable(mgr); 288 dss_mgr_disable(mgr);
289 289
290 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 290 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
291 291
292 hdmi_pll_disable(&hdmi.wp); 292 hdmi_pll_disable(&hdmi.wp);
293 293
294 hdmi_power_off_core(dssdev); 294 hdmi_power_off_core(dssdev);
295 } 295 }
296 296
297 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 297 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
298 struct omap_video_timings *timings) 298 struct omap_video_timings *timings)
299 { 299 {
300 struct omap_dss_device *out = &hdmi.output; 300 struct omap_dss_device *out = &hdmi.output;
301 301
302 if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) 302 if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
303 return -EINVAL; 303 return -EINVAL;
304 304
305 return 0; 305 return 0;
306 } 306 }
307 307
308 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 308 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
309 struct omap_video_timings *timings) 309 struct omap_video_timings *timings)
310 { 310 {
311 mutex_lock(&hdmi.lock); 311 mutex_lock(&hdmi.lock);
312 312
313 hdmi.cfg.timings = *timings; 313 hdmi.cfg.timings = *timings;
314 314
315 dispc_set_tv_pclk(timings->pixelclock); 315 dispc_set_tv_pclk(timings->pixelclock);
316 316
317 mutex_unlock(&hdmi.lock); 317 mutex_unlock(&hdmi.lock);
318 } 318 }
319 319
320 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 320 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
321 struct omap_video_timings *timings) 321 struct omap_video_timings *timings)
322 { 322 {
323 *timings = hdmi.cfg.timings; 323 *timings = hdmi.cfg.timings;
324 } 324 }
325 325
326 static void hdmi_dump_regs(struct seq_file *s) 326 static void hdmi_dump_regs(struct seq_file *s)
327 { 327 {
328 mutex_lock(&hdmi.lock); 328 mutex_lock(&hdmi.lock);
329 329
330 if (hdmi_runtime_get()) { 330 if (hdmi_runtime_get()) {
331 mutex_unlock(&hdmi.lock); 331 mutex_unlock(&hdmi.lock);
332 return; 332 return;
333 } 333 }
334 334
335 hdmi_wp_dump(&hdmi.wp, s); 335 hdmi_wp_dump(&hdmi.wp, s);
336 pll_dump(hdmi.pll, s); 336 pll_dump(hdmi.pll, s);
337 hdmi_phy_dump(&hdmi.phy, s); 337 hdmi_phy_dump(&hdmi.phy, s);
338 hdmi4_core_dump(&hdmi.core, s); 338 hdmi4_core_dump(&hdmi.core, s);
339 339
340 hdmi_runtime_put(); 340 hdmi_runtime_put();
341 mutex_unlock(&hdmi.lock); 341 mutex_unlock(&hdmi.lock);
342 } 342 }
343 343
344 static int read_edid(u8 *buf, int len) 344 static int read_edid(u8 *buf, int len)
345 { 345 {
346 int r; 346 int r;
347 347
348 mutex_lock(&hdmi.lock); 348 mutex_lock(&hdmi.lock);
349 349
350 r = hdmi_runtime_get(); 350 r = hdmi_runtime_get();
351 BUG_ON(r); 351 BUG_ON(r);
352 352
353 r = hdmi4_read_edid(&hdmi.core, buf, len); 353 r = hdmi4_read_edid(&hdmi.core, buf, len);
354 354
355 hdmi_runtime_put(); 355 hdmi_runtime_put();
356 mutex_unlock(&hdmi.lock); 356 mutex_unlock(&hdmi.lock);
357 357
358 return r; 358 return r;
359 } 359 }
360 360
361 static int hdmi_display_enable(struct omap_dss_device *dssdev) 361 static int hdmi_display_enable(struct omap_dss_device *dssdev)
362 { 362 {
363 struct omap_dss_device *out = &hdmi.output; 363 struct omap_dss_device *out = &hdmi.output;
364 int r = 0; 364 int r = 0;
365 365
366 DSSDBG("ENTER hdmi_display_enable\n"); 366 DSSDBG("ENTER hdmi_display_enable\n");
367 367
368 mutex_lock(&hdmi.lock); 368 mutex_lock(&hdmi.lock);
369 369
370 if (out == NULL || out->manager == NULL) { 370 if (out == NULL || out->manager == NULL) {
371 DSSERR("failed to enable display: no output/manager\n"); 371 DSSERR("failed to enable display: no output/manager\n");
372 r = -ENODEV; 372 r = -ENODEV;
373 goto err0; 373 goto err0;
374 } 374 }
375 375
376 r = hdmi_power_on_full(dssdev); 376 r = hdmi_power_on_full(dssdev);
377 if (r) { 377 if (r) {
378 DSSERR("failed to power on device\n"); 378 DSSERR("failed to power on device\n");
379 goto err0; 379 goto err0;
380 } 380 }
381 381
382 hdmi.display_enabled = true; 382 hdmi.display_enabled = true;
383 383
384 mutex_unlock(&hdmi.lock); 384 mutex_unlock(&hdmi.lock);
385 return 0; 385 return 0;
386 386
387 err0: 387 err0:
388 mutex_unlock(&hdmi.lock); 388 mutex_unlock(&hdmi.lock);
389 return r; 389 return r;
390 } 390 }
391 391
392 static void hdmi_display_disable(struct omap_dss_device *dssdev) 392 static void hdmi_display_disable(struct omap_dss_device *dssdev)
393 { 393 {
394 DSSDBG("Enter hdmi_display_disable\n"); 394 DSSDBG("Enter hdmi_display_disable\n");
395 395
396 mutex_lock(&hdmi.lock); 396 mutex_lock(&hdmi.lock);
397 397
398 if (hdmi.audio_abort_cb) 398 /* If set hdmi.audio_abort_cb(&hdmi.pdev->dev) should be
399 hdmi.audio_abort_cb(&hdmi.pdev->dev); 399 * called here, if audio abort functionality is needed. */
400 400
401 hdmi_power_off_full(dssdev); 401 hdmi_power_off_full(dssdev);
402 402
403 hdmi.display_enabled = false; 403 hdmi.display_enabled = false;
404 404
405 mutex_unlock(&hdmi.lock); 405 mutex_unlock(&hdmi.lock);
406 } 406 }
407 407
408 static int hdmi_core_enable(struct omap_dss_device *dssdev) 408 static int hdmi_core_enable(struct omap_dss_device *dssdev)
409 { 409 {
410 int r = 0; 410 int r = 0;
411 411
412 DSSDBG("ENTER omapdss_hdmi_core_enable\n"); 412 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
413 413
414 mutex_lock(&hdmi.lock); 414 mutex_lock(&hdmi.lock);
415 415
416 r = hdmi_power_on_core(dssdev); 416 r = hdmi_power_on_core(dssdev);
417 if (r) { 417 if (r) {
418 DSSERR("failed to power on device\n"); 418 DSSERR("failed to power on device\n");
419 goto err0; 419 goto err0;
420 } 420 }
421 421
422 mutex_unlock(&hdmi.lock); 422 mutex_unlock(&hdmi.lock);
423 return 0; 423 return 0;
424 424
425 err0: 425 err0:
426 mutex_unlock(&hdmi.lock); 426 mutex_unlock(&hdmi.lock);
427 return r; 427 return r;
428 } 428 }
429 429
430 static void hdmi_core_disable(struct omap_dss_device *dssdev) 430 static void hdmi_core_disable(struct omap_dss_device *dssdev)
431 { 431 {
432 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 432 DSSDBG("Enter omapdss_hdmi_core_disable\n");
433 433
434 mutex_lock(&hdmi.lock); 434 mutex_lock(&hdmi.lock);
435 435
436 hdmi_power_off_core(dssdev); 436 hdmi_power_off_core(dssdev);
437 437
438 mutex_unlock(&hdmi.lock); 438 mutex_unlock(&hdmi.lock);
439 } 439 }
440 440
441 static int hdmi_connect(struct omap_dss_device *dssdev, 441 static int hdmi_connect(struct omap_dss_device *dssdev,
442 struct omap_dss_device *dst) 442 struct omap_dss_device *dst)
443 { 443 {
444 struct omap_overlay_manager *mgr; 444 struct omap_overlay_manager *mgr;
445 int r; 445 int r;
446 446
447 r = hdmi_init_regulator(); 447 r = hdmi_init_regulator();
448 if (r) 448 if (r)
449 return r; 449 return r;
450 450
451 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); 451 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
452 if (!mgr) 452 if (!mgr)
453 return -ENODEV; 453 return -ENODEV;
454 454
455 r = dss_mgr_connect(mgr, dssdev); 455 r = dss_mgr_connect(mgr, dssdev);
456 if (r) 456 if (r)
457 return r; 457 return r;
458 458
459 r = omapdss_output_set_device(dssdev, dst); 459 r = omapdss_output_set_device(dssdev, dst);
460 if (r) { 460 if (r) {
461 DSSERR("failed to connect output to new device: %s\n", 461 DSSERR("failed to connect output to new device: %s\n",
462 dst->name); 462 dst->name);
463 dss_mgr_disconnect(mgr, dssdev); 463 dss_mgr_disconnect(mgr, dssdev);
464 return r; 464 return r;
465 } 465 }
466 466
467 return 0; 467 return 0;
468 } 468 }
469 469
470 static void hdmi_disconnect(struct omap_dss_device *dssdev, 470 static void hdmi_disconnect(struct omap_dss_device *dssdev,
471 struct omap_dss_device *dst) 471 struct omap_dss_device *dst)
472 { 472 {
473 WARN_ON(dst != dssdev->dst); 473 WARN_ON(dst != dssdev->dst);
474 474
475 if (dst != dssdev->dst) 475 if (dst != dssdev->dst)
476 return; 476 return;
477 477
478 omapdss_output_unset_device(dssdev); 478 omapdss_output_unset_device(dssdev);
479 479
480 if (dssdev->manager) 480 if (dssdev->manager)
481 dss_mgr_disconnect(dssdev->manager, dssdev); 481 dss_mgr_disconnect(dssdev->manager, dssdev);
482 } 482 }
483 483
484 static int hdmi_read_edid(struct omap_dss_device *dssdev, 484 static int hdmi_read_edid(struct omap_dss_device *dssdev,
485 u8 *edid, int len) 485 u8 *edid, int len)
486 { 486 {
487 bool need_enable; 487 bool need_enable;
488 int r; 488 int r;
489 489
490 need_enable = hdmi.core_enabled == false; 490 need_enable = hdmi.core_enabled == false;
491 491
492 if (need_enable) { 492 if (need_enable) {
493 r = hdmi_core_enable(dssdev); 493 r = hdmi_core_enable(dssdev);
494 if (r) 494 if (r)
495 return r; 495 return r;
496 } 496 }
497 497
498 r = read_edid(edid, len); 498 r = read_edid(edid, len);
499 499
500 if (need_enable) 500 if (need_enable)
501 hdmi_core_disable(dssdev); 501 hdmi_core_disable(dssdev);
502 502
503 return r; 503 return r;
504 } 504 }
505 505
506 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 506 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
507 const struct hdmi_avi_infoframe *avi) 507 const struct hdmi_avi_infoframe *avi)
508 { 508 {
509 hdmi.cfg.infoframe = *avi; 509 hdmi.cfg.infoframe = *avi;
510 return 0; 510 return 0;
511 } 511 }
512 512
513 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 513 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
514 bool hdmi_mode) 514 bool hdmi_mode)
515 { 515 {
516 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 516 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
517 return 0; 517 return 0;
518 } 518 }
519 519
520 static const struct omapdss_hdmi_ops hdmi_ops = { 520 static const struct omapdss_hdmi_ops hdmi_ops = {
521 .connect = hdmi_connect, 521 .connect = hdmi_connect,
522 .disconnect = hdmi_disconnect, 522 .disconnect = hdmi_disconnect,
523 523
524 .enable = hdmi_display_enable, 524 .enable = hdmi_display_enable,
525 .disable = hdmi_display_disable, 525 .disable = hdmi_display_disable,
526 526
527 .check_timings = hdmi_display_check_timing, 527 .check_timings = hdmi_display_check_timing,
528 .set_timings = hdmi_display_set_timing, 528 .set_timings = hdmi_display_set_timing,
529 .get_timings = hdmi_display_get_timings, 529 .get_timings = hdmi_display_get_timings,
530 530
531 .read_edid = hdmi_read_edid, 531 .read_edid = hdmi_read_edid,
532 .set_infoframe = hdmi_set_infoframe, 532 .set_infoframe = hdmi_set_infoframe,
533 .set_hdmi_mode = hdmi_set_hdmi_mode, 533 .set_hdmi_mode = hdmi_set_hdmi_mode,
534 }; 534 };
535 535
536 static void hdmi_init_output(struct platform_device *pdev) 536 static void hdmi_init_output(struct platform_device *pdev)
537 { 537 {
538 struct omap_dss_device *out = &hdmi.output; 538 struct omap_dss_device *out = &hdmi.output;
539 539
540 out->dev = &pdev->dev; 540 out->dev = &pdev->dev;
541 out->id = OMAP_DSS_OUTPUT_HDMI; 541 out->id = OMAP_DSS_OUTPUT_HDMI;
542 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 542 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
543 out->name = "hdmi.0"; 543 out->name = "hdmi.0";
544 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 544 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
545 out->ops.hdmi = &hdmi_ops; 545 out->ops.hdmi = &hdmi_ops;
546 out->owner = THIS_MODULE; 546 out->owner = THIS_MODULE;
547 547
548 omapdss_register_output(out); 548 omapdss_register_output(out);
549 } 549 }
550 550
551 static void __exit hdmi_uninit_output(struct platform_device *pdev) 551 static void __exit hdmi_uninit_output(struct platform_device *pdev)
552 { 552 {
553 struct omap_dss_device *out = &hdmi.output; 553 struct omap_dss_device *out = &hdmi.output;
554 554
555 omapdss_unregister_output(out); 555 omapdss_unregister_output(out);
556 } 556 }
557 557
558 static int hdmi_probe_of(struct platform_device *pdev) 558 static int hdmi_probe_of(struct platform_device *pdev)
559 { 559 {
560 struct device_node *node = pdev->dev.of_node; 560 struct device_node *node = pdev->dev.of_node;
561 struct device_node *ep; 561 struct device_node *ep;
562 int r; 562 int r;
563 563
564 ep = omapdss_of_get_first_endpoint(node); 564 ep = omapdss_of_get_first_endpoint(node);
565 if (!ep) 565 if (!ep)
566 return 0; 566 return 0;
567 567
568 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 568 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
569 if (r) 569 if (r)
570 goto err; 570 goto err;
571 571
572 of_node_put(ep); 572 of_node_put(ep);
573 return 0; 573 return 0;
574 574
575 err: 575 err:
576 of_node_put(ep); 576 of_node_put(ep);
577 return r; 577 return r;
578 } 578 }
579 579
580 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 580 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
581 static int audio_startup(struct device *dev, 581 static int audio_startup(struct device *dev,
582 void (*abort_cb)(struct device *dev)) 582 void (*abort_cb)(struct device *dev))
583 { 583 {
584 struct omap_hdmi *hd = dev_get_drvdata(dev); 584 struct omap_hdmi *hd = dev_get_drvdata(dev);
585 int ret = 0; 585 int ret = 0;
586 586
587 mutex_lock(&hd->lock); 587 mutex_lock(&hd->lock);
588 588
589 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 589 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
590 ret = -EPERM; 590 ret = -EPERM;
591 goto out; 591 goto out;
592 } 592 }
593 593
594 hd->audio_abort_cb = abort_cb; 594 hd->audio_abort_cb = abort_cb;
595 595
596 out: 596 out:
597 mutex_unlock(&hd->lock); 597 mutex_unlock(&hd->lock);
598 598
599 return ret; 599 return ret;
600 } 600 }
601 601
602 static int audio_enable(struct device *dev, bool enable) 602 static int audio_enable(struct device *dev, bool enable)
603 { 603 {
604 struct omap_hdmi *hd = dev_get_drvdata(dev); 604 struct omap_hdmi *hd = dev_get_drvdata(dev);
605 int ret; 605 int ret;
606 606
607 mutex_lock(&hd->lock); 607 mutex_lock(&hd->lock);
608 608
609 ret = hdmi_wp_audio_enable(&hd->wp, enable); 609 ret = hdmi_wp_audio_enable(&hd->wp, enable);
610 610
611 if (!enable) 611 if (!enable)
612 hd->audio_abort_cb = NULL; 612 hd->audio_abort_cb = NULL;
613 613
614 mutex_unlock(&hd->lock); 614 mutex_unlock(&hd->lock);
615 615
616 return ret; 616 return ret;
617 } 617 }
618 618
619 static int audio_start(struct device *dev, bool enable) 619 static int audio_start(struct device *dev, bool enable)
620 { 620 {
621 struct omap_hdmi *hd = dev_get_drvdata(dev); 621 struct omap_hdmi *hd = dev_get_drvdata(dev);
622 int ret = 0; 622 int ret = 0;
623 623
624 if (enable) 624 if (enable)
625 ret = hdmi4_audio_start(&hd->core, &hd->wp); 625 ret = hdmi4_audio_start(&hd->core, &hd->wp);
626 else 626 else
627 hdmi4_audio_stop(&hd->core, &hd->wp); 627 hdmi4_audio_stop(&hd->core, &hd->wp);
628 628
629 return ret; 629 return ret;
630 } 630 }
631 631
632 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio) 632 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio)
633 { 633 {
634 struct omap_hdmi *hd = dev_get_drvdata(dev); 634 struct omap_hdmi *hd = dev_get_drvdata(dev);
635 int ret; 635 int ret;
636 636
637 mutex_lock(&hd->lock); 637 mutex_lock(&hd->lock);
638 if (!hdmi_mode_has_audio(&hd->cfg)) 638 if (!hdmi_mode_has_audio(&hd->cfg))
639 ret = -EPERM; 639 ret = -EPERM;
640 else 640 else
641 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio, 641 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
642 hd->cfg.timings.pixelclock); 642 hd->cfg.timings.pixelclock);
643 mutex_unlock(&hd->lock); 643 mutex_unlock(&hd->lock);
644 644
645 return ret; 645 return ret;
646 } 646 }
647 647
648 static int hdmi_audio_register(struct device *dev) 648 static int hdmi_audio_register(struct device *dev)
649 { 649 {
650 struct omap_hdmi_audio ha = { 650 struct omap_hdmi_audio ha = {
651 .dev = dev, 651 .dev = dev,
652 .hw_version = OMAP4_HDMI, 652 .hw_version = OMAP4_HDMI,
653 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 653 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
654 .audio_startup = audio_startup, 654 .audio_startup = audio_startup,
655 .audio_enable = audio_enable, 655 .audio_enable = audio_enable,
656 .audio_start = audio_start, 656 .audio_start = audio_start,
657 .audio_config = audio_config, 657 .audio_config = audio_config,
658 }; 658 };
659 659
660 return omap_hdmi_audio_register(&ha); 660 return omap_hdmi_audio_register(&ha);
661 } 661 }
662 #else /* CONFIG_OMAP4_DSS_HDMI_AUDIO */ 662 #else /* CONFIG_OMAP4_DSS_HDMI_AUDIO */
663 static int hdmi_audio_register(struct device *dev) 663 static int hdmi_audio_register(struct device *dev)
664 { 664 {
665 return 0; 665 return 0;
666 } 666 }
667 #endif 667 #endif
668 668
669 /* HDMI HW IP initialisation */ 669 /* HDMI HW IP initialisation */
670 static int omapdss_hdmihw_probe(struct platform_device *pdev) 670 static int omapdss_hdmihw_probe(struct platform_device *pdev)
671 { 671 {
672 int r; 672 int r;
673 int irq; 673 int irq;
674 674
675 hdmi.pdev = pdev; 675 hdmi.pdev = pdev;
676 dev_set_drvdata(&pdev->dev, &hdmi); 676 dev_set_drvdata(&pdev->dev, &hdmi);
677 677
678 mutex_init(&hdmi.lock); 678 mutex_init(&hdmi.lock);
679 679
680 if (pdev->dev.of_node) { 680 if (pdev->dev.of_node) {
681 r = hdmi_probe_of(pdev); 681 r = hdmi_probe_of(pdev);
682 if (r) 682 if (r)
683 return r; 683 return r;
684 } 684 }
685 685
686 r = hdmi_wp_init(pdev, &hdmi.wp); 686 r = hdmi_wp_init(pdev, &hdmi.wp);
687 if (r) 687 if (r)
688 return r; 688 return r;
689 689
690 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI, 690 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI,
691 NULL, 0); 691 NULL, 0);
692 if (!hdmi.pll) 692 if (!hdmi.pll)
693 return -ENODEV; 693 return -ENODEV;
694 694
695 r = hdmi_phy_init(pdev, &hdmi.phy); 695 r = hdmi_phy_init(pdev, &hdmi.phy);
696 if (r) 696 if (r)
697 return r; 697 return r;
698 698
699 r = hdmi4_core_init(pdev, &hdmi.core); 699 r = hdmi4_core_init(pdev, &hdmi.core);
700 if (r) 700 if (r)
701 return r; 701 return r;
702 702
703 irq = platform_get_irq(pdev, 0); 703 irq = platform_get_irq(pdev, 0);
704 if (irq < 0) { 704 if (irq < 0) {
705 DSSERR("platform_get_irq failed\n"); 705 DSSERR("platform_get_irq failed\n");
706 return -ENODEV; 706 return -ENODEV;
707 } 707 }
708 708
709 r = devm_request_threaded_irq(&pdev->dev, irq, 709 r = devm_request_threaded_irq(&pdev->dev, irq,
710 NULL, hdmi_irq_handler, 710 NULL, hdmi_irq_handler,
711 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 711 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
712 if (r) { 712 if (r) {
713 DSSERR("HDMI IRQ request failed\n"); 713 DSSERR("HDMI IRQ request failed\n");
714 return r; 714 return r;
715 } 715 }
716 716
717 pm_runtime_enable(&pdev->dev); 717 pm_runtime_enable(&pdev->dev);
718 718
719 hdmi_init_output(pdev); 719 hdmi_init_output(pdev);
720 720
721 r = hdmi_audio_register(&pdev->dev); 721 r = hdmi_audio_register(&pdev->dev);
722 if (r) { 722 if (r) {
723 DSSERR("Registering HDMI audio failed\n"); 723 DSSERR("Registering HDMI audio failed\n");
724 hdmi_uninit_output(pdev); 724 hdmi_uninit_output(pdev);
725 pm_runtime_disable(&pdev->dev); 725 pm_runtime_disable(&pdev->dev);
726 return r; 726 return r;
727 } 727 }
728 728
729 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 729 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
730 730
731 return 0; 731 return 0;
732 } 732 }
733 733
734 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 734 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
735 { 735 {
736 omap_hdmi_audio_unregister(&pdev->dev); 736 omap_hdmi_audio_unregister(&pdev->dev);
737 737
738 hdmi_uninit_output(pdev); 738 hdmi_uninit_output(pdev);
739 739
740 pm_runtime_disable(&pdev->dev); 740 pm_runtime_disable(&pdev->dev);
741 741
742 return 0; 742 return 0;
743 } 743 }
744 744
745 static int hdmi_runtime_suspend(struct device *dev) 745 static int hdmi_runtime_suspend(struct device *dev)
746 { 746 {
747 pll_enable_clock(hdmi.pll, false); 747 pll_enable_clock(hdmi.pll, false);
748 748
749 dispc_runtime_put(); 749 dispc_runtime_put();
750 750
751 return 0; 751 return 0;
752 } 752 }
753 753
754 static int hdmi_runtime_resume(struct device *dev) 754 static int hdmi_runtime_resume(struct device *dev)
755 { 755 {
756 int r; 756 int r;
757 757
758 r = dispc_runtime_get(); 758 r = dispc_runtime_get();
759 if (r < 0) 759 if (r < 0)
760 return r; 760 return r;
761 761
762 pll_enable_clock(hdmi.pll, true); 762 pll_enable_clock(hdmi.pll, true);
763 763
764 return 0; 764 return 0;
765 } 765 }
766 766
767 static const struct dev_pm_ops hdmi_pm_ops = { 767 static const struct dev_pm_ops hdmi_pm_ops = {
768 .runtime_suspend = hdmi_runtime_suspend, 768 .runtime_suspend = hdmi_runtime_suspend,
769 .runtime_resume = hdmi_runtime_resume, 769 .runtime_resume = hdmi_runtime_resume,
770 }; 770 };
771 771
772 static const struct of_device_id hdmi_of_match[] = { 772 static const struct of_device_id hdmi_of_match[] = {
773 { .compatible = "ti,omap4-hdmi", }, 773 { .compatible = "ti,omap4-hdmi", },
774 {}, 774 {},
775 }; 775 };
776 776
777 static struct platform_driver omapdss_hdmihw_driver = { 777 static struct platform_driver omapdss_hdmihw_driver = {
778 .probe = omapdss_hdmihw_probe, 778 .probe = omapdss_hdmihw_probe,
779 .remove = __exit_p(omapdss_hdmihw_remove), 779 .remove = __exit_p(omapdss_hdmihw_remove),
780 .driver = { 780 .driver = {
781 .name = "omapdss_hdmi", 781 .name = "omapdss_hdmi",
782 .owner = THIS_MODULE, 782 .owner = THIS_MODULE,
783 .pm = &hdmi_pm_ops, 783 .pm = &hdmi_pm_ops,
784 .of_match_table = hdmi_of_match, 784 .of_match_table = hdmi_of_match,
785 }, 785 },
786 }; 786 };
787 787
788 int __init hdmi4_init_platform_driver(void) 788 int __init hdmi4_init_platform_driver(void)
789 { 789 {
790 return platform_driver_register(&omapdss_hdmihw_driver); 790 return platform_driver_register(&omapdss_hdmihw_driver);
791 } 791 }
792 792
793 void __exit hdmi4_uninit_platform_driver(void) 793 void __exit hdmi4_uninit_platform_driver(void)
794 { 794 {
795 platform_driver_unregister(&omapdss_hdmihw_driver); 795 platform_driver_unregister(&omapdss_hdmihw_driver);
796 } 796 }
797 797
drivers/video/fbdev/omap2/dss/hdmi5.c
1 /* 1 /*
2 * HDMI driver for OMAP5 2 * HDMI driver for OMAP5
3 * 3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated 4 * Copyright (C) 2014 Texas Instruments Incorporated
5 * 5 *
6 * Authors: 6 * Authors:
7 * Yong Zhi 7 * Yong Zhi
8 * Mythri pk 8 * Mythri pk
9 * Archit Taneja <archit@ti.com> 9 * Archit Taneja <archit@ti.com>
10 * Tomi Valkeinen <tomi.valkeinen@ti.com> 10 * Tomi Valkeinen <tomi.valkeinen@ti.com>
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify it 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 13 * under the terms of the GNU General Public License version 2 as published by
14 * the Free Software Foundation. 14 * the Free Software Foundation.
15 * 15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT 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 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details. 19 * more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License along with 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/>. 22 * this program. If not, see <http://www.gnu.org/licenses/>.
23 */ 23 */
24 24
25 #define DSS_SUBSYS_NAME "HDMI" 25 #define DSS_SUBSYS_NAME "HDMI"
26 26
27 #include <linux/kernel.h> 27 #include <linux/kernel.h>
28 #include <linux/module.h> 28 #include <linux/module.h>
29 #include <linux/err.h> 29 #include <linux/err.h>
30 #include <linux/io.h> 30 #include <linux/io.h>
31 #include <linux/interrupt.h> 31 #include <linux/interrupt.h>
32 #include <linux/mutex.h> 32 #include <linux/mutex.h>
33 #include <linux/delay.h> 33 #include <linux/delay.h>
34 #include <linux/string.h> 34 #include <linux/string.h>
35 #include <linux/platform_device.h> 35 #include <linux/platform_device.h>
36 #include <linux/pm_runtime.h> 36 #include <linux/pm_runtime.h>
37 #include <linux/clk.h> 37 #include <linux/clk.h>
38 #include <linux/gpio.h> 38 #include <linux/gpio.h>
39 #include <linux/regulator/consumer.h> 39 #include <linux/regulator/consumer.h>
40 #include <video/omapdss.h> 40 #include <video/omapdss.h>
41 #include <sound/omap-hdmi-audio.h> 41 #include <sound/omap-hdmi-audio.h>
42 42
43 #include "hdmi5_core.h" 43 #include "hdmi5_core.h"
44 #include "dss.h" 44 #include "dss.h"
45 #include "dss_features.h" 45 #include "dss_features.h"
46 46
47 static struct omap_hdmi hdmi; 47 static struct omap_hdmi hdmi;
48 48
49 static int hdmi_runtime_get(void) 49 static int hdmi_runtime_get(void)
50 { 50 {
51 int r; 51 int r;
52 52
53 DSSDBG("hdmi_runtime_get\n"); 53 DSSDBG("hdmi_runtime_get\n");
54 54
55 r = pm_runtime_get_sync(&hdmi.pdev->dev); 55 r = pm_runtime_get_sync(&hdmi.pdev->dev);
56 WARN_ON(r < 0); 56 WARN_ON(r < 0);
57 if (r < 0) 57 if (r < 0)
58 return r; 58 return r;
59 59
60 return 0; 60 return 0;
61 } 61 }
62 62
63 static void hdmi_runtime_put(void) 63 static void hdmi_runtime_put(void)
64 { 64 {
65 int r; 65 int r;
66 66
67 DSSDBG("hdmi_runtime_put\n"); 67 DSSDBG("hdmi_runtime_put\n");
68 68
69 r = pm_runtime_put_sync(&hdmi.pdev->dev); 69 r = pm_runtime_put_sync(&hdmi.pdev->dev);
70 WARN_ON(r < 0 && r != -ENOSYS); 70 WARN_ON(r < 0 && r != -ENOSYS);
71 } 71 }
72 72
73 static irqreturn_t hdmi_irq_handler(int irq, void *data) 73 static irqreturn_t hdmi_irq_handler(int irq, void *data)
74 { 74 {
75 struct hdmi_wp_data *wp = data; 75 struct hdmi_wp_data *wp = data;
76 u32 irqstatus; 76 u32 irqstatus;
77 77
78 irqstatus = hdmi_wp_get_irqstatus(wp); 78 irqstatus = hdmi_wp_get_irqstatus(wp);
79 hdmi_wp_set_irqstatus(wp, irqstatus); 79 hdmi_wp_set_irqstatus(wp, irqstatus);
80 80
81 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 81 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
82 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 82 irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
83 u32 v; 83 u32 v;
84 /* 84 /*
85 * If we get both connect and disconnect interrupts at the same 85 * If we get both connect and disconnect interrupts at the same
86 * time, turn off the PHY, clear interrupts, and restart, which 86 * time, turn off the PHY, clear interrupts, and restart, which
87 * raises connect interrupt if a cable is connected, or nothing 87 * raises connect interrupt if a cable is connected, or nothing
88 * if cable is not connected. 88 * if cable is not connected.
89 */ 89 */
90 90
91 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 91 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
92 92
93 /* 93 /*
94 * We always get bogus CONNECT & DISCONNECT interrupts when 94 * We always get bogus CONNECT & DISCONNECT interrupts when
95 * setting the PHY to LDOON. To ignore those, we force the RXDET 95 * setting the PHY to LDOON. To ignore those, we force the RXDET
96 * line to 0 until the PHY power state has been changed. 96 * line to 0 until the PHY power state has been changed.
97 */ 97 */
98 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); 98 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
99 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ 99 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
100 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ 100 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
101 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); 101 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
102 102
103 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 103 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
104 HDMI_IRQ_LINK_DISCONNECT); 104 HDMI_IRQ_LINK_DISCONNECT);
105 105
106 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 106 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
107 107
108 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); 108 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
109 109
110 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 110 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
111 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 111 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
112 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 112 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
113 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 113 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
114 } 114 }
115 115
116 return IRQ_HANDLED; 116 return IRQ_HANDLED;
117 } 117 }
118 118
119 static int hdmi_init_regulator(void) 119 static int hdmi_init_regulator(void)
120 { 120 {
121 int r; 121 int r;
122 struct regulator *reg; 122 struct regulator *reg;
123 123
124 if (hdmi.vdda_reg != NULL) 124 if (hdmi.vdda_reg != NULL)
125 return 0; 125 return 0;
126 126
127 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 127 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
128 if (IS_ERR(reg)) { 128 if (IS_ERR(reg)) {
129 DSSERR("can't get VDDA regulator\n"); 129 DSSERR("can't get VDDA regulator\n");
130 return PTR_ERR(reg); 130 return PTR_ERR(reg);
131 } 131 }
132 132
133 if (regulator_can_change_voltage(reg)) { 133 if (regulator_can_change_voltage(reg)) {
134 r = regulator_set_voltage(reg, 1800000, 1800000); 134 r = regulator_set_voltage(reg, 1800000, 1800000);
135 if (r) { 135 if (r) {
136 devm_regulator_put(reg); 136 devm_regulator_put(reg);
137 DSSWARN("can't set the regulator voltage\n"); 137 DSSWARN("can't set the regulator voltage\n");
138 return r; 138 return r;
139 } 139 }
140 } 140 }
141 141
142 hdmi.vdda_reg = reg; 142 hdmi.vdda_reg = reg;
143 143
144 return 0; 144 return 0;
145 } 145 }
146 146
147 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp, 147 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp,
148 struct pll_params *p) 148 struct pll_params *p)
149 { 149 {
150 u16 r = 0; 150 u16 r = 0;
151 151
152 dss_ctrl_hdmi_pll_enable(true); 152 dss_ctrl_hdmi_pll_enable(true);
153 153
154 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 154 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
155 if (r) 155 if (r)
156 return r; 156 return r;
157 157
158 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 158 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
159 if (r) 159 if (r)
160 return r; 160 return r;
161 161
162 pll_sysreset(pll); 162 pll_sysreset(pll);
163 163
164 r = pll_wait_reset(pll); 164 r = pll_wait_reset(pll);
165 if (r) 165 if (r)
166 return r; 166 return r;
167 167
168 r = pll_calc_and_check_clock_rates(pll, p); 168 r = pll_calc_and_check_clock_rates(pll, p);
169 if (r) 169 if (r)
170 return r; 170 return r;
171 171
172 r = pll_set_clock_div(pll, p); 172 r = pll_set_clock_div(pll, p);
173 if (r) 173 if (r)
174 return r; 174 return r;
175 175
176 return 0; 176 return 0;
177 } 177 }
178 178
179 static void hdmi_pll_disable(struct hdmi_wp_data *wp) 179 static void hdmi_pll_disable(struct hdmi_wp_data *wp)
180 { 180 {
181 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 181 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
182 182
183 dss_ctrl_hdmi_pll_enable(false); 183 dss_ctrl_hdmi_pll_enable(false);
184 } 184 }
185 185
186 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 186 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
187 { 187 {
188 int r; 188 int r;
189 189
190 r = regulator_enable(hdmi.vdda_reg); 190 r = regulator_enable(hdmi.vdda_reg);
191 if (r) 191 if (r)
192 return r; 192 return r;
193 193
194 r = hdmi_runtime_get(); 194 r = hdmi_runtime_get();
195 if (r) 195 if (r)
196 goto err_runtime_get; 196 goto err_runtime_get;
197 197
198 /* Make selection of HDMI in DSS */ 198 /* Make selection of HDMI in DSS */
199 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 199 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
200 200
201 hdmi.core_enabled = true; 201 hdmi.core_enabled = true;
202 202
203 return 0; 203 return 0;
204 204
205 err_runtime_get: 205 err_runtime_get:
206 regulator_disable(hdmi.vdda_reg); 206 regulator_disable(hdmi.vdda_reg);
207 207
208 return r; 208 return r;
209 } 209 }
210 210
211 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 211 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
212 { 212 {
213 hdmi.core_enabled = false; 213 hdmi.core_enabled = false;
214 214
215 hdmi_runtime_put(); 215 hdmi_runtime_put();
216 regulator_disable(hdmi.vdda_reg); 216 regulator_disable(hdmi.vdda_reg);
217 } 217 }
218 218
219 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 219 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
220 { 220 {
221 int r; 221 int r;
222 struct omap_video_timings *p; 222 struct omap_video_timings *p;
223 struct omap_overlay_manager *mgr = hdmi.output.manager; 223 struct omap_overlay_manager *mgr = hdmi.output.manager;
224 unsigned long phy; 224 unsigned long phy;
225 struct pll_params param; 225 struct pll_params param;
226 bool ok; 226 bool ok;
227 227
228 r = hdmi_power_on_core(dssdev); 228 r = hdmi_power_on_core(dssdev);
229 if (r) 229 if (r)
230 return r; 230 return r;
231 231
232 p = &hdmi.cfg.timings; 232 p = &hdmi.cfg.timings;
233 233
234 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 234 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
235 235
236 phy = p->pixelclock * 10; 236 phy = p->pixelclock * 10;
237 237
238 memset(&param, 0, sizeof(param)); 238 memset(&param, 0, sizeof(param));
239 239
240 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param); 240 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param);
241 if (!ok) { 241 if (!ok) {
242 DSSDBG("Failed to calculate PLL settings\n"); 242 DSSDBG("Failed to calculate PLL settings\n");
243 goto err_pll_enable; 243 goto err_pll_enable;
244 } 244 }
245 245
246 /* disable and clear irqs */ 246 /* disable and clear irqs */
247 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 247 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
248 hdmi_wp_set_irqstatus(&hdmi.wp, 248 hdmi_wp_set_irqstatus(&hdmi.wp,
249 hdmi_wp_get_irqstatus(&hdmi.wp)); 249 hdmi_wp_get_irqstatus(&hdmi.wp));
250 250
251 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 251 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
252 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param); 252 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param);
253 if (r) { 253 if (r) {
254 DSSDBG("Failed to lock PLL\n"); 254 DSSDBG("Failed to lock PLL\n");
255 goto err_pll_enable; 255 goto err_pll_enable;
256 } 256 }
257 257
258 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 258 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
259 if (r) { 259 if (r) {
260 DSSDBG("Failed to start PHY\n"); 260 DSSDBG("Failed to start PHY\n");
261 goto err_phy_cfg; 261 goto err_phy_cfg;
262 } 262 }
263 263
264 r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); 264 r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON);
265 if (r) 265 if (r)
266 goto err_phy_pwr; 266 goto err_phy_pwr;
267 267
268 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 268 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
269 269
270 /* bypass TV gamma table */ 270 /* bypass TV gamma table */
271 dispc_enable_gamma_table(0); 271 dispc_enable_gamma_table(0);
272 272
273 /* tv size */ 273 /* tv size */
274 dss_mgr_set_timings(mgr, p); 274 dss_mgr_set_timings(mgr, p);
275 275
276 r = dss_mgr_enable(mgr); 276 r = dss_mgr_enable(mgr);
277 if (r) 277 if (r)
278 goto err_mgr_enable; 278 goto err_mgr_enable;
279 279
280 r = hdmi_wp_video_start(&hdmi.wp); 280 r = hdmi_wp_video_start(&hdmi.wp);
281 if (r) 281 if (r)
282 goto err_vid_enable; 282 goto err_vid_enable;
283 283
284 hdmi_wp_set_irqenable(&hdmi.wp, 284 hdmi_wp_set_irqenable(&hdmi.wp,
285 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 285 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
286 286
287 return 0; 287 return 0;
288 288
289 err_vid_enable: 289 err_vid_enable:
290 dss_mgr_disable(mgr); 290 dss_mgr_disable(mgr);
291 err_mgr_enable: 291 err_mgr_enable:
292 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 292 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
293 err_phy_pwr: 293 err_phy_pwr:
294 err_phy_cfg: 294 err_phy_cfg:
295 hdmi_pll_disable(&hdmi.wp); 295 hdmi_pll_disable(&hdmi.wp);
296 err_pll_enable: 296 err_pll_enable:
297 hdmi_power_off_core(dssdev); 297 hdmi_power_off_core(dssdev);
298 return -EIO; 298 return -EIO;
299 } 299 }
300 300
301 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 301 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
302 { 302 {
303 struct omap_overlay_manager *mgr = hdmi.output.manager; 303 struct omap_overlay_manager *mgr = hdmi.output.manager;
304 304
305 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 305 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
306 306
307 hdmi_wp_video_stop(&hdmi.wp); 307 hdmi_wp_video_stop(&hdmi.wp);
308 308
309 dss_mgr_disable(mgr); 309 dss_mgr_disable(mgr);
310 310
311 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 311 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
312 312
313 hdmi_pll_disable(&hdmi.wp); 313 hdmi_pll_disable(&hdmi.wp);
314 314
315 hdmi_power_off_core(dssdev); 315 hdmi_power_off_core(dssdev);
316 } 316 }
317 317
318 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 318 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
319 struct omap_video_timings *timings) 319 struct omap_video_timings *timings)
320 { 320 {
321 struct omap_dss_device *out = &hdmi.output; 321 struct omap_dss_device *out = &hdmi.output;
322 322
323 if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) 323 if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
324 return -EINVAL; 324 return -EINVAL;
325 325
326 return 0; 326 return 0;
327 } 327 }
328 328
329 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 329 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
330 struct omap_video_timings *timings) 330 struct omap_video_timings *timings)
331 { 331 {
332 mutex_lock(&hdmi.lock); 332 mutex_lock(&hdmi.lock);
333 333
334 hdmi.cfg.timings = *timings; 334 hdmi.cfg.timings = *timings;
335 335
336 dispc_set_tv_pclk(timings->pixelclock); 336 dispc_set_tv_pclk(timings->pixelclock);
337 337
338 mutex_unlock(&hdmi.lock); 338 mutex_unlock(&hdmi.lock);
339 } 339 }
340 340
341 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 341 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
342 struct omap_video_timings *timings) 342 struct omap_video_timings *timings)
343 { 343 {
344 *timings = hdmi.cfg.timings; 344 *timings = hdmi.cfg.timings;
345 } 345 }
346 346
347 static void hdmi_dump_regs(struct seq_file *s) 347 static void hdmi_dump_regs(struct seq_file *s)
348 { 348 {
349 mutex_lock(&hdmi.lock); 349 mutex_lock(&hdmi.lock);
350 350
351 if (hdmi_runtime_get()) { 351 if (hdmi_runtime_get()) {
352 mutex_unlock(&hdmi.lock); 352 mutex_unlock(&hdmi.lock);
353 return; 353 return;
354 } 354 }
355 355
356 hdmi_wp_dump(&hdmi.wp, s); 356 hdmi_wp_dump(&hdmi.wp, s);
357 pll_dump(hdmi.pll, s); 357 pll_dump(hdmi.pll, s);
358 hdmi_phy_dump(&hdmi.phy, s); 358 hdmi_phy_dump(&hdmi.phy, s);
359 hdmi5_core_dump(&hdmi.core, s); 359 hdmi5_core_dump(&hdmi.core, s);
360 360
361 hdmi_runtime_put(); 361 hdmi_runtime_put();
362 mutex_unlock(&hdmi.lock); 362 mutex_unlock(&hdmi.lock);
363 } 363 }
364 364
365 static int read_edid(u8 *buf, int len) 365 static int read_edid(u8 *buf, int len)
366 { 366 {
367 int r; 367 int r;
368 int idlemode; 368 int idlemode;
369 369
370 mutex_lock(&hdmi.lock); 370 mutex_lock(&hdmi.lock);
371 371
372 r = hdmi_runtime_get(); 372 r = hdmi_runtime_get();
373 BUG_ON(r); 373 BUG_ON(r);
374 374
375 idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 375 idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
376 /* No-idle mode */ 376 /* No-idle mode */
377 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 377 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
378 378
379 r = hdmi5_read_edid(&hdmi.core, buf, len); 379 r = hdmi5_read_edid(&hdmi.core, buf, len);
380 380
381 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); 381 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
382 382
383 hdmi_runtime_put(); 383 hdmi_runtime_put();
384 mutex_unlock(&hdmi.lock); 384 mutex_unlock(&hdmi.lock);
385 385
386 return r; 386 return r;
387 } 387 }
388 388
389 static int hdmi_display_enable(struct omap_dss_device *dssdev) 389 static int hdmi_display_enable(struct omap_dss_device *dssdev)
390 { 390 {
391 struct omap_dss_device *out = &hdmi.output; 391 struct omap_dss_device *out = &hdmi.output;
392 int r = 0; 392 int r = 0;
393 393
394 DSSDBG("ENTER hdmi_display_enable\n"); 394 DSSDBG("ENTER hdmi_display_enable\n");
395 395
396 mutex_lock(&hdmi.lock); 396 mutex_lock(&hdmi.lock);
397 397
398 if (out == NULL || out->manager == NULL) { 398 if (out == NULL || out->manager == NULL) {
399 DSSERR("failed to enable display: no output/manager\n"); 399 DSSERR("failed to enable display: no output/manager\n");
400 r = -ENODEV; 400 r = -ENODEV;
401 goto err0; 401 goto err0;
402 } 402 }
403 403
404 r = hdmi_power_on_full(dssdev); 404 r = hdmi_power_on_full(dssdev);
405 if (r) { 405 if (r) {
406 DSSERR("failed to power on device\n"); 406 DSSERR("failed to power on device\n");
407 goto err0; 407 goto err0;
408 } 408 }
409 409
410 hdmi.display_enabled = true; 410 hdmi.display_enabled = true;
411 411
412 mutex_unlock(&hdmi.lock); 412 mutex_unlock(&hdmi.lock);
413 return 0; 413 return 0;
414 414
415 err0: 415 err0:
416 mutex_unlock(&hdmi.lock); 416 mutex_unlock(&hdmi.lock);
417 return r; 417 return r;
418 } 418 }
419 419
420 static void hdmi_display_disable(struct omap_dss_device *dssdev) 420 static void hdmi_display_disable(struct omap_dss_device *dssdev)
421 { 421 {
422 DSSDBG("Enter hdmi_display_disable\n"); 422 DSSDBG("Enter hdmi_display_disable\n");
423 423
424 mutex_lock(&hdmi.lock); 424 mutex_lock(&hdmi.lock);
425 425
426 if (hdmi.audio_abort_cb) 426 /* If set hdmi.audio_abort_cb(&hdmi.pdev->dev) should be
427 hdmi.audio_abort_cb(&hdmi.pdev->dev); 427 * called here, if audio abort functionality is needed. */
428 428
429 hdmi_power_off_full(dssdev); 429 hdmi_power_off_full(dssdev);
430 430
431 hdmi.display_enabled = false; 431 hdmi.display_enabled = false;
432 432
433 mutex_unlock(&hdmi.lock); 433 mutex_unlock(&hdmi.lock);
434 } 434 }
435 435
436 static int hdmi_core_enable(struct omap_dss_device *dssdev) 436 static int hdmi_core_enable(struct omap_dss_device *dssdev)
437 { 437 {
438 int r = 0; 438 int r = 0;
439 439
440 DSSDBG("ENTER omapdss_hdmi_core_enable\n"); 440 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
441 441
442 mutex_lock(&hdmi.lock); 442 mutex_lock(&hdmi.lock);
443 443
444 r = hdmi_power_on_core(dssdev); 444 r = hdmi_power_on_core(dssdev);
445 if (r) { 445 if (r) {
446 DSSERR("failed to power on device\n"); 446 DSSERR("failed to power on device\n");
447 goto err0; 447 goto err0;
448 } 448 }
449 449
450 mutex_unlock(&hdmi.lock); 450 mutex_unlock(&hdmi.lock);
451 return 0; 451 return 0;
452 452
453 err0: 453 err0:
454 mutex_unlock(&hdmi.lock); 454 mutex_unlock(&hdmi.lock);
455 return r; 455 return r;
456 } 456 }
457 457
458 static void hdmi_core_disable(struct omap_dss_device *dssdev) 458 static void hdmi_core_disable(struct omap_dss_device *dssdev)
459 { 459 {
460 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 460 DSSDBG("Enter omapdss_hdmi_core_disable\n");
461 461
462 mutex_lock(&hdmi.lock); 462 mutex_lock(&hdmi.lock);
463 463
464 hdmi_power_off_core(dssdev); 464 hdmi_power_off_core(dssdev);
465 465
466 mutex_unlock(&hdmi.lock); 466 mutex_unlock(&hdmi.lock);
467 } 467 }
468 468
469 static int hdmi_connect(struct omap_dss_device *dssdev, 469 static int hdmi_connect(struct omap_dss_device *dssdev,
470 struct omap_dss_device *dst) 470 struct omap_dss_device *dst)
471 { 471 {
472 struct omap_overlay_manager *mgr; 472 struct omap_overlay_manager *mgr;
473 int r; 473 int r;
474 474
475 r = hdmi_init_regulator(); 475 r = hdmi_init_regulator();
476 if (r) 476 if (r)
477 return r; 477 return r;
478 478
479 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); 479 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
480 if (!mgr) 480 if (!mgr)
481 return -ENODEV; 481 return -ENODEV;
482 482
483 r = dss_mgr_connect(mgr, dssdev); 483 r = dss_mgr_connect(mgr, dssdev);
484 if (r) 484 if (r)
485 return r; 485 return r;
486 486
487 r = omapdss_output_set_device(dssdev, dst); 487 r = omapdss_output_set_device(dssdev, dst);
488 if (r) { 488 if (r) {
489 DSSERR("failed to connect output to new device: %s\n", 489 DSSERR("failed to connect output to new device: %s\n",
490 dst->name); 490 dst->name);
491 dss_mgr_disconnect(mgr, dssdev); 491 dss_mgr_disconnect(mgr, dssdev);
492 return r; 492 return r;
493 } 493 }
494 494
495 return 0; 495 return 0;
496 } 496 }
497 497
498 static void hdmi_disconnect(struct omap_dss_device *dssdev, 498 static void hdmi_disconnect(struct omap_dss_device *dssdev,
499 struct omap_dss_device *dst) 499 struct omap_dss_device *dst)
500 { 500 {
501 WARN_ON(dst != dssdev->dst); 501 WARN_ON(dst != dssdev->dst);
502 502
503 if (dst != dssdev->dst) 503 if (dst != dssdev->dst)
504 return; 504 return;
505 505
506 omapdss_output_unset_device(dssdev); 506 omapdss_output_unset_device(dssdev);
507 507
508 if (dssdev->manager) 508 if (dssdev->manager)
509 dss_mgr_disconnect(dssdev->manager, dssdev); 509 dss_mgr_disconnect(dssdev->manager, dssdev);
510 } 510 }
511 511
512 static int hdmi_read_edid(struct omap_dss_device *dssdev, 512 static int hdmi_read_edid(struct omap_dss_device *dssdev,
513 u8 *edid, int len) 513 u8 *edid, int len)
514 { 514 {
515 bool need_enable; 515 bool need_enable;
516 int r; 516 int r;
517 517
518 need_enable = hdmi.core_enabled == false; 518 need_enable = hdmi.core_enabled == false;
519 519
520 if (need_enable) { 520 if (need_enable) {
521 r = hdmi_core_enable(dssdev); 521 r = hdmi_core_enable(dssdev);
522 if (r) 522 if (r)
523 return r; 523 return r;
524 } 524 }
525 525
526 r = read_edid(edid, len); 526 r = read_edid(edid, len);
527 527
528 if (need_enable) 528 if (need_enable)
529 hdmi_core_disable(dssdev); 529 hdmi_core_disable(dssdev);
530 530
531 return r; 531 return r;
532 } 532 }
533 533
534 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 534 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
535 const struct hdmi_avi_infoframe *avi) 535 const struct hdmi_avi_infoframe *avi)
536 { 536 {
537 hdmi.cfg.infoframe = *avi; 537 hdmi.cfg.infoframe = *avi;
538 return 0; 538 return 0;
539 } 539 }
540 540
541 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 541 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
542 bool hdmi_mode) 542 bool hdmi_mode)
543 { 543 {
544 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 544 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
545 return 0; 545 return 0;
546 } 546 }
547 547
548 static const struct omapdss_hdmi_ops hdmi_ops = { 548 static const struct omapdss_hdmi_ops hdmi_ops = {
549 .connect = hdmi_connect, 549 .connect = hdmi_connect,
550 .disconnect = hdmi_disconnect, 550 .disconnect = hdmi_disconnect,
551 551
552 .enable = hdmi_display_enable, 552 .enable = hdmi_display_enable,
553 .disable = hdmi_display_disable, 553 .disable = hdmi_display_disable,
554 554
555 .check_timings = hdmi_display_check_timing, 555 .check_timings = hdmi_display_check_timing,
556 .set_timings = hdmi_display_set_timing, 556 .set_timings = hdmi_display_set_timing,
557 .get_timings = hdmi_display_get_timings, 557 .get_timings = hdmi_display_get_timings,
558 558
559 .read_edid = hdmi_read_edid, 559 .read_edid = hdmi_read_edid,
560 .set_infoframe = hdmi_set_infoframe, 560 .set_infoframe = hdmi_set_infoframe,
561 .set_hdmi_mode = hdmi_set_hdmi_mode, 561 .set_hdmi_mode = hdmi_set_hdmi_mode,
562 }; 562 };
563 563
564 static void hdmi_init_output(struct platform_device *pdev) 564 static void hdmi_init_output(struct platform_device *pdev)
565 { 565 {
566 struct omap_dss_device *out = &hdmi.output; 566 struct omap_dss_device *out = &hdmi.output;
567 567
568 out->dev = &pdev->dev; 568 out->dev = &pdev->dev;
569 out->id = OMAP_DSS_OUTPUT_HDMI; 569 out->id = OMAP_DSS_OUTPUT_HDMI;
570 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 570 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
571 out->name = "hdmi.0"; 571 out->name = "hdmi.0";
572 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 572 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
573 out->ops.hdmi = &hdmi_ops; 573 out->ops.hdmi = &hdmi_ops;
574 out->owner = THIS_MODULE; 574 out->owner = THIS_MODULE;
575 575
576 omapdss_register_output(out); 576 omapdss_register_output(out);
577 } 577 }
578 578
579 static void __exit hdmi_uninit_output(struct platform_device *pdev) 579 static void __exit hdmi_uninit_output(struct platform_device *pdev)
580 { 580 {
581 struct omap_dss_device *out = &hdmi.output; 581 struct omap_dss_device *out = &hdmi.output;
582 582
583 omapdss_unregister_output(out); 583 omapdss_unregister_output(out);
584 } 584 }
585 585
586 static int hdmi_probe_of(struct platform_device *pdev) 586 static int hdmi_probe_of(struct platform_device *pdev)
587 { 587 {
588 struct device_node *node = pdev->dev.of_node; 588 struct device_node *node = pdev->dev.of_node;
589 struct device_node *ep; 589 struct device_node *ep;
590 int r; 590 int r;
591 591
592 ep = omapdss_of_get_first_endpoint(node); 592 ep = omapdss_of_get_first_endpoint(node);
593 if (!ep) 593 if (!ep)
594 return 0; 594 return 0;
595 595
596 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 596 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
597 if (r) 597 if (r)
598 goto err; 598 goto err;
599 599
600 of_node_put(ep); 600 of_node_put(ep);
601 return 0; 601 return 0;
602 602
603 err: 603 err:
604 of_node_put(ep); 604 of_node_put(ep);
605 return r; 605 return r;
606 } 606 }
607 607
608 #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) 608 #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
609 static int audio_startup(struct device *dev, 609 static int audio_startup(struct device *dev,
610 void (*abort_cb)(struct device *dev)) 610 void (*abort_cb)(struct device *dev))
611 { 611 {
612 struct omap_hdmi *hd = dev_get_drvdata(dev); 612 struct omap_hdmi *hd = dev_get_drvdata(dev);
613 int ret = 0; 613 int ret = 0;
614 614
615 mutex_lock(&hd->lock); 615 mutex_lock(&hd->lock);
616 616
617 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 617 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
618 ret = -EPERM; 618 ret = -EPERM;
619 goto out; 619 goto out;
620 } 620 }
621 621
622 hd->audio_abort_cb = abort_cb; 622 hd->audio_abort_cb = abort_cb;
623 623
624 out: 624 out:
625 mutex_unlock(&hd->lock); 625 mutex_unlock(&hd->lock);
626 626
627 return ret; 627 return ret;
628 } 628 }
629 629
630 static int audio_enable(struct device *dev, bool enable) 630 static int audio_enable(struct device *dev, bool enable)
631 { 631 {
632 struct omap_hdmi *hd = dev_get_drvdata(dev); 632 struct omap_hdmi *hd = dev_get_drvdata(dev);
633 int ret; 633 int ret;
634 634
635 mutex_lock(&hd->lock); 635 mutex_lock(&hd->lock);
636 636
637 if (enable) { 637 if (enable) {
638 /* No idle while playing audio */ 638 /* No idle while playing audio */
639 hd->wp_idlemode = 639 hd->wp_idlemode =
640 REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 640 REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
641 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 641 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
642 } 642 }
643 643
644 ret = hdmi_wp_audio_enable(&hd->wp, enable); 644 ret = hdmi_wp_audio_enable(&hd->wp, enable);
645 645
646 if (!enable) { 646 if (!enable) {
647 /* Playback stopped, restore original idlemode */ 647 /* Playback stopped, restore original idlemode */
648 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 648 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode,
649 3, 2); 649 3, 2);
650 650
651 hd->audio_abort_cb = NULL; 651 hd->audio_abort_cb = NULL;
652 } 652 }
653 653
654 mutex_unlock(&hd->lock); 654 mutex_unlock(&hd->lock);
655 655
656 return ret; 656 return ret;
657 } 657 }
658 658
659 static int audio_start(struct device *dev, bool enable) 659 static int audio_start(struct device *dev, bool enable)
660 { 660 {
661 struct omap_hdmi *hd = dev_get_drvdata(dev); 661 struct omap_hdmi *hd = dev_get_drvdata(dev);
662 662
663 return hdmi_wp_audio_core_req_enable(&hd->wp, enable); 663 return hdmi_wp_audio_core_req_enable(&hd->wp, enable);
664 } 664 }
665 665
666 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio) 666 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio)
667 { 667 {
668 struct omap_hdmi *hd = dev_get_drvdata(dev); 668 struct omap_hdmi *hd = dev_get_drvdata(dev);
669 int ret; 669 int ret;
670 670
671 mutex_lock(&hd->lock); 671 mutex_lock(&hd->lock);
672 if (!hdmi_mode_has_audio(&hd->cfg)) 672 if (!hdmi_mode_has_audio(&hd->cfg))
673 ret = -EPERM; 673 ret = -EPERM;
674 else 674 else
675 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio, 675 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
676 hd->cfg.timings.pixelclock); 676 hd->cfg.timings.pixelclock);
677 mutex_unlock(&hd->lock); 677 mutex_unlock(&hd->lock);
678 678
679 return ret; 679 return ret;
680 } 680 }
681 681
682 static int hdmi_audio_register(struct device *dev) 682 static int hdmi_audio_register(struct device *dev)
683 { 683 {
684 struct omap_hdmi_audio ha = { 684 struct omap_hdmi_audio ha = {
685 .dev = dev, 685 .dev = dev,
686 .hw_version = OMAP5_HDMI, 686 .hw_version = OMAP5_HDMI,
687 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 687 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
688 .audio_startup = audio_startup, 688 .audio_startup = audio_startup,
689 .audio_enable = audio_enable, 689 .audio_enable = audio_enable,
690 .audio_start = audio_start, 690 .audio_start = audio_start,
691 .audio_config = audio_config, 691 .audio_config = audio_config,
692 }; 692 };
693 693
694 return omap_hdmi_audio_register(&ha); 694 return omap_hdmi_audio_register(&ha);
695 } 695 }
696 #else /* CONFIG_OMAP5_DSS_HDMI_AUDIO */ 696 #else /* CONFIG_OMAP5_DSS_HDMI_AUDIO */
697 static int hdmi_audio_register(struct device *dev) 697 static int hdmi_audio_register(struct device *dev)
698 { 698 {
699 return 0; 699 return 0;
700 } 700 }
701 #endif 701 #endif
702 702
703 /* HDMI HW IP initialisation */ 703 /* HDMI HW IP initialisation */
704 static int omapdss_hdmihw_probe(struct platform_device *pdev) 704 static int omapdss_hdmihw_probe(struct platform_device *pdev)
705 { 705 {
706 int r; 706 int r;
707 int irq; 707 int irq;
708 708
709 hdmi.pdev = pdev; 709 hdmi.pdev = pdev;
710 dev_set_drvdata(&pdev->dev, &hdmi); 710 dev_set_drvdata(&pdev->dev, &hdmi);
711 711
712 mutex_init(&hdmi.lock); 712 mutex_init(&hdmi.lock);
713 713
714 if (pdev->dev.of_node) { 714 if (pdev->dev.of_node) {
715 r = hdmi_probe_of(pdev); 715 r = hdmi_probe_of(pdev);
716 if (r) 716 if (r)
717 return r; 717 return r;
718 } 718 }
719 719
720 r = hdmi_wp_init(pdev, &hdmi.wp); 720 r = hdmi_wp_init(pdev, &hdmi.wp);
721 if (r) 721 if (r)
722 return r; 722 return r;
723 723
724 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI, 724 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI,
725 NULL, 0); 725 NULL, 0);
726 if (!hdmi.pll) 726 if (!hdmi.pll)
727 return -ENODEV; 727 return -ENODEV;
728 728
729 r = hdmi_phy_init(pdev, &hdmi.phy); 729 r = hdmi_phy_init(pdev, &hdmi.phy);
730 if (r) 730 if (r)
731 return r; 731 return r;
732 732
733 r = hdmi5_core_init(pdev, &hdmi.core); 733 r = hdmi5_core_init(pdev, &hdmi.core);
734 if (r) 734 if (r)
735 return r; 735 return r;
736 736
737 irq = platform_get_irq(pdev, 0); 737 irq = platform_get_irq(pdev, 0);
738 if (irq < 0) { 738 if (irq < 0) {
739 DSSERR("platform_get_irq failed\n"); 739 DSSERR("platform_get_irq failed\n");
740 return -ENODEV; 740 return -ENODEV;
741 } 741 }
742 742
743 r = devm_request_threaded_irq(&pdev->dev, irq, 743 r = devm_request_threaded_irq(&pdev->dev, irq,
744 NULL, hdmi_irq_handler, 744 NULL, hdmi_irq_handler,
745 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 745 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
746 if (r) { 746 if (r) {
747 DSSERR("HDMI IRQ request failed\n"); 747 DSSERR("HDMI IRQ request failed\n");
748 return r; 748 return r;
749 } 749 }
750 750
751 pm_runtime_enable(&pdev->dev); 751 pm_runtime_enable(&pdev->dev);
752 752
753 hdmi_init_output(pdev); 753 hdmi_init_output(pdev);
754 754
755 r = hdmi_audio_register(&pdev->dev); 755 r = hdmi_audio_register(&pdev->dev);
756 if (r) { 756 if (r) {
757 DSSERR("Registering HDMI audio failed\n"); 757 DSSERR("Registering HDMI audio failed\n");
758 hdmi_uninit_output(pdev); 758 hdmi_uninit_output(pdev);
759 pm_runtime_disable(&pdev->dev); 759 pm_runtime_disable(&pdev->dev);
760 return r; 760 return r;
761 } 761 }
762 762
763 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 763 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
764 764
765 return 0; 765 return 0;
766 } 766 }
767 767
768 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 768 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
769 { 769 {
770 omap_hdmi_audio_unregister(&pdev->dev); 770 omap_hdmi_audio_unregister(&pdev->dev);
771 771
772 hdmi_uninit_output(pdev); 772 hdmi_uninit_output(pdev);
773 773
774 pm_runtime_disable(&pdev->dev); 774 pm_runtime_disable(&pdev->dev);
775 775
776 return 0; 776 return 0;
777 } 777 }
778 778
779 static int hdmi_runtime_suspend(struct device *dev) 779 static int hdmi_runtime_suspend(struct device *dev)
780 { 780 {
781 pll_enable_clock(hdmi.pll, false); 781 pll_enable_clock(hdmi.pll, false);
782 782
783 dispc_runtime_put(); 783 dispc_runtime_put();
784 784
785 return 0; 785 return 0;
786 } 786 }
787 787
788 static int hdmi_runtime_resume(struct device *dev) 788 static int hdmi_runtime_resume(struct device *dev)
789 { 789 {
790 int r; 790 int r;
791 791
792 r = dispc_runtime_get(); 792 r = dispc_runtime_get();
793 if (r < 0) 793 if (r < 0)
794 return r; 794 return r;
795 795
796 pll_enable_clock(hdmi.pll, true); 796 pll_enable_clock(hdmi.pll, true);
797 797
798 return 0; 798 return 0;
799 } 799 }
800 800
801 static const struct dev_pm_ops hdmi_pm_ops = { 801 static const struct dev_pm_ops hdmi_pm_ops = {
802 .runtime_suspend = hdmi_runtime_suspend, 802 .runtime_suspend = hdmi_runtime_suspend,
803 .runtime_resume = hdmi_runtime_resume, 803 .runtime_resume = hdmi_runtime_resume,
804 }; 804 };
805 805
806 static const struct of_device_id hdmi_of_match[] = { 806 static const struct of_device_id hdmi_of_match[] = {
807 { .compatible = "ti,omap5-hdmi", }, 807 { .compatible = "ti,omap5-hdmi", },
808 { .compatible = "ti,dra7-hdmi", }, 808 { .compatible = "ti,dra7-hdmi", },
809 {}, 809 {},
810 }; 810 };
811 811
812 static struct platform_driver omapdss_hdmihw_driver = { 812 static struct platform_driver omapdss_hdmihw_driver = {
813 .probe = omapdss_hdmihw_probe, 813 .probe = omapdss_hdmihw_probe,
814 .remove = __exit_p(omapdss_hdmihw_remove), 814 .remove = __exit_p(omapdss_hdmihw_remove),
815 .driver = { 815 .driver = {
816 .name = "omapdss_hdmi5", 816 .name = "omapdss_hdmi5",
817 .owner = THIS_MODULE, 817 .owner = THIS_MODULE,
818 .pm = &hdmi_pm_ops, 818 .pm = &hdmi_pm_ops,
819 .of_match_table = hdmi_of_match, 819 .of_match_table = hdmi_of_match,
820 }, 820 },
821 }; 821 };
822 822
823 int __init hdmi5_init_platform_driver(void) 823 int __init hdmi5_init_platform_driver(void)
824 { 824 {
825 return platform_driver_register(&omapdss_hdmihw_driver); 825 return platform_driver_register(&omapdss_hdmihw_driver);
826 } 826 }
827 827
828 void __exit hdmi5_uninit_platform_driver(void) 828 void __exit hdmi5_uninit_platform_driver(void)
829 { 829 {
830 platform_driver_unregister(&omapdss_hdmihw_driver); 830 platform_driver_unregister(&omapdss_hdmihw_driver);
831 } 831 }
832 832