xref: /linux/drivers/gpu/drm/omapdrm/dss/hdmi5.c (revision e7e67d9a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * HDMI driver for OMAP5
4  *
5  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
6  *
7  * Authors:
8  *	Yong Zhi
9  *	Mythri pk
10  *	Archit Taneja <archit@ti.com>
11  *	Tomi Valkeinen <tomi.valkeinen@ti.com>
12  */
13 
14 #define DSS_SUBSYS_NAME "HDMI"
15 
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/err.h>
19 #include <linux/io.h>
20 #include <linux/interrupt.h>
21 #include <linux/mutex.h>
22 #include <linux/delay.h>
23 #include <linux/string.h>
24 #include <linux/platform_device.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/clk.h>
27 #include <linux/gpio.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/component.h>
30 #include <linux/of.h>
31 #include <linux/of_graph.h>
32 #include <sound/omap-hdmi-audio.h>
33 
34 #include <drm/drm_atomic.h>
35 #include <drm/drm_atomic_state_helper.h>
36 
37 #include "omapdss.h"
38 #include "hdmi5_core.h"
39 #include "dss.h"
40 
41 static int hdmi_runtime_get(struct omap_hdmi *hdmi)
42 {
43 	int r;
44 
45 	DSSDBG("hdmi_runtime_get\n");
46 
47 	r = pm_runtime_get_sync(&hdmi->pdev->dev);
48 	WARN_ON(r < 0);
49 	if (r < 0)
50 		return r;
51 
52 	return 0;
53 }
54 
55 static void hdmi_runtime_put(struct omap_hdmi *hdmi)
56 {
57 	int r;
58 
59 	DSSDBG("hdmi_runtime_put\n");
60 
61 	r = pm_runtime_put_sync(&hdmi->pdev->dev);
62 	WARN_ON(r < 0 && r != -ENOSYS);
63 }
64 
65 static irqreturn_t hdmi_irq_handler(int irq, void *data)
66 {
67 	struct omap_hdmi *hdmi = data;
68 	struct hdmi_wp_data *wp = &hdmi->wp;
69 	u32 irqstatus;
70 
71 	irqstatus = hdmi_wp_get_irqstatus(wp);
72 	hdmi_wp_set_irqstatus(wp, irqstatus);
73 
74 	if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
75 			irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
76 		u32 v;
77 		/*
78 		 * If we get both connect and disconnect interrupts at the same
79 		 * time, turn off the PHY, clear interrupts, and restart, which
80 		 * raises connect interrupt if a cable is connected, or nothing
81 		 * if cable is not connected.
82 		 */
83 
84 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
85 
86 		/*
87 		 * We always get bogus CONNECT & DISCONNECT interrupts when
88 		 * setting the PHY to LDOON. To ignore those, we force the RXDET
89 		 * line to 0 until the PHY power state has been changed.
90 		 */
91 		v = hdmi_read_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
92 		v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
93 		v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
94 		hdmi_write_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
95 
96 		hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
97 				HDMI_IRQ_LINK_DISCONNECT);
98 
99 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
100 
101 		REG_FLD_MOD(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
102 
103 	} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
104 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
105 	} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
106 		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
107 	}
108 
109 	return IRQ_HANDLED;
110 }
111 
112 static int hdmi_power_on_core(struct omap_hdmi *hdmi)
113 {
114 	int r;
115 
116 	r = regulator_enable(hdmi->vdda_reg);
117 	if (r)
118 		return r;
119 
120 	r = hdmi_runtime_get(hdmi);
121 	if (r)
122 		goto err_runtime_get;
123 
124 	/* Make selection of HDMI in DSS */
125 	dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK);
126 
127 	hdmi->core_enabled = true;
128 
129 	return 0;
130 
131 err_runtime_get:
132 	regulator_disable(hdmi->vdda_reg);
133 
134 	return r;
135 }
136 
137 static void hdmi_power_off_core(struct omap_hdmi *hdmi)
138 {
139 	hdmi->core_enabled = false;
140 
141 	hdmi_runtime_put(hdmi);
142 	regulator_disable(hdmi->vdda_reg);
143 }
144 
145 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
146 {
147 	int r;
148 	const struct videomode *vm;
149 	struct dss_pll_clock_info hdmi_cinfo = { 0 };
150 	unsigned int pc;
151 
152 	r = hdmi_power_on_core(hdmi);
153 	if (r)
154 		return r;
155 
156 	vm = &hdmi->cfg.vm;
157 
158 	DSSDBG("hdmi_power_on hactive= %d vactive = %d\n", vm->hactive,
159 	       vm->vactive);
160 
161 	pc = vm->pixelclock;
162 	if (vm->flags & DISPLAY_FLAGS_DOUBLECLK)
163 		pc *= 2;
164 
165 	/* DSS_HDMI_TCLK is bitclk / 10 */
166 	pc *= 10;
167 
168 	dss_pll_calc_b(&hdmi->pll.pll, clk_get_rate(hdmi->pll.pll.clkin),
169 		pc, &hdmi_cinfo);
170 
171 	/* disable and clear irqs */
172 	hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
173 	hdmi_wp_set_irqstatus(&hdmi->wp,
174 			hdmi_wp_get_irqstatus(&hdmi->wp));
175 
176 	r = dss_pll_enable(&hdmi->pll.pll);
177 	if (r) {
178 		DSSERR("Failed to enable PLL\n");
179 		goto err_pll_enable;
180 	}
181 
182 	r = dss_pll_set_config(&hdmi->pll.pll, &hdmi_cinfo);
183 	if (r) {
184 		DSSERR("Failed to configure PLL\n");
185 		goto err_pll_cfg;
186 	}
187 
188 	r = hdmi_phy_configure(&hdmi->phy, hdmi_cinfo.clkdco,
189 		hdmi_cinfo.clkout[0]);
190 	if (r) {
191 		DSSDBG("Failed to start PHY\n");
192 		goto err_phy_cfg;
193 	}
194 
195 	r = hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_LDOON);
196 	if (r)
197 		goto err_phy_pwr;
198 
199 	hdmi5_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
200 
201 	r = dss_mgr_enable(&hdmi->output);
202 	if (r)
203 		goto err_mgr_enable;
204 
205 	r = hdmi_wp_video_start(&hdmi->wp);
206 	if (r)
207 		goto err_vid_enable;
208 
209 	hdmi_wp_set_irqenable(&hdmi->wp,
210 			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
211 
212 	return 0;
213 
214 err_vid_enable:
215 	dss_mgr_disable(&hdmi->output);
216 err_mgr_enable:
217 	hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
218 err_phy_pwr:
219 err_phy_cfg:
220 err_pll_cfg:
221 	dss_pll_disable(&hdmi->pll.pll);
222 err_pll_enable:
223 	hdmi_power_off_core(hdmi);
224 	return -EIO;
225 }
226 
227 static void hdmi_power_off_full(struct omap_hdmi *hdmi)
228 {
229 	hdmi_wp_clear_irqenable(&hdmi->wp, 0xffffffff);
230 
231 	hdmi_wp_video_stop(&hdmi->wp);
232 
233 	dss_mgr_disable(&hdmi->output);
234 
235 	hdmi_wp_set_phy_pwr(&hdmi->wp, HDMI_PHYPWRCMD_OFF);
236 
237 	dss_pll_disable(&hdmi->pll.pll);
238 
239 	hdmi_power_off_core(hdmi);
240 }
241 
242 static int hdmi_dump_regs(struct seq_file *s, void *p)
243 {
244 	struct omap_hdmi *hdmi = s->private;
245 
246 	mutex_lock(&hdmi->lock);
247 
248 	if (hdmi_runtime_get(hdmi)) {
249 		mutex_unlock(&hdmi->lock);
250 		return 0;
251 	}
252 
253 	hdmi_wp_dump(&hdmi->wp, s);
254 	hdmi_pll_dump(&hdmi->pll, s);
255 	hdmi_phy_dump(&hdmi->phy, s);
256 	hdmi5_core_dump(&hdmi->core, s);
257 
258 	hdmi_runtime_put(hdmi);
259 	mutex_unlock(&hdmi->lock);
260 	return 0;
261 }
262 
263 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
264 {
265 	REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
266 	hdmi_wp_audio_enable(&hd->wp, true);
267 	hdmi_wp_audio_core_req_enable(&hd->wp, true);
268 }
269 
270 static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
271 {
272 	hdmi_wp_audio_core_req_enable(&hd->wp, false);
273 	hdmi_wp_audio_enable(&hd->wp, false);
274 	REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
275 }
276 
277 static int hdmi_core_enable(struct omap_hdmi *hdmi)
278 {
279 	int r = 0;
280 
281 	DSSDBG("ENTER omapdss_hdmi_core_enable\n");
282 
283 	mutex_lock(&hdmi->lock);
284 
285 	r = hdmi_power_on_core(hdmi);
286 	if (r) {
287 		DSSERR("failed to power on device\n");
288 		goto err0;
289 	}
290 
291 	mutex_unlock(&hdmi->lock);
292 	return 0;
293 
294 err0:
295 	mutex_unlock(&hdmi->lock);
296 	return r;
297 }
298 
299 static void hdmi_core_disable(struct omap_hdmi *hdmi)
300 {
301 	DSSDBG("Enter omapdss_hdmi_core_disable\n");
302 
303 	mutex_lock(&hdmi->lock);
304 
305 	hdmi_power_off_core(hdmi);
306 
307 	mutex_unlock(&hdmi->lock);
308 }
309 
310 static int hdmi_connect(struct omap_dss_device *src,
311 			struct omap_dss_device *dst)
312 {
313 	return omapdss_device_connect(dst->dss, dst, dst->next);
314 }
315 
316 static void hdmi_disconnect(struct omap_dss_device *src,
317 			    struct omap_dss_device *dst)
318 {
319 	omapdss_device_disconnect(dst, dst->next);
320 }
321 
322 #define MAX_EDID	512
323 
324 static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi,
325 					struct drm_connector *connector)
326 {
327 	struct hdmi_core_data *core = &hdmi->core;
328 	int max_ext_blocks = 3;
329 	int r, n, i;
330 	u8 *edid;
331 
332 	edid = kzalloc(MAX_EDID, GFP_KERNEL);
333 	if (!edid)
334 		return NULL;
335 
336 	r = hdmi5_core_ddc_read(core, edid, 0, EDID_LENGTH);
337 	if (r)
338 		goto error;
339 
340 	n = edid[0x7e];
341 
342 	if (n > max_ext_blocks)
343 		n = max_ext_blocks;
344 
345 	for (i = 1; i <= n; i++) {
346 		r = hdmi5_core_ddc_read(core, edid + i * EDID_LENGTH, i,
347 					EDID_LENGTH);
348 		if (r)
349 			goto error;
350 	}
351 
352 	return (struct edid *)edid;
353 
354 error:
355 	kfree(edid);
356 	return NULL;
357 }
358 
359 static struct edid *
360 hdmi_do_read_edid(struct omap_hdmi *hdmi,
361 		  struct edid *(*read)(struct omap_hdmi *hdmi,
362 				       struct drm_connector *connector),
363 		  struct drm_connector *connector)
364 {
365 	struct edid *edid;
366 	bool need_enable;
367 	int idlemode;
368 	int r;
369 
370 	need_enable = hdmi->core_enabled == false;
371 
372 	if (need_enable) {
373 		r = hdmi_core_enable(hdmi);
374 		if (r)
375 			return NULL;
376 	}
377 
378 	mutex_lock(&hdmi->lock);
379 	r = hdmi_runtime_get(hdmi);
380 	BUG_ON(r);
381 
382 	idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
383 	/* No-idle mode */
384 	REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
385 
386 	hdmi5_core_ddc_init(&hdmi->core);
387 
388 	edid = read(hdmi, connector);
389 
390 	hdmi5_core_ddc_uninit(&hdmi->core);
391 
392 	REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
393 
394 	hdmi_runtime_put(hdmi);
395 	mutex_unlock(&hdmi->lock);
396 
397 	if (need_enable)
398 		hdmi_core_disable(hdmi);
399 
400 	return (struct edid *)edid;
401 }
402 
403 static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
404 {
405 	return hdmi_do_read_edid(dssdev_to_hdmi(dssdev), hdmi_read_edid_data,
406 				 NULL);
407 }
408 
409 static const struct omap_dss_device_ops hdmi_ops = {
410 	.connect		= hdmi_connect,
411 	.disconnect		= hdmi_disconnect,
412 
413 	.read_edid		= hdmi_read_edid,
414 };
415 
416 /* -----------------------------------------------------------------------------
417  * DRM Bridge Operations
418  */
419 
420 static int hdmi5_bridge_attach(struct drm_bridge *bridge,
421 			       enum drm_bridge_attach_flags flags)
422 {
423 	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
424 
425 	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
426 		return -EINVAL;
427 
428 	return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge,
429 				 bridge, flags);
430 }
431 
432 static void hdmi5_bridge_mode_set(struct drm_bridge *bridge,
433 				  const struct drm_display_mode *mode,
434 				  const struct drm_display_mode *adjusted_mode)
435 {
436 	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
437 
438 	mutex_lock(&hdmi->lock);
439 
440 	drm_display_mode_to_videomode(adjusted_mode, &hdmi->cfg.vm);
441 
442 	dispc_set_tv_pclk(hdmi->dss->dispc, adjusted_mode->clock * 1000);
443 
444 	mutex_unlock(&hdmi->lock);
445 }
446 
447 static void hdmi5_bridge_enable(struct drm_bridge *bridge,
448 				struct drm_bridge_state *bridge_state)
449 {
450 	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
451 	struct drm_atomic_state *state = bridge_state->base.state;
452 	struct drm_connector_state *conn_state;
453 	struct drm_connector *connector;
454 	struct drm_crtc_state *crtc_state;
455 	unsigned long flags;
456 	int ret;
457 
458 	/*
459 	 * None of these should fail, as the bridge can't be enabled without a
460 	 * valid CRTC to connector path with fully populated new states.
461 	 */
462 	connector = drm_atomic_get_new_connector_for_encoder(state,
463 							     bridge->encoder);
464 	if (WARN_ON(!connector))
465 		return;
466 	conn_state = drm_atomic_get_new_connector_state(state, connector);
467 	if (WARN_ON(!conn_state))
468 		return;
469 	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
470 	if (WARN_ON(!crtc_state))
471 		return;
472 
473 	hdmi->cfg.hdmi_dvi_mode = connector->display_info.is_hdmi
474 				? HDMI_HDMI : HDMI_DVI;
475 
476 	if (connector->display_info.is_hdmi) {
477 		const struct drm_display_mode *mode;
478 		struct hdmi_avi_infoframe avi;
479 
480 		mode = &crtc_state->adjusted_mode;
481 		ret = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
482 							       mode);
483 		if (ret == 0)
484 			hdmi->cfg.infoframe = avi;
485 	}
486 
487 	mutex_lock(&hdmi->lock);
488 
489 	ret = hdmi_power_on_full(hdmi);
490 	if (ret) {
491 		DSSERR("failed to power on device\n");
492 		goto done;
493 	}
494 
495 	if (hdmi->audio_configured) {
496 		ret = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
497 					 &hdmi->audio_config,
498 					 hdmi->cfg.vm.pixelclock);
499 		if (ret) {
500 			DSSERR("Error restoring audio configuration: %d", ret);
501 			hdmi->audio_abort_cb(&hdmi->pdev->dev);
502 			hdmi->audio_configured = false;
503 		}
504 	}
505 
506 	spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
507 	if (hdmi->audio_configured && hdmi->audio_playing)
508 		hdmi_start_audio_stream(hdmi);
509 	hdmi->display_enabled = true;
510 	spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
511 
512 done:
513 	mutex_unlock(&hdmi->lock);
514 }
515 
516 static void hdmi5_bridge_disable(struct drm_bridge *bridge,
517 				 struct drm_bridge_state *bridge_state)
518 {
519 	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
520 	unsigned long flags;
521 
522 	mutex_lock(&hdmi->lock);
523 
524 	spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
525 	hdmi_stop_audio_stream(hdmi);
526 	hdmi->display_enabled = false;
527 	spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
528 
529 	hdmi_power_off_full(hdmi);
530 
531 	mutex_unlock(&hdmi->lock);
532 }
533 
534 static struct edid *hdmi5_bridge_read_edid(struct omap_hdmi *hdmi,
535 					   struct drm_connector *connector)
536 {
537 	return drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
538 }
539 
540 static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
541 					  struct drm_connector *connector)
542 {
543 	struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
544 
545 	return hdmi_do_read_edid(hdmi, hdmi5_bridge_read_edid, connector);
546 }
547 
548 static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
549 	.attach = hdmi5_bridge_attach,
550 	.mode_set = hdmi5_bridge_mode_set,
551 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
552 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
553 	.atomic_reset = drm_atomic_helper_bridge_reset,
554 	.atomic_enable = hdmi5_bridge_enable,
555 	.atomic_disable = hdmi5_bridge_disable,
556 	.get_edid = hdmi5_bridge_get_edid,
557 };
558 
559 static void hdmi5_bridge_init(struct omap_hdmi *hdmi)
560 {
561 	hdmi->bridge.funcs = &hdmi5_bridge_funcs;
562 	hdmi->bridge.of_node = hdmi->pdev->dev.of_node;
563 	hdmi->bridge.ops = DRM_BRIDGE_OP_EDID;
564 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
565 
566 	drm_bridge_add(&hdmi->bridge);
567 }
568 
569 static void hdmi5_bridge_cleanup(struct omap_hdmi *hdmi)
570 {
571 	drm_bridge_remove(&hdmi->bridge);
572 }
573 
574 /* -----------------------------------------------------------------------------
575  * Audio Callbacks
576  */
577 
578 static int hdmi_audio_startup(struct device *dev,
579 			      void (*abort_cb)(struct device *dev))
580 {
581 	struct omap_hdmi *hd = dev_get_drvdata(dev);
582 
583 	mutex_lock(&hd->lock);
584 
585 	WARN_ON(hd->audio_abort_cb != NULL);
586 
587 	hd->audio_abort_cb = abort_cb;
588 
589 	mutex_unlock(&hd->lock);
590 
591 	return 0;
592 }
593 
594 static int hdmi_audio_shutdown(struct device *dev)
595 {
596 	struct omap_hdmi *hd = dev_get_drvdata(dev);
597 
598 	mutex_lock(&hd->lock);
599 	hd->audio_abort_cb = NULL;
600 	hd->audio_configured = false;
601 	hd->audio_playing = false;
602 	mutex_unlock(&hd->lock);
603 
604 	return 0;
605 }
606 
607 static int hdmi_audio_start(struct device *dev)
608 {
609 	struct omap_hdmi *hd = dev_get_drvdata(dev);
610 	unsigned long flags;
611 
612 	spin_lock_irqsave(&hd->audio_playing_lock, flags);
613 
614 	if (hd->display_enabled) {
615 		if (!hdmi_mode_has_audio(&hd->cfg))
616 			DSSERR("%s: Video mode does not support audio\n",
617 			       __func__);
618 		hdmi_start_audio_stream(hd);
619 	}
620 	hd->audio_playing = true;
621 
622 	spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
623 	return 0;
624 }
625 
626 static void hdmi_audio_stop(struct device *dev)
627 {
628 	struct omap_hdmi *hd = dev_get_drvdata(dev);
629 	unsigned long flags;
630 
631 	if (!hdmi_mode_has_audio(&hd->cfg))
632 		DSSERR("%s: Video mode does not support audio\n", __func__);
633 
634 	spin_lock_irqsave(&hd->audio_playing_lock, flags);
635 
636 	if (hd->display_enabled)
637 		hdmi_stop_audio_stream(hd);
638 	hd->audio_playing = false;
639 
640 	spin_unlock_irqrestore(&hd->audio_playing_lock, flags);
641 }
642 
643 static int hdmi_audio_config(struct device *dev,
644 			     struct omap_dss_audio *dss_audio)
645 {
646 	struct omap_hdmi *hd = dev_get_drvdata(dev);
647 	int ret = 0;
648 
649 	mutex_lock(&hd->lock);
650 
651 	if (hd->display_enabled) {
652 		ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
653 					 hd->cfg.vm.pixelclock);
654 		if (ret)
655 			goto out;
656 	}
657 
658 	hd->audio_configured = true;
659 	hd->audio_config = *dss_audio;
660 out:
661 	mutex_unlock(&hd->lock);
662 
663 	return ret;
664 }
665 
666 static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
667 	.audio_startup = hdmi_audio_startup,
668 	.audio_shutdown = hdmi_audio_shutdown,
669 	.audio_start = hdmi_audio_start,
670 	.audio_stop = hdmi_audio_stop,
671 	.audio_config = hdmi_audio_config,
672 };
673 
674 static int hdmi_audio_register(struct omap_hdmi *hdmi)
675 {
676 	struct omap_hdmi_audio_pdata pdata = {
677 		.dev = &hdmi->pdev->dev,
678 		.version = 5,
679 		.audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi->wp),
680 		.ops = &hdmi_audio_ops,
681 	};
682 
683 	hdmi->audio_pdev = platform_device_register_data(
684 		&hdmi->pdev->dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
685 		&pdata, sizeof(pdata));
686 
687 	if (IS_ERR(hdmi->audio_pdev))
688 		return PTR_ERR(hdmi->audio_pdev);
689 
690 	hdmi_runtime_get(hdmi);
691 	hdmi->wp_idlemode =
692 		REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
693 	hdmi_runtime_put(hdmi);
694 
695 	return 0;
696 }
697 
698 /* -----------------------------------------------------------------------------
699  * Component Bind & Unbind
700  */
701 
702 static int hdmi5_bind(struct device *dev, struct device *master, void *data)
703 {
704 	struct dss_device *dss = dss_get_device(master);
705 	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
706 	int r;
707 
708 	hdmi->dss = dss;
709 
710 	r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
711 	if (r)
712 		return r;
713 
714 	r = hdmi_audio_register(hdmi);
715 	if (r) {
716 		DSSERR("Registering HDMI audio failed %d\n", r);
717 		goto err_pll_uninit;
718 	}
719 
720 	hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
721 						hdmi);
722 
723 	return 0;
724 
725 err_pll_uninit:
726 	hdmi_pll_uninit(&hdmi->pll);
727 	return r;
728 }
729 
730 static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
731 {
732 	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
733 
734 	dss_debugfs_remove_file(hdmi->debugfs);
735 
736 	if (hdmi->audio_pdev)
737 		platform_device_unregister(hdmi->audio_pdev);
738 
739 	hdmi_pll_uninit(&hdmi->pll);
740 }
741 
742 static const struct component_ops hdmi5_component_ops = {
743 	.bind	= hdmi5_bind,
744 	.unbind	= hdmi5_unbind,
745 };
746 
747 /* -----------------------------------------------------------------------------
748  * Probe & Remove, Suspend & Resume
749  */
750 
751 static int hdmi5_init_output(struct omap_hdmi *hdmi)
752 {
753 	struct omap_dss_device *out = &hdmi->output;
754 	int r;
755 
756 	hdmi5_bridge_init(hdmi);
757 
758 	out->dev = &hdmi->pdev->dev;
759 	out->id = OMAP_DSS_OUTPUT_HDMI;
760 	out->type = OMAP_DISPLAY_TYPE_HDMI;
761 	out->name = "hdmi.0";
762 	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
763 	out->ops = &hdmi_ops;
764 	out->owner = THIS_MODULE;
765 	out->of_port = 0;
766 	out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
767 
768 	r = omapdss_device_init_output(out, &hdmi->bridge);
769 	if (r < 0) {
770 		hdmi5_bridge_cleanup(hdmi);
771 		return r;
772 	}
773 
774 	omapdss_device_register(out);
775 
776 	return 0;
777 }
778 
779 static void hdmi5_uninit_output(struct omap_hdmi *hdmi)
780 {
781 	struct omap_dss_device *out = &hdmi->output;
782 
783 	omapdss_device_unregister(out);
784 	omapdss_device_cleanup_output(out);
785 
786 	hdmi5_bridge_cleanup(hdmi);
787 }
788 
789 static int hdmi5_probe_of(struct omap_hdmi *hdmi)
790 {
791 	struct platform_device *pdev = hdmi->pdev;
792 	struct device_node *node = pdev->dev.of_node;
793 	struct device_node *ep;
794 	int r;
795 
796 	ep = of_graph_get_endpoint_by_regs(node, 0, 0);
797 	if (!ep)
798 		return 0;
799 
800 	r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
801 	of_node_put(ep);
802 	return r;
803 }
804 
805 static int hdmi5_probe(struct platform_device *pdev)
806 {
807 	struct omap_hdmi *hdmi;
808 	int irq;
809 	int r;
810 
811 	hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
812 	if (!hdmi)
813 		return -ENOMEM;
814 
815 	hdmi->pdev = pdev;
816 
817 	dev_set_drvdata(&pdev->dev, hdmi);
818 
819 	mutex_init(&hdmi->lock);
820 	spin_lock_init(&hdmi->audio_playing_lock);
821 
822 	r = hdmi5_probe_of(hdmi);
823 	if (r)
824 		goto err_free;
825 
826 	r = hdmi_wp_init(pdev, &hdmi->wp, 5);
827 	if (r)
828 		goto err_free;
829 
830 	r = hdmi_phy_init(pdev, &hdmi->phy, 5);
831 	if (r)
832 		goto err_free;
833 
834 	r = hdmi5_core_init(pdev, &hdmi->core);
835 	if (r)
836 		goto err_free;
837 
838 	irq = platform_get_irq(pdev, 0);
839 	if (irq < 0) {
840 		DSSERR("platform_get_irq failed\n");
841 		r = -ENODEV;
842 		goto err_free;
843 	}
844 
845 	r = devm_request_threaded_irq(&pdev->dev, irq,
846 			NULL, hdmi_irq_handler,
847 			IRQF_ONESHOT, "OMAP HDMI", hdmi);
848 	if (r) {
849 		DSSERR("HDMI IRQ request failed\n");
850 		goto err_free;
851 	}
852 
853 	hdmi->vdda_reg = devm_regulator_get(&pdev->dev, "vdda");
854 	if (IS_ERR(hdmi->vdda_reg)) {
855 		r = PTR_ERR(hdmi->vdda_reg);
856 		if (r != -EPROBE_DEFER)
857 			DSSERR("can't get VDDA regulator\n");
858 		goto err_free;
859 	}
860 
861 	pm_runtime_enable(&pdev->dev);
862 
863 	r = hdmi5_init_output(hdmi);
864 	if (r)
865 		goto err_pm_disable;
866 
867 	r = component_add(&pdev->dev, &hdmi5_component_ops);
868 	if (r)
869 		goto err_uninit_output;
870 
871 	return 0;
872 
873 err_uninit_output:
874 	hdmi5_uninit_output(hdmi);
875 err_pm_disable:
876 	pm_runtime_disable(&pdev->dev);
877 err_free:
878 	kfree(hdmi);
879 	return r;
880 }
881 
882 static int hdmi5_remove(struct platform_device *pdev)
883 {
884 	struct omap_hdmi *hdmi = platform_get_drvdata(pdev);
885 
886 	component_del(&pdev->dev, &hdmi5_component_ops);
887 
888 	hdmi5_uninit_output(hdmi);
889 
890 	pm_runtime_disable(&pdev->dev);
891 
892 	kfree(hdmi);
893 	return 0;
894 }
895 
896 static const struct of_device_id hdmi_of_match[] = {
897 	{ .compatible = "ti,omap5-hdmi", },
898 	{ .compatible = "ti,dra7-hdmi", },
899 	{},
900 };
901 
902 struct platform_driver omapdss_hdmi5hw_driver = {
903 	.probe		= hdmi5_probe,
904 	.remove		= hdmi5_remove,
905 	.driver         = {
906 		.name   = "omapdss_hdmi5",
907 		.of_match_table = hdmi_of_match,
908 		.suppress_bind_attrs = true,
909 	},
910 };
911