xref: /openbmc/linux/drivers/gpu/drm/omapdrm/dss/hdmi5.c (revision 110e6f26)
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 <linux/component.h>
41 #include <video/omapdss.h>
42 #include <sound/omap-hdmi-audio.h>
43 
44 #include "hdmi5_core.h"
45 #include "dss.h"
46 #include "dss_features.h"
47 
48 static struct omap_hdmi hdmi;
49 
50 static int hdmi_runtime_get(void)
51 {
52 	int r;
53 
54 	DSSDBG("hdmi_runtime_get\n");
55 
56 	r = pm_runtime_get_sync(&hdmi.pdev->dev);
57 	WARN_ON(r < 0);
58 	if (r < 0)
59 		return r;
60 
61 	return 0;
62 }
63 
64 static void hdmi_runtime_put(void)
65 {
66 	int r;
67 
68 	DSSDBG("hdmi_runtime_put\n");
69 
70 	r = pm_runtime_put_sync(&hdmi.pdev->dev);
71 	WARN_ON(r < 0 && r != -ENOSYS);
72 }
73 
74 static irqreturn_t hdmi_irq_handler(int irq, void *data)
75 {
76 	struct hdmi_wp_data *wp = data;
77 	u32 irqstatus;
78 
79 	irqstatus = hdmi_wp_get_irqstatus(wp);
80 	hdmi_wp_set_irqstatus(wp, irqstatus);
81 
82 	if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
83 			irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
84 		u32 v;
85 		/*
86 		 * If we get both connect and disconnect interrupts at the same
87 		 * time, turn off the PHY, clear interrupts, and restart, which
88 		 * raises connect interrupt if a cable is connected, or nothing
89 		 * if cable is not connected.
90 		 */
91 
92 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
93 
94 		/*
95 		 * We always get bogus CONNECT & DISCONNECT interrupts when
96 		 * setting the PHY to LDOON. To ignore those, we force the RXDET
97 		 * line to 0 until the PHY power state has been changed.
98 		 */
99 		v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
100 		v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
101 		v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
102 		hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
103 
104 		hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
105 				HDMI_IRQ_LINK_DISCONNECT);
106 
107 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
108 
109 		REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
110 
111 	} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
112 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
113 	} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
114 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
115 	}
116 
117 	return IRQ_HANDLED;
118 }
119 
120 static int hdmi_init_regulator(void)
121 {
122 	int r;
123 	struct regulator *reg;
124 
125 	if (hdmi.vdda_reg != NULL)
126 		return 0;
127 
128 	reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
129 	if (IS_ERR(reg)) {
130 		DSSERR("can't get VDDA regulator\n");
131 		return PTR_ERR(reg);
132 	}
133 
134 	if (regulator_can_change_voltage(reg)) {
135 		r = regulator_set_voltage(reg, 1800000, 1800000);
136 		if (r) {
137 			devm_regulator_put(reg);
138 			DSSWARN("can't set the regulator voltage\n");
139 			return r;
140 		}
141 	}
142 
143 	hdmi.vdda_reg = reg;
144 
145 	return 0;
146 }
147 
148 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
149 {
150 	int r;
151 
152 	r = regulator_enable(hdmi.vdda_reg);
153 	if (r)
154 		return r;
155 
156 	r = hdmi_runtime_get();
157 	if (r)
158 		goto err_runtime_get;
159 
160 	/* Make selection of HDMI in DSS */
161 	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
162 
163 	hdmi.core_enabled = true;
164 
165 	return 0;
166 
167 err_runtime_get:
168 	regulator_disable(hdmi.vdda_reg);
169 
170 	return r;
171 }
172 
173 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
174 {
175 	hdmi.core_enabled = false;
176 
177 	hdmi_runtime_put();
178 	regulator_disable(hdmi.vdda_reg);
179 }
180 
181 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
182 {
183 	int r;
184 	struct omap_video_timings *p;
185 	enum omap_channel channel = dssdev->dispc_channel;
186 	struct dss_pll_clock_info hdmi_cinfo = { 0 };
187 	unsigned pc;
188 
189 	r = hdmi_power_on_core(dssdev);
190 	if (r)
191 		return r;
192 
193 	p = &hdmi.cfg.timings;
194 
195 	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
196 
197 	pc = p->pixelclock;
198 	if (p->double_pixel)
199 		pc *= 2;
200 
201 	hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo);
202 
203 	/* disable and clear irqs */
204 	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
205 	hdmi_wp_set_irqstatus(&hdmi.wp,
206 			hdmi_wp_get_irqstatus(&hdmi.wp));
207 
208 	r = dss_pll_enable(&hdmi.pll.pll);
209 	if (r) {
210 		DSSERR("Failed to enable PLL\n");
211 		goto err_pll_enable;
212 	}
213 
214 	r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
215 	if (r) {
216 		DSSERR("Failed to configure PLL\n");
217 		goto err_pll_cfg;
218 	}
219 
220 	r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
221 		hdmi_cinfo.clkout[0]);
222 	if (r) {
223 		DSSDBG("Failed to start PHY\n");
224 		goto err_phy_cfg;
225 	}
226 
227 	r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON);
228 	if (r)
229 		goto err_phy_pwr;
230 
231 	hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
232 
233 	/* bypass TV gamma table */
234 	dispc_enable_gamma_table(0);
235 
236 	/* tv size */
237 	dss_mgr_set_timings(channel, p);
238 
239 	r = dss_mgr_enable(channel);
240 	if (r)
241 		goto err_mgr_enable;
242 
243 	r = hdmi_wp_video_start(&hdmi.wp);
244 	if (r)
245 		goto err_vid_enable;
246 
247 	hdmi_wp_set_irqenable(&hdmi.wp,
248 			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
249 
250 	return 0;
251 
252 err_vid_enable:
253 	dss_mgr_disable(channel);
254 err_mgr_enable:
255 	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
256 err_phy_pwr:
257 err_phy_cfg:
258 err_pll_cfg:
259 	dss_pll_disable(&hdmi.pll.pll);
260 err_pll_enable:
261 	hdmi_power_off_core(dssdev);
262 	return -EIO;
263 }
264 
265 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
266 {
267 	enum omap_channel channel = dssdev->dispc_channel;
268 
269 	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
270 
271 	hdmi_wp_video_stop(&hdmi.wp);
272 
273 	dss_mgr_disable(channel);
274 
275 	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
276 
277 	dss_pll_disable(&hdmi.pll.pll);
278 
279 	hdmi_power_off_core(dssdev);
280 }
281 
282 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
283 					struct omap_video_timings *timings)
284 {
285 	if (!dispc_mgr_timings_ok(dssdev->dispc_channel, timings))
286 		return -EINVAL;
287 
288 	return 0;
289 }
290 
291 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
292 		struct omap_video_timings *timings)
293 {
294 	mutex_lock(&hdmi.lock);
295 
296 	hdmi.cfg.timings = *timings;
297 
298 	dispc_set_tv_pclk(timings->pixelclock);
299 
300 	mutex_unlock(&hdmi.lock);
301 }
302 
303 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
304 		struct omap_video_timings *timings)
305 {
306 	*timings = hdmi.cfg.timings;
307 }
308 
309 static void hdmi_dump_regs(struct seq_file *s)
310 {
311 	mutex_lock(&hdmi.lock);
312 
313 	if (hdmi_runtime_get()) {
314 		mutex_unlock(&hdmi.lock);
315 		return;
316 	}
317 
318 	hdmi_wp_dump(&hdmi.wp, s);
319 	hdmi_pll_dump(&hdmi.pll, s);
320 	hdmi_phy_dump(&hdmi.phy, s);
321 	hdmi5_core_dump(&hdmi.core, s);
322 
323 	hdmi_runtime_put();
324 	mutex_unlock(&hdmi.lock);
325 }
326 
327 static int read_edid(u8 *buf, int len)
328 {
329 	int r;
330 	int idlemode;
331 
332 	mutex_lock(&hdmi.lock);
333 
334 	r = hdmi_runtime_get();
335 	BUG_ON(r);
336 
337 	idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
338 	/* No-idle mode */
339 	REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
340 
341 	r = hdmi5_read_edid(&hdmi.core,  buf, len);
342 
343 	REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
344 
345 	hdmi_runtime_put();
346 	mutex_unlock(&hdmi.lock);
347 
348 	return r;
349 }
350 
351 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
352 {
353 	REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
354 	hdmi_wp_audio_enable(&hd->wp, true);
355 	hdmi_wp_audio_core_req_enable(&hd->wp, true);
356 }
357 
358 static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
359 {
360 	hdmi_wp_audio_core_req_enable(&hd->wp, false);
361 	hdmi_wp_audio_enable(&hd->wp, false);
362 	REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
363 }
364 
365 static int hdmi_display_enable(struct omap_dss_device *dssdev)
366 {
367 	struct omap_dss_device *out = &hdmi.output;
368 	unsigned long flags;
369 	int r = 0;
370 
371 	DSSDBG("ENTER hdmi_display_enable\n");
372 
373 	mutex_lock(&hdmi.lock);
374 
375 	if (!out->dispc_channel_connected) {
376 		DSSERR("failed to enable display: no output/manager\n");
377 		r = -ENODEV;
378 		goto err0;
379 	}
380 
381 	r = hdmi_power_on_full(dssdev);
382 	if (r) {
383 		DSSERR("failed to power on device\n");
384 		goto err0;
385 	}
386 
387 	if (hdmi.audio_configured) {
388 		r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config,
389 				       hdmi.cfg.timings.pixelclock);
390 		if (r) {
391 			DSSERR("Error restoring audio configuration: %d", r);
392 			hdmi.audio_abort_cb(&hdmi.pdev->dev);
393 			hdmi.audio_configured = false;
394 		}
395 	}
396 
397 	spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
398 	if (hdmi.audio_configured && hdmi.audio_playing)
399 		hdmi_start_audio_stream(&hdmi);
400 	hdmi.display_enabled = true;
401 	spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
402 
403 	mutex_unlock(&hdmi.lock);
404 	return 0;
405 
406 err0:
407 	mutex_unlock(&hdmi.lock);
408 	return r;
409 }
410 
411 static void hdmi_display_disable(struct omap_dss_device *dssdev)
412 {
413 	unsigned long flags;
414 
415 	DSSDBG("Enter hdmi_display_disable\n");
416 
417 	mutex_lock(&hdmi.lock);
418 
419 	spin_lock_irqsave(&hdmi.audio_playing_lock, flags);
420 	hdmi_stop_audio_stream(&hdmi);
421 	hdmi.display_enabled = false;
422 	spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags);
423 
424 	hdmi_power_off_full(dssdev);
425 
426 	mutex_unlock(&hdmi.lock);
427 }
428 
429 static int hdmi_core_enable(struct omap_dss_device *dssdev)
430 {
431 	int r = 0;
432 
433 	DSSDBG("ENTER omapdss_hdmi_core_enable\n");
434 
435 	mutex_lock(&hdmi.lock);
436 
437 	r = hdmi_power_on_core(dssdev);
438 	if (r) {
439 		DSSERR("failed to power on device\n");
440 		goto err0;
441 	}
442 
443 	mutex_unlock(&hdmi.lock);
444 	return 0;
445 
446 err0:
447 	mutex_unlock(&hdmi.lock);
448 	return r;
449 }
450 
451 static void hdmi_core_disable(struct omap_dss_device *dssdev)
452 {
453 	DSSDBG("Enter omapdss_hdmi_core_disable\n");
454 
455 	mutex_lock(&hdmi.lock);
456 
457 	hdmi_power_off_core(dssdev);
458 
459 	mutex_unlock(&hdmi.lock);
460 }
461 
462 static int hdmi_connect(struct omap_dss_device *dssdev,
463 		struct omap_dss_device *dst)
464 {
465 	enum omap_channel channel = dssdev->dispc_channel;
466 	int r;
467 
468 	r = hdmi_init_regulator();
469 	if (r)
470 		return r;
471 
472 	r = dss_mgr_connect(channel, dssdev);
473 	if (r)
474 		return r;
475 
476 	r = omapdss_output_set_device(dssdev, dst);
477 	if (r) {
478 		DSSERR("failed to connect output to new device: %s\n",
479 				dst->name);
480 		dss_mgr_disconnect(channel, dssdev);
481 		return r;
482 	}
483 
484 	return 0;
485 }
486 
487 static void hdmi_disconnect(struct omap_dss_device *dssdev,
488 		struct omap_dss_device *dst)
489 {
490 	enum omap_channel channel = dssdev->dispc_channel;
491 
492 	WARN_ON(dst != dssdev->dst);
493 
494 	if (dst != dssdev->dst)
495 		return;
496 
497 	omapdss_output_unset_device(dssdev);
498 
499 	dss_mgr_disconnect(channel, dssdev);
500 }
501 
502 static int hdmi_read_edid(struct omap_dss_device *dssdev,
503 		u8 *edid, int len)
504 {
505 	bool need_enable;
506 	int r;
507 
508 	need_enable = hdmi.core_enabled == false;
509 
510 	if (need_enable) {
511 		r = hdmi_core_enable(dssdev);
512 		if (r)
513 			return r;
514 	}
515 
516 	r = read_edid(edid, len);
517 
518 	if (need_enable)
519 		hdmi_core_disable(dssdev);
520 
521 	return r;
522 }
523 
524 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
525 		const struct hdmi_avi_infoframe *avi)
526 {
527 	hdmi.cfg.infoframe = *avi;
528 	return 0;
529 }
530 
531 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
532 		bool hdmi_mode)
533 {
534 	hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
535 	return 0;
536 }
537 
538 static const struct omapdss_hdmi_ops hdmi_ops = {
539 	.connect		= hdmi_connect,
540 	.disconnect		= hdmi_disconnect,
541 
542 	.enable			= hdmi_display_enable,
543 	.disable		= hdmi_display_disable,
544 
545 	.check_timings		= hdmi_display_check_timing,
546 	.set_timings		= hdmi_display_set_timing,
547 	.get_timings		= hdmi_display_get_timings,
548 
549 	.read_edid		= hdmi_read_edid,
550 	.set_infoframe		= hdmi_set_infoframe,
551 	.set_hdmi_mode		= hdmi_set_hdmi_mode,
552 };
553 
554 static void hdmi_init_output(struct platform_device *pdev)
555 {
556 	struct omap_dss_device *out = &hdmi.output;
557 
558 	out->dev = &pdev->dev;
559 	out->id = OMAP_DSS_OUTPUT_HDMI;
560 	out->output_type = OMAP_DISPLAY_TYPE_HDMI;
561 	out->name = "hdmi.0";
562 	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
563 	out->ops.hdmi = &hdmi_ops;
564 	out->owner = THIS_MODULE;
565 
566 	omapdss_register_output(out);
567 }
568 
569 static void hdmi_uninit_output(struct platform_device *pdev)
570 {
571 	struct omap_dss_device *out = &hdmi.output;
572 
573 	omapdss_unregister_output(out);
574 }
575 
576 static int hdmi_probe_of(struct platform_device *pdev)
577 {
578 	struct device_node *node = pdev->dev.of_node;
579 	struct device_node *ep;
580 	int r;
581 
582 	ep = omapdss_of_get_first_endpoint(node);
583 	if (!ep)
584 		return 0;
585 
586 	r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
587 	if (r)
588 		goto err;
589 
590 	of_node_put(ep);
591 	return 0;
592 
593 err:
594 	of_node_put(ep);
595 	return r;
596 }
597 
598 /* Audio callbacks */
599 static int hdmi_audio_startup(struct device *dev,
600 			      void (*abort_cb)(struct device *dev))
601 {
602 	struct omap_hdmi *hd = dev_get_drvdata(dev);
603 	int ret = 0;
604 
605 	mutex_lock(&hd->lock);
606 
607 	if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
608 		ret = -EPERM;
609 		goto out;
610 	}
611 
612 	hd->audio_abort_cb = abort_cb;
613 
614 out:
615 	mutex_unlock(&hd->lock);
616 
617 	return ret;
618 }
619 
620 static int hdmi_audio_shutdown(struct device *dev)
621 {
622 	struct omap_hdmi *hd = dev_get_drvdata(dev);
623 
624 	mutex_lock(&hd->lock);
625 	hd->audio_abort_cb = NULL;
626 	hd->audio_configured = false;
627 	hd->audio_playing = false;
628 	mutex_unlock(&hd->lock);
629 
630 	return 0;
631 }
632 
633 static int hdmi_audio_start(struct device *dev)
634 {
635 	struct omap_hdmi *hd = dev_get_drvdata(dev);
636 	unsigned long flags;
637 
638 	WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
639 
640 	spin_lock_irqsave(&hd->audio_playing_lock, flags);
641 
642 	if (hd->display_enabled)
643 		hdmi_start_audio_stream(hd);
644 	hd->audio_playing = true;
645 
646 	spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
647 	return 0;
648 }
649 
650 static void hdmi_audio_stop(struct device *dev)
651 {
652 	struct omap_hdmi *hd = dev_get_drvdata(dev);
653 	unsigned long flags;
654 
655 	WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
656 
657 	spin_lock_irqsave(&hd->audio_playing_lock, flags);
658 
659 	if (hd->display_enabled)
660 		hdmi_stop_audio_stream(hd);
661 	hd->audio_playing = false;
662 
663 	spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
664 }
665 
666 static int hdmi_audio_config(struct device *dev,
667 			     struct omap_dss_audio *dss_audio)
668 {
669 	struct omap_hdmi *hd = dev_get_drvdata(dev);
670 	int ret;
671 
672 	mutex_lock(&hd->lock);
673 
674 	if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
675 		ret = -EPERM;
676 		goto out;
677 	}
678 
679 	ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
680 				 hd->cfg.timings.pixelclock);
681 
682 	if (!ret) {
683 		hd->audio_configured = true;
684 		hd->audio_config = *dss_audio;
685 	}
686 out:
687 	mutex_unlock(&hd->lock);
688 
689 	return ret;
690 }
691 
692 static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
693 	.audio_startup = hdmi_audio_startup,
694 	.audio_shutdown = hdmi_audio_shutdown,
695 	.audio_start = hdmi_audio_start,
696 	.audio_stop = hdmi_audio_stop,
697 	.audio_config = hdmi_audio_config,
698 };
699 
700 static int hdmi_audio_register(struct device *dev)
701 {
702 	struct omap_hdmi_audio_pdata pdata = {
703 		.dev = dev,
704 		.dss_version = omapdss_get_version(),
705 		.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
706 		.ops = &hdmi_audio_ops,
707 	};
708 
709 	hdmi.audio_pdev = platform_device_register_data(
710 		dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
711 		&pdata, sizeof(pdata));
712 
713 	if (IS_ERR(hdmi.audio_pdev))
714 		return PTR_ERR(hdmi.audio_pdev);
715 
716 	hdmi_runtime_get();
717 	hdmi.wp_idlemode =
718 		REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
719 	hdmi_runtime_put();
720 
721 	return 0;
722 }
723 
724 /* HDMI HW IP initialisation */
725 static int hdmi5_bind(struct device *dev, struct device *master, void *data)
726 {
727 	struct platform_device *pdev = to_platform_device(dev);
728 	int r;
729 	int irq;
730 
731 	hdmi.pdev = pdev;
732 	dev_set_drvdata(&pdev->dev, &hdmi);
733 
734 	mutex_init(&hdmi.lock);
735 	spin_lock_init(&hdmi.audio_playing_lock);
736 
737 	if (pdev->dev.of_node) {
738 		r = hdmi_probe_of(pdev);
739 		if (r)
740 			return r;
741 	}
742 
743 	r = hdmi_wp_init(pdev, &hdmi.wp);
744 	if (r)
745 		return r;
746 
747 	r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
748 	if (r)
749 		return r;
750 
751 	r = hdmi_phy_init(pdev, &hdmi.phy);
752 	if (r)
753 		goto err;
754 
755 	r = hdmi5_core_init(pdev, &hdmi.core);
756 	if (r)
757 		goto err;
758 
759 	irq = platform_get_irq(pdev, 0);
760 	if (irq < 0) {
761 		DSSERR("platform_get_irq failed\n");
762 		r = -ENODEV;
763 		goto err;
764 	}
765 
766 	r = devm_request_threaded_irq(&pdev->dev, irq,
767 			NULL, hdmi_irq_handler,
768 			IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
769 	if (r) {
770 		DSSERR("HDMI IRQ request failed\n");
771 		goto err;
772 	}
773 
774 	pm_runtime_enable(&pdev->dev);
775 
776 	hdmi_init_output(pdev);
777 
778 	r = hdmi_audio_register(&pdev->dev);
779 	if (r) {
780 		DSSERR("Registering HDMI audio failed %d\n", r);
781 		hdmi_uninit_output(pdev);
782 		pm_runtime_disable(&pdev->dev);
783 		return r;
784 	}
785 
786 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
787 
788 	return 0;
789 err:
790 	hdmi_pll_uninit(&hdmi.pll);
791 	return r;
792 }
793 
794 static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
795 {
796 	struct platform_device *pdev = to_platform_device(dev);
797 
798 	if (hdmi.audio_pdev)
799 		platform_device_unregister(hdmi.audio_pdev);
800 
801 	hdmi_uninit_output(pdev);
802 
803 	hdmi_pll_uninit(&hdmi.pll);
804 
805 	pm_runtime_disable(&pdev->dev);
806 }
807 
808 static const struct component_ops hdmi5_component_ops = {
809 	.bind	= hdmi5_bind,
810 	.unbind	= hdmi5_unbind,
811 };
812 
813 static int hdmi5_probe(struct platform_device *pdev)
814 {
815 	return component_add(&pdev->dev, &hdmi5_component_ops);
816 }
817 
818 static int hdmi5_remove(struct platform_device *pdev)
819 {
820 	component_del(&pdev->dev, &hdmi5_component_ops);
821 	return 0;
822 }
823 
824 static int hdmi_runtime_suspend(struct device *dev)
825 {
826 	dispc_runtime_put();
827 
828 	return 0;
829 }
830 
831 static int hdmi_runtime_resume(struct device *dev)
832 {
833 	int r;
834 
835 	r = dispc_runtime_get();
836 	if (r < 0)
837 		return r;
838 
839 	return 0;
840 }
841 
842 static const struct dev_pm_ops hdmi_pm_ops = {
843 	.runtime_suspend = hdmi_runtime_suspend,
844 	.runtime_resume = hdmi_runtime_resume,
845 };
846 
847 static const struct of_device_id hdmi_of_match[] = {
848 	{ .compatible = "ti,omap5-hdmi", },
849 	{ .compatible = "ti,dra7-hdmi", },
850 	{},
851 };
852 
853 static struct platform_driver omapdss_hdmihw_driver = {
854 	.probe		= hdmi5_probe,
855 	.remove		= hdmi5_remove,
856 	.driver         = {
857 		.name   = "omapdss_hdmi5",
858 		.pm	= &hdmi_pm_ops,
859 		.of_match_table = hdmi_of_match,
860 		.suppress_bind_attrs = true,
861 	},
862 };
863 
864 int __init hdmi5_init_platform_driver(void)
865 {
866 	return platform_driver_register(&omapdss_hdmihw_driver);
867 }
868 
869 void hdmi5_uninit_platform_driver(void)
870 {
871 	platform_driver_unregister(&omapdss_hdmihw_driver);
872 }
873