forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/omapdrm/dss/hdmi5.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * HDMI driver for OMAP5
34 *
....@@ -8,18 +9,6 @@
89 * Mythri pk
910 * Archit Taneja <archit@ti.com>
1011 * 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/>.
2312 */
2413
2514 #define DSS_SUBSYS_NAME "HDMI"
....@@ -35,12 +24,14 @@
3524 #include <linux/platform_device.h>
3625 #include <linux/pm_runtime.h>
3726 #include <linux/clk.h>
38
-#include <linux/gpio.h>
3927 #include <linux/regulator/consumer.h>
4028 #include <linux/component.h>
4129 #include <linux/of.h>
4230 #include <linux/of_graph.h>
4331 #include <sound/omap-hdmi-audio.h>
32
+
33
+#include <drm/drm_atomic.h>
34
+#include <drm/drm_atomic_state_helper.h>
4435
4536 #include "omapdss.h"
4637 #include "hdmi5_core.h"
....@@ -117,24 +108,6 @@
117108 return IRQ_HANDLED;
118109 }
119110
120
-static int hdmi_init_regulator(struct omap_hdmi *hdmi)
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
-
138111 static int hdmi_power_on_core(struct omap_hdmi *hdmi)
139112 {
140113 int r;
....@@ -171,7 +144,7 @@
171144 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
172145 {
173146 int r;
174
- struct videomode *vm;
147
+ const struct videomode *vm;
175148 struct dss_pll_clock_info hdmi_cinfo = { 0 };
176149 unsigned int pc;
177150
....@@ -224,9 +197,6 @@
224197
225198 hdmi5_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
226199
227
- /* tv size */
228
- dss_mgr_set_timings(&hdmi->output, vm);
229
-
230200 r = dss_mgr_enable(&hdmi->output);
231201 if (r)
232202 goto err_mgr_enable;
....@@ -268,39 +238,6 @@
268238 hdmi_power_off_core(hdmi);
269239 }
270240
271
-static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
272
- struct videomode *vm)
273
-{
274
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
275
-
276
- if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
277
- return -EINVAL;
278
-
279
- return 0;
280
-}
281
-
282
-static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
283
- struct videomode *vm)
284
-{
285
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
286
-
287
- mutex_lock(&hdmi->lock);
288
-
289
- hdmi->cfg.vm = *vm;
290
-
291
- dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
292
-
293
- mutex_unlock(&hdmi->lock);
294
-}
295
-
296
-static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
297
- struct videomode *vm)
298
-{
299
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
300
-
301
- *vm = hdmi->cfg.vm;
302
-}
303
-
304241 static int hdmi_dump_regs(struct seq_file *s, void *p)
305242 {
306243 struct omap_hdmi *hdmi = s->private;
....@@ -322,30 +259,6 @@
322259 return 0;
323260 }
324261
325
-static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
326
-{
327
- int r;
328
- int idlemode;
329
-
330
- mutex_lock(&hdmi->lock);
331
-
332
- r = hdmi_runtime_get(hdmi);
333
- BUG_ON(r);
334
-
335
- idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
336
- /* No-idle mode */
337
- REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
338
-
339
- r = hdmi5_read_edid(&hdmi->core, buf, len);
340
-
341
- REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
342
-
343
- hdmi_runtime_put(hdmi);
344
- mutex_unlock(&hdmi->lock);
345
-
346
- return r;
347
-}
348
-
349262 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
350263 {
351264 REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
....@@ -358,72 +271,6 @@
358271 hdmi_wp_audio_core_req_enable(&hd->wp, false);
359272 hdmi_wp_audio_enable(&hd->wp, false);
360273 REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
361
-}
362
-
363
-static int hdmi_display_enable(struct omap_dss_device *dssdev)
364
-{
365
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
366
- unsigned long flags;
367
- int r = 0;
368
-
369
- DSSDBG("ENTER hdmi_display_enable\n");
370
-
371
- mutex_lock(&hdmi->lock);
372
-
373
- if (!dssdev->dispc_channel_connected) {
374
- DSSERR("failed to enable display: no output/manager\n");
375
- r = -ENODEV;
376
- goto err0;
377
- }
378
-
379
- r = hdmi_power_on_full(hdmi);
380
- if (r) {
381
- DSSERR("failed to power on device\n");
382
- goto err0;
383
- }
384
-
385
- if (hdmi->audio_configured) {
386
- r = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
387
- &hdmi->audio_config,
388
- hdmi->cfg.vm.pixelclock);
389
- if (r) {
390
- DSSERR("Error restoring audio configuration: %d", r);
391
- hdmi->audio_abort_cb(&hdmi->pdev->dev);
392
- hdmi->audio_configured = false;
393
- }
394
- }
395
-
396
- spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
397
- if (hdmi->audio_configured && hdmi->audio_playing)
398
- hdmi_start_audio_stream(hdmi);
399
- hdmi->display_enabled = true;
400
- spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
401
-
402
- mutex_unlock(&hdmi->lock);
403
- return 0;
404
-
405
-err0:
406
- mutex_unlock(&hdmi->lock);
407
- return r;
408
-}
409
-
410
-static void hdmi_display_disable(struct omap_dss_device *dssdev)
411
-{
412
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
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(hdmi);
425
-
426
- mutex_unlock(&hdmi->lock);
427274 }
428275
429276 static int hdmi_core_enable(struct omap_hdmi *hdmi)
....@@ -459,51 +306,131 @@
459306 mutex_unlock(&hdmi->lock);
460307 }
461308
462
-static int hdmi_connect(struct omap_dss_device *dssdev,
463
- struct omap_dss_device *dst)
309
+/* -----------------------------------------------------------------------------
310
+ * DRM Bridge Operations
311
+ */
312
+
313
+static int hdmi5_bridge_attach(struct drm_bridge *bridge,
314
+ enum drm_bridge_attach_flags flags)
464315 {
465
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
466
- int r;
316
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
467317
468
- r = hdmi_init_regulator(hdmi);
469
- if (r)
470
- return r;
318
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
319
+ return -EINVAL;
471320
472
- r = dss_mgr_connect(&hdmi->output, 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(&hdmi->output, dssdev);
481
- return r;
482
- }
483
-
484
- return 0;
321
+ return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge,
322
+ bridge, flags);
485323 }
486324
487
-static void hdmi_disconnect(struct omap_dss_device *dssdev,
488
- struct omap_dss_device *dst)
325
+static void hdmi5_bridge_mode_set(struct drm_bridge *bridge,
326
+ const struct drm_display_mode *mode,
327
+ const struct drm_display_mode *adjusted_mode)
489328 {
490
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
329
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
491330
492
- WARN_ON(dst != dssdev->dst);
331
+ mutex_lock(&hdmi->lock);
493332
494
- if (dst != dssdev->dst)
333
+ drm_display_mode_to_videomode(adjusted_mode, &hdmi->cfg.vm);
334
+
335
+ dispc_set_tv_pclk(hdmi->dss->dispc, adjusted_mode->clock * 1000);
336
+
337
+ mutex_unlock(&hdmi->lock);
338
+}
339
+
340
+static void hdmi5_bridge_enable(struct drm_bridge *bridge,
341
+ struct drm_bridge_state *bridge_state)
342
+{
343
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
344
+ struct drm_atomic_state *state = bridge_state->base.state;
345
+ struct drm_connector_state *conn_state;
346
+ struct drm_connector *connector;
347
+ struct drm_crtc_state *crtc_state;
348
+ unsigned long flags;
349
+ int ret;
350
+
351
+ /*
352
+ * None of these should fail, as the bridge can't be enabled without a
353
+ * valid CRTC to connector path with fully populated new states.
354
+ */
355
+ connector = drm_atomic_get_new_connector_for_encoder(state,
356
+ bridge->encoder);
357
+ if (WARN_ON(!connector))
358
+ return;
359
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
360
+ if (WARN_ON(!conn_state))
361
+ return;
362
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
363
+ if (WARN_ON(!crtc_state))
495364 return;
496365
497
- omapdss_output_unset_device(dssdev);
366
+ hdmi->cfg.hdmi_dvi_mode = connector->display_info.is_hdmi
367
+ ? HDMI_HDMI : HDMI_DVI;
498368
499
- dss_mgr_disconnect(&hdmi->output, dssdev);
369
+ if (connector->display_info.is_hdmi) {
370
+ const struct drm_display_mode *mode;
371
+ struct hdmi_avi_infoframe avi;
372
+
373
+ mode = &crtc_state->adjusted_mode;
374
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
375
+ mode);
376
+ if (ret == 0)
377
+ hdmi->cfg.infoframe = avi;
378
+ }
379
+
380
+ mutex_lock(&hdmi->lock);
381
+
382
+ ret = hdmi_power_on_full(hdmi);
383
+ if (ret) {
384
+ DSSERR("failed to power on device\n");
385
+ goto done;
386
+ }
387
+
388
+ if (hdmi->audio_configured) {
389
+ ret = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
390
+ &hdmi->audio_config,
391
+ hdmi->cfg.vm.pixelclock);
392
+ if (ret) {
393
+ DSSERR("Error restoring audio configuration: %d", ret);
394
+ hdmi->audio_abort_cb(&hdmi->pdev->dev);
395
+ hdmi->audio_configured = false;
396
+ }
397
+ }
398
+
399
+ spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
400
+ if (hdmi->audio_configured && hdmi->audio_playing)
401
+ hdmi_start_audio_stream(hdmi);
402
+ hdmi->display_enabled = true;
403
+ spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
404
+
405
+done:
406
+ mutex_unlock(&hdmi->lock);
500407 }
501408
502
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
503
- u8 *edid, int len)
409
+static void hdmi5_bridge_disable(struct drm_bridge *bridge,
410
+ struct drm_bridge_state *bridge_state)
504411 {
505
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
412
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
413
+ unsigned long flags;
414
+
415
+ mutex_lock(&hdmi->lock);
416
+
417
+ spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
418
+ hdmi_stop_audio_stream(hdmi);
419
+ hdmi->display_enabled = false;
420
+ spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
421
+
422
+ hdmi_power_off_full(hdmi);
423
+
424
+ mutex_unlock(&hdmi->lock);
425
+}
426
+
427
+static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
428
+ struct drm_connector *connector)
429
+{
430
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
431
+ struct edid *edid;
506432 bool need_enable;
433
+ int idlemode;
507434 int r;
508435
509436 need_enable = hdmi->core_enabled == false;
....@@ -511,97 +438,64 @@
511438 if (need_enable) {
512439 r = hdmi_core_enable(hdmi);
513440 if (r)
514
- return r;
441
+ return NULL;
515442 }
516443
517
- r = read_edid(hdmi, edid, len);
444
+ mutex_lock(&hdmi->lock);
445
+ r = hdmi_runtime_get(hdmi);
446
+ BUG_ON(r);
447
+
448
+ idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
449
+ /* No-idle mode */
450
+ REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
451
+
452
+ hdmi5_core_ddc_init(&hdmi->core);
453
+
454
+ edid = drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
455
+
456
+ hdmi5_core_ddc_uninit(&hdmi->core);
457
+
458
+ REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
459
+
460
+ hdmi_runtime_put(hdmi);
461
+ mutex_unlock(&hdmi->lock);
518462
519463 if (need_enable)
520464 hdmi_core_disable(hdmi);
521465
522
- return r;
466
+ return (struct edid *)edid;
523467 }
524468
525
-static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
526
- const struct hdmi_avi_infoframe *avi)
527
-{
528
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
529
-
530
- hdmi->cfg.infoframe = *avi;
531
- return 0;
532
-}
533
-
534
-static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
535
- bool hdmi_mode)
536
-{
537
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
538
-
539
- hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
540
- return 0;
541
-}
542
-
543
-static const struct omapdss_hdmi_ops hdmi_ops = {
544
- .connect = hdmi_connect,
545
- .disconnect = hdmi_disconnect,
546
-
547
- .enable = hdmi_display_enable,
548
- .disable = hdmi_display_disable,
549
-
550
- .check_timings = hdmi_display_check_timing,
551
- .set_timings = hdmi_display_set_timing,
552
- .get_timings = hdmi_display_get_timings,
553
-
554
- .read_edid = hdmi_read_edid,
555
- .set_infoframe = hdmi_set_infoframe,
556
- .set_hdmi_mode = hdmi_set_hdmi_mode,
469
+static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
470
+ .attach = hdmi5_bridge_attach,
471
+ .mode_set = hdmi5_bridge_mode_set,
472
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
473
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
474
+ .atomic_reset = drm_atomic_helper_bridge_reset,
475
+ .atomic_enable = hdmi5_bridge_enable,
476
+ .atomic_disable = hdmi5_bridge_disable,
477
+ .get_edid = hdmi5_bridge_get_edid,
557478 };
558479
559
-static void hdmi_init_output(struct omap_hdmi *hdmi)
480
+static void hdmi5_bridge_init(struct omap_hdmi *hdmi)
560481 {
561
- struct omap_dss_device *out = &hdmi->output;
482
+ hdmi->bridge.funcs = &hdmi5_bridge_funcs;
483
+ hdmi->bridge.of_node = hdmi->pdev->dev.of_node;
484
+ hdmi->bridge.ops = DRM_BRIDGE_OP_EDID;
485
+ hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
562486
563
- out->dev = &hdmi->pdev->dev;
564
- out->id = OMAP_DSS_OUTPUT_HDMI;
565
- out->output_type = OMAP_DISPLAY_TYPE_HDMI;
566
- out->name = "hdmi.0";
567
- out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
568
- out->ops.hdmi = &hdmi_ops;
569
- out->owner = THIS_MODULE;
570
-
571
- omapdss_register_output(out);
487
+ drm_bridge_add(&hdmi->bridge);
572488 }
573489
574
-static void hdmi_uninit_output(struct omap_hdmi *hdmi)
490
+static void hdmi5_bridge_cleanup(struct omap_hdmi *hdmi)
575491 {
576
- struct omap_dss_device *out = &hdmi->output;
577
-
578
- omapdss_unregister_output(out);
492
+ drm_bridge_remove(&hdmi->bridge);
579493 }
580494
581
-static int hdmi_probe_of(struct omap_hdmi *hdmi)
582
-{
583
- struct platform_device *pdev = hdmi->pdev;
584
- struct device_node *node = pdev->dev.of_node;
585
- struct device_node *ep;
586
- int r;
495
+/* -----------------------------------------------------------------------------
496
+ * Audio Callbacks
497
+ */
587498
588
- ep = of_graph_get_endpoint_by_regs(node, 0, 0);
589
- if (!ep)
590
- return 0;
591
-
592
- r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
593
- if (r)
594
- goto err;
595
-
596
- of_node_put(ep);
597
- return 0;
598
-
599
-err:
600
- of_node_put(ep);
601
- return r;
602
-}
603
-
604
-/* Audio callbacks */
605499 static int hdmi_audio_startup(struct device *dev,
606500 void (*abort_cb)(struct device *dev))
607501 {
....@@ -722,71 +616,26 @@
722616 return 0;
723617 }
724618
725
-/* HDMI HW IP initialisation */
619
+/* -----------------------------------------------------------------------------
620
+ * Component Bind & Unbind
621
+ */
622
+
726623 static int hdmi5_bind(struct device *dev, struct device *master, void *data)
727624 {
728
- struct platform_device *pdev = to_platform_device(dev);
729625 struct dss_device *dss = dss_get_device(master);
730
- struct omap_hdmi *hdmi;
626
+ struct omap_hdmi *hdmi = dev_get_drvdata(dev);
731627 int r;
732
- int irq;
733628
734
- hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
735
- if (!hdmi)
736
- return -ENOMEM;
737
-
738
- hdmi->pdev = pdev;
739629 hdmi->dss = dss;
740
- dev_set_drvdata(&pdev->dev, hdmi);
741630
742
- mutex_init(&hdmi->lock);
743
- spin_lock_init(&hdmi->audio_playing_lock);
744
-
745
- r = hdmi_probe_of(hdmi);
631
+ r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
746632 if (r)
747
- goto err_free;
748
-
749
- r = hdmi_wp_init(pdev, &hdmi->wp, 5);
750
- if (r)
751
- goto err_free;
752
-
753
- r = hdmi_pll_init(dss, pdev, &hdmi->pll, &hdmi->wp);
754
- if (r)
755
- goto err_free;
756
-
757
- r = hdmi_phy_init(pdev, &hdmi->phy, 5);
758
- if (r)
759
- goto err_pll;
760
-
761
- r = hdmi5_core_init(pdev, &hdmi->core);
762
- if (r)
763
- goto err_pll;
764
-
765
- irq = platform_get_irq(pdev, 0);
766
- if (irq < 0) {
767
- DSSERR("platform_get_irq failed\n");
768
- r = -ENODEV;
769
- goto err_pll;
770
- }
771
-
772
- r = devm_request_threaded_irq(&pdev->dev, irq,
773
- NULL, hdmi_irq_handler,
774
- IRQF_ONESHOT, "OMAP HDMI", hdmi);
775
- if (r) {
776
- DSSERR("HDMI IRQ request failed\n");
777
- goto err_pll;
778
- }
779
-
780
- pm_runtime_enable(&pdev->dev);
781
-
782
- hdmi_init_output(hdmi);
633
+ return r;
783634
784635 r = hdmi_audio_register(hdmi);
785636 if (r) {
786637 DSSERR("Registering HDMI audio failed %d\n", r);
787
- hdmi_uninit_output(hdmi);
788
- pm_runtime_disable(&pdev->dev);
789
- return r;
638
+ goto err_pll_uninit;
790639 }
791640
792641 hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
....@@ -794,10 +643,8 @@
794643
795644 return 0;
796645
797
-err_pll:
646
+err_pll_uninit:
798647 hdmi_pll_uninit(&hdmi->pll);
799
-err_free:
800
- kfree(hdmi);
801648 return r;
802649 }
803650
....@@ -810,13 +657,7 @@
810657 if (hdmi->audio_pdev)
811658 platform_device_unregister(hdmi->audio_pdev);
812659
813
- hdmi_uninit_output(hdmi);
814
-
815660 hdmi_pll_uninit(&hdmi->pll);
816
-
817
- pm_runtime_disable(dev);
818
-
819
- kfree(hdmi);
820661 }
821662
822663 static const struct component_ops hdmi5_component_ops = {
....@@ -824,42 +665,152 @@
824665 .unbind = hdmi5_unbind,
825666 };
826667
668
+/* -----------------------------------------------------------------------------
669
+ * Probe & Remove, Suspend & Resume
670
+ */
671
+
672
+static int hdmi5_init_output(struct omap_hdmi *hdmi)
673
+{
674
+ struct omap_dss_device *out = &hdmi->output;
675
+ int r;
676
+
677
+ hdmi5_bridge_init(hdmi);
678
+
679
+ out->dev = &hdmi->pdev->dev;
680
+ out->id = OMAP_DSS_OUTPUT_HDMI;
681
+ out->type = OMAP_DISPLAY_TYPE_HDMI;
682
+ out->name = "hdmi.0";
683
+ out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
684
+ out->owner = THIS_MODULE;
685
+ out->of_port = 0;
686
+
687
+ r = omapdss_device_init_output(out, &hdmi->bridge);
688
+ if (r < 0) {
689
+ hdmi5_bridge_cleanup(hdmi);
690
+ return r;
691
+ }
692
+
693
+ omapdss_device_register(out);
694
+
695
+ return 0;
696
+}
697
+
698
+static void hdmi5_uninit_output(struct omap_hdmi *hdmi)
699
+{
700
+ struct omap_dss_device *out = &hdmi->output;
701
+
702
+ omapdss_device_unregister(out);
703
+ omapdss_device_cleanup_output(out);
704
+
705
+ hdmi5_bridge_cleanup(hdmi);
706
+}
707
+
708
+static int hdmi5_probe_of(struct omap_hdmi *hdmi)
709
+{
710
+ struct platform_device *pdev = hdmi->pdev;
711
+ struct device_node *node = pdev->dev.of_node;
712
+ struct device_node *ep;
713
+ int r;
714
+
715
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
716
+ if (!ep)
717
+ return 0;
718
+
719
+ r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
720
+ of_node_put(ep);
721
+ return r;
722
+}
723
+
827724 static int hdmi5_probe(struct platform_device *pdev)
828725 {
829
- return component_add(&pdev->dev, &hdmi5_component_ops);
726
+ struct omap_hdmi *hdmi;
727
+ int irq;
728
+ int r;
729
+
730
+ hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
731
+ if (!hdmi)
732
+ return -ENOMEM;
733
+
734
+ hdmi->pdev = pdev;
735
+
736
+ dev_set_drvdata(&pdev->dev, hdmi);
737
+
738
+ mutex_init(&hdmi->lock);
739
+ spin_lock_init(&hdmi->audio_playing_lock);
740
+
741
+ r = hdmi5_probe_of(hdmi);
742
+ if (r)
743
+ goto err_free;
744
+
745
+ r = hdmi_wp_init(pdev, &hdmi->wp, 5);
746
+ if (r)
747
+ goto err_free;
748
+
749
+ r = hdmi_phy_init(pdev, &hdmi->phy, 5);
750
+ if (r)
751
+ goto err_free;
752
+
753
+ r = hdmi5_core_init(pdev, &hdmi->core);
754
+ if (r)
755
+ goto err_free;
756
+
757
+ irq = platform_get_irq(pdev, 0);
758
+ if (irq < 0) {
759
+ DSSERR("platform_get_irq failed\n");
760
+ r = -ENODEV;
761
+ goto err_free;
762
+ }
763
+
764
+ r = devm_request_threaded_irq(&pdev->dev, irq,
765
+ NULL, hdmi_irq_handler,
766
+ IRQF_ONESHOT, "OMAP HDMI", hdmi);
767
+ if (r) {
768
+ DSSERR("HDMI IRQ request failed\n");
769
+ goto err_free;
770
+ }
771
+
772
+ hdmi->vdda_reg = devm_regulator_get(&pdev->dev, "vdda");
773
+ if (IS_ERR(hdmi->vdda_reg)) {
774
+ r = PTR_ERR(hdmi->vdda_reg);
775
+ if (r != -EPROBE_DEFER)
776
+ DSSERR("can't get VDDA regulator\n");
777
+ goto err_free;
778
+ }
779
+
780
+ pm_runtime_enable(&pdev->dev);
781
+
782
+ r = hdmi5_init_output(hdmi);
783
+ if (r)
784
+ goto err_pm_disable;
785
+
786
+ r = component_add(&pdev->dev, &hdmi5_component_ops);
787
+ if (r)
788
+ goto err_uninit_output;
789
+
790
+ return 0;
791
+
792
+err_uninit_output:
793
+ hdmi5_uninit_output(hdmi);
794
+err_pm_disable:
795
+ pm_runtime_disable(&pdev->dev);
796
+err_free:
797
+ kfree(hdmi);
798
+ return r;
830799 }
831800
832801 static int hdmi5_remove(struct platform_device *pdev)
833802 {
803
+ struct omap_hdmi *hdmi = platform_get_drvdata(pdev);
804
+
834805 component_del(&pdev->dev, &hdmi5_component_ops);
806
+
807
+ hdmi5_uninit_output(hdmi);
808
+
809
+ pm_runtime_disable(&pdev->dev);
810
+
811
+ kfree(hdmi);
835812 return 0;
836813 }
837
-
838
-static int hdmi_runtime_suspend(struct device *dev)
839
-{
840
- struct omap_hdmi *hdmi = dev_get_drvdata(dev);
841
-
842
- dispc_runtime_put(hdmi->dss->dispc);
843
-
844
- return 0;
845
-}
846
-
847
-static int hdmi_runtime_resume(struct device *dev)
848
-{
849
- struct omap_hdmi *hdmi = dev_get_drvdata(dev);
850
- int r;
851
-
852
- r = dispc_runtime_get(hdmi->dss->dispc);
853
- if (r < 0)
854
- return r;
855
-
856
- return 0;
857
-}
858
-
859
-static const struct dev_pm_ops hdmi_pm_ops = {
860
- .runtime_suspend = hdmi_runtime_suspend,
861
- .runtime_resume = hdmi_runtime_resume,
862
-};
863814
864815 static const struct of_device_id hdmi_of_match[] = {
865816 { .compatible = "ti,omap5-hdmi", },
....@@ -872,7 +823,6 @@
872823 .remove = hdmi5_remove,
873824 .driver = {
874825 .name = "omapdss_hdmi5",
875
- .pm = &hdmi_pm_ops,
876826 .of_match_table = hdmi_of_match,
877827 .suppress_bind_attrs = true,
878828 },