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