forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/omapdrm/dss/hdmi4.c
....@@ -1,21 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * HDMI interface DSS driver for TI's OMAP4 family of SoCs.
34 *
45 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
56 * Authors: Yong Zhi
67 * Mythri pk <mythripk@ti.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify it
9
- * under the terms of the GNU General Public License version 2 as published by
10
- * the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful, but WITHOUT
13
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
- * more details.
16
- *
17
- * You should have received a copy of the GNU General Public License along with
18
- * this program. If not, see <http://www.gnu.org/licenses/>.
198 */
209
2110 #define DSS_SUBSYS_NAME "HDMI"
....@@ -31,13 +20,15 @@
3120 #include <linux/platform_device.h>
3221 #include <linux/pm_runtime.h>
3322 #include <linux/clk.h>
34
-#include <linux/gpio.h>
3523 #include <linux/regulator/consumer.h>
3624 #include <linux/component.h>
3725 #include <linux/of.h>
3826 #include <linux/of_graph.h>
3927 #include <sound/omap-hdmi-audio.h>
4028 #include <media/cec.h>
29
+
30
+#include <drm/drm_atomic.h>
31
+#include <drm/drm_atomic_state_helper.h>
4132
4233 #include "omapdss.h"
4334 #include "hdmi4_core.h"
....@@ -108,26 +99,6 @@
10899 return IRQ_HANDLED;
109100 }
110101
111
-static int hdmi_init_regulator(struct omap_hdmi *hdmi)
112
-{
113
- struct regulator *reg;
114
-
115
- if (hdmi->vdda_reg != NULL)
116
- return 0;
117
-
118
- reg = devm_regulator_get(&hdmi->pdev->dev, "vdda");
119
-
120
- if (IS_ERR(reg)) {
121
- if (PTR_ERR(reg) != -EPROBE_DEFER)
122
- DSSERR("can't get VDDA regulator\n");
123
- return PTR_ERR(reg);
124
- }
125
-
126
- hdmi->vdda_reg = reg;
127
-
128
- return 0;
129
-}
130
-
131102 static int hdmi_power_on_core(struct omap_hdmi *hdmi)
132103 {
133104 int r;
....@@ -174,7 +145,7 @@
174145 static int hdmi_power_on_full(struct omap_hdmi *hdmi)
175146 {
176147 int r;
177
- struct videomode *vm;
148
+ const struct videomode *vm;
178149 struct hdmi_wp_data *wp = &hdmi->wp;
179150 struct dss_pll_clock_info hdmi_cinfo = { 0 };
180151 unsigned int pc;
....@@ -227,9 +198,6 @@
227198
228199 hdmi4_configure(&hdmi->core, &hdmi->wp, &hdmi->cfg);
229200
230
- /* tv size */
231
- dss_mgr_set_timings(&hdmi->output, vm);
232
-
233201 r = dss_mgr_enable(&hdmi->output);
234202 if (r)
235203 goto err_mgr_enable;
....@@ -271,39 +239,6 @@
271239 hdmi_power_off_core(hdmi);
272240 }
273241
274
-static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
275
- struct videomode *vm)
276
-{
277
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
278
-
279
- if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
280
- return -EINVAL;
281
-
282
- return 0;
283
-}
284
-
285
-static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
286
- struct videomode *vm)
287
-{
288
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
289
-
290
- mutex_lock(&hdmi->lock);
291
-
292
- hdmi->cfg.vm = *vm;
293
-
294
- dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock);
295
-
296
- mutex_unlock(&hdmi->lock);
297
-}
298
-
299
-static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
300
- struct videomode *vm)
301
-{
302
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
303
-
304
- *vm = hdmi->cfg.vm;
305
-}
306
-
307242 static int hdmi_dump_regs(struct seq_file *s, void *p)
308243 {
309244 struct omap_hdmi *hdmi = s->private;
....@@ -325,23 +260,6 @@
325260 return 0;
326261 }
327262
328
-static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
329
-{
330
- int r;
331
-
332
- mutex_lock(&hdmi->lock);
333
-
334
- r = hdmi_runtime_get(hdmi);
335
- BUG_ON(r);
336
-
337
- r = hdmi4_read_edid(&hdmi->core, buf, len);
338
-
339
- hdmi_runtime_put(hdmi);
340
- mutex_unlock(&hdmi->lock);
341
-
342
- return r;
343
-}
344
-
345263 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
346264 {
347265 hdmi_wp_audio_enable(&hd->wp, true);
....@@ -352,72 +270,6 @@
352270 {
353271 hdmi4_audio_stop(&hd->core, &hd->wp);
354272 hdmi_wp_audio_enable(&hd->wp, false);
355
-}
356
-
357
-static int hdmi_display_enable(struct omap_dss_device *dssdev)
358
-{
359
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
360
- unsigned long flags;
361
- int r = 0;
362
-
363
- DSSDBG("ENTER hdmi_display_enable\n");
364
-
365
- mutex_lock(&hdmi->lock);
366
-
367
- if (!dssdev->dispc_channel_connected) {
368
- DSSERR("failed to enable display: no output/manager\n");
369
- r = -ENODEV;
370
- goto err0;
371
- }
372
-
373
- r = hdmi_power_on_full(hdmi);
374
- if (r) {
375
- DSSERR("failed to power on device\n");
376
- goto err0;
377
- }
378
-
379
- if (hdmi->audio_configured) {
380
- r = hdmi4_audio_config(&hdmi->core, &hdmi->wp,
381
- &hdmi->audio_config,
382
- hdmi->cfg.vm.pixelclock);
383
- if (r) {
384
- DSSERR("Error restoring audio configuration: %d", r);
385
- hdmi->audio_abort_cb(&hdmi->pdev->dev);
386
- hdmi->audio_configured = false;
387
- }
388
- }
389
-
390
- spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
391
- if (hdmi->audio_configured && hdmi->audio_playing)
392
- hdmi_start_audio_stream(hdmi);
393
- hdmi->display_enabled = true;
394
- spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
395
-
396
- mutex_unlock(&hdmi->lock);
397
- return 0;
398
-
399
-err0:
400
- mutex_unlock(&hdmi->lock);
401
- return r;
402
-}
403
-
404
-static void hdmi_display_disable(struct omap_dss_device *dssdev)
405
-{
406
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
407
- unsigned long flags;
408
-
409
- DSSDBG("Enter hdmi_display_disable\n");
410
-
411
- mutex_lock(&hdmi->lock);
412
-
413
- spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
414
- hdmi_stop_audio_stream(hdmi);
415
- hdmi->display_enabled = false;
416
- spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
417
-
418
- hdmi_power_off_full(hdmi);
419
-
420
- mutex_unlock(&hdmi->lock);
421273 }
422274
423275 int hdmi4_core_enable(struct hdmi_core_data *core)
....@@ -456,50 +308,139 @@
456308 mutex_unlock(&hdmi->lock);
457309 }
458310
459
-static int hdmi_connect(struct omap_dss_device *dssdev,
460
- struct omap_dss_device *dst)
311
+/* -----------------------------------------------------------------------------
312
+ * DRM Bridge Operations
313
+ */
314
+
315
+static int hdmi4_bridge_attach(struct drm_bridge *bridge,
316
+ enum drm_bridge_attach_flags flags)
461317 {
462
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
463
- int r;
318
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
464319
465
- r = hdmi_init_regulator(hdmi);
466
- if (r)
467
- return r;
320
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
321
+ return -EINVAL;
468322
469
- r = dss_mgr_connect(&hdmi->output, dssdev);
470
- if (r)
471
- return r;
472
-
473
- r = omapdss_output_set_device(dssdev, dst);
474
- if (r) {
475
- DSSERR("failed to connect output to new device: %s\n",
476
- dst->name);
477
- dss_mgr_disconnect(&hdmi->output, dssdev);
478
- return r;
479
- }
480
-
481
- return 0;
323
+ return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge,
324
+ bridge, flags);
482325 }
483326
484
-static void hdmi_disconnect(struct omap_dss_device *dssdev,
485
- struct omap_dss_device *dst)
327
+static void hdmi4_bridge_mode_set(struct drm_bridge *bridge,
328
+ const struct drm_display_mode *mode,
329
+ const struct drm_display_mode *adjusted_mode)
486330 {
487
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
331
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
488332
489
- WARN_ON(dst != dssdev->dst);
333
+ mutex_lock(&hdmi->lock);
490334
491
- if (dst != dssdev->dst)
335
+ drm_display_mode_to_videomode(adjusted_mode, &hdmi->cfg.vm);
336
+
337
+ dispc_set_tv_pclk(hdmi->dss->dispc, adjusted_mode->clock * 1000);
338
+
339
+ mutex_unlock(&hdmi->lock);
340
+}
341
+
342
+static void hdmi4_bridge_enable(struct drm_bridge *bridge,
343
+ struct drm_bridge_state *bridge_state)
344
+{
345
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
346
+ struct drm_atomic_state *state = bridge_state->base.state;
347
+ struct drm_connector_state *conn_state;
348
+ struct drm_connector *connector;
349
+ struct drm_crtc_state *crtc_state;
350
+ unsigned long flags;
351
+ int ret;
352
+
353
+ /*
354
+ * None of these should fail, as the bridge can't be enabled without a
355
+ * valid CRTC to connector path with fully populated new states.
356
+ */
357
+ connector = drm_atomic_get_new_connector_for_encoder(state,
358
+ bridge->encoder);
359
+ if (WARN_ON(!connector))
360
+ return;
361
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
362
+ if (WARN_ON(!conn_state))
363
+ return;
364
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
365
+ if (WARN_ON(!crtc_state))
492366 return;
493367
494
- omapdss_output_unset_device(dssdev);
368
+ hdmi->cfg.hdmi_dvi_mode = connector->display_info.is_hdmi
369
+ ? HDMI_HDMI : HDMI_DVI;
495370
496
- dss_mgr_disconnect(&hdmi->output, dssdev);
371
+ if (connector->display_info.is_hdmi) {
372
+ const struct drm_display_mode *mode;
373
+ struct hdmi_avi_infoframe avi;
374
+
375
+ mode = &crtc_state->adjusted_mode;
376
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
377
+ mode);
378
+ if (ret == 0)
379
+ hdmi->cfg.infoframe = avi;
380
+ }
381
+
382
+ mutex_lock(&hdmi->lock);
383
+
384
+ ret = hdmi_power_on_full(hdmi);
385
+ if (ret) {
386
+ DSSERR("failed to power on device\n");
387
+ goto done;
388
+ }
389
+
390
+ if (hdmi->audio_configured) {
391
+ ret = hdmi4_audio_config(&hdmi->core, &hdmi->wp,
392
+ &hdmi->audio_config,
393
+ hdmi->cfg.vm.pixelclock);
394
+ if (ret) {
395
+ DSSERR("Error restoring audio configuration: %d", ret);
396
+ hdmi->audio_abort_cb(&hdmi->pdev->dev);
397
+ hdmi->audio_configured = false;
398
+ }
399
+ }
400
+
401
+ spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
402
+ if (hdmi->audio_configured && hdmi->audio_playing)
403
+ hdmi_start_audio_stream(hdmi);
404
+ hdmi->display_enabled = true;
405
+ spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
406
+
407
+done:
408
+ mutex_unlock(&hdmi->lock);
497409 }
498410
499
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
500
- u8 *edid, int len)
411
+static void hdmi4_bridge_disable(struct drm_bridge *bridge,
412
+ struct drm_bridge_state *bridge_state)
501413 {
502
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
414
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
415
+ unsigned long flags;
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);
427
+}
428
+
429
+static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge,
430
+ enum drm_connector_status status)
431
+{
432
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
433
+
434
+ if (status == connector_status_disconnected)
435
+ hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
436
+}
437
+
438
+static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge,
439
+ struct drm_connector *connector)
440
+{
441
+ struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
442
+ struct edid *edid = NULL;
443
+ unsigned int cec_addr;
503444 bool need_enable;
504445 int r;
505446
....@@ -508,109 +449,70 @@
508449 if (need_enable) {
509450 r = hdmi4_core_enable(&hdmi->core);
510451 if (r)
511
- return r;
452
+ return NULL;
512453 }
513454
514
- r = read_edid(hdmi, edid, len);
515
- if (r >= 256)
516
- hdmi4_cec_set_phys_addr(&hdmi->core,
517
- cec_get_edid_phys_addr(edid, r, NULL));
518
- else
519
- hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
455
+ mutex_lock(&hdmi->lock);
456
+ r = hdmi_runtime_get(hdmi);
457
+ BUG_ON(r);
458
+
459
+ r = hdmi4_core_ddc_init(&hdmi->core);
460
+ if (r)
461
+ goto done;
462
+
463
+ edid = drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core);
464
+
465
+done:
466
+ hdmi_runtime_put(hdmi);
467
+ mutex_unlock(&hdmi->lock);
468
+
469
+ if (edid && edid->extensions) {
470
+ unsigned int len = (edid->extensions + 1) * EDID_LENGTH;
471
+
472
+ cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL);
473
+ } else {
474
+ cec_addr = CEC_PHYS_ADDR_INVALID;
475
+ }
476
+
477
+ hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
478
+
520479 if (need_enable)
521480 hdmi4_core_disable(&hdmi->core);
522481
523
- return r;
482
+ return edid;
524483 }
525484
526
-static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
527
-{
528
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
529
-
530
- hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
531
-}
532
-
533
-static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
534
- const struct hdmi_avi_infoframe *avi)
535
-{
536
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
537
-
538
- hdmi->cfg.infoframe = *avi;
539
- return 0;
540
-}
541
-
542
-static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
543
- bool hdmi_mode)
544
-{
545
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
546
-
547
- hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
548
- return 0;
549
-}
550
-
551
-static const struct omapdss_hdmi_ops hdmi_ops = {
552
- .connect = hdmi_connect,
553
- .disconnect = hdmi_disconnect,
554
-
555
- .enable = hdmi_display_enable,
556
- .disable = hdmi_display_disable,
557
-
558
- .check_timings = hdmi_display_check_timing,
559
- .set_timings = hdmi_display_set_timing,
560
- .get_timings = hdmi_display_get_timings,
561
-
562
- .read_edid = hdmi_read_edid,
563
- .lost_hotplug = hdmi_lost_hotplug,
564
- .set_infoframe = hdmi_set_infoframe,
565
- .set_hdmi_mode = hdmi_set_hdmi_mode,
485
+static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
486
+ .attach = hdmi4_bridge_attach,
487
+ .mode_set = hdmi4_bridge_mode_set,
488
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
489
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
490
+ .atomic_reset = drm_atomic_helper_bridge_reset,
491
+ .atomic_enable = hdmi4_bridge_enable,
492
+ .atomic_disable = hdmi4_bridge_disable,
493
+ .hpd_notify = hdmi4_bridge_hpd_notify,
494
+ .get_edid = hdmi4_bridge_get_edid,
566495 };
567496
568
-static void hdmi_init_output(struct omap_hdmi *hdmi)
497
+static void hdmi4_bridge_init(struct omap_hdmi *hdmi)
569498 {
570
- struct omap_dss_device *out = &hdmi->output;
499
+ hdmi->bridge.funcs = &hdmi4_bridge_funcs;
500
+ hdmi->bridge.of_node = hdmi->pdev->dev.of_node;
501
+ hdmi->bridge.ops = DRM_BRIDGE_OP_EDID;
502
+ hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
571503
572
- out->dev = &hdmi->pdev->dev;
573
- out->id = OMAP_DSS_OUTPUT_HDMI;
574
- out->output_type = OMAP_DISPLAY_TYPE_HDMI;
575
- out->name = "hdmi.0";
576
- out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
577
- out->ops.hdmi = &hdmi_ops;
578
- out->owner = THIS_MODULE;
579
-
580
- omapdss_register_output(out);
504
+ drm_bridge_add(&hdmi->bridge);
581505 }
582506
583
-static void hdmi_uninit_output(struct omap_hdmi *hdmi)
507
+static void hdmi4_bridge_cleanup(struct omap_hdmi *hdmi)
584508 {
585
- struct omap_dss_device *out = &hdmi->output;
586
-
587
- omapdss_unregister_output(out);
509
+ drm_bridge_remove(&hdmi->bridge);
588510 }
589511
590
-static int hdmi_probe_of(struct omap_hdmi *hdmi)
591
-{
592
- struct platform_device *pdev = hdmi->pdev;
593
- struct device_node *node = pdev->dev.of_node;
594
- struct device_node *ep;
595
- int r;
512
+/* -----------------------------------------------------------------------------
513
+ * Audio Callbacks
514
+ */
596515
597
- ep = of_graph_get_endpoint_by_regs(node, 0, 0);
598
- if (!ep)
599
- return 0;
600
-
601
- r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
602
- if (r)
603
- goto err;
604
-
605
- of_node_put(ep);
606
- return 0;
607
-
608
-err:
609
- of_node_put(ep);
610
- return r;
611
-}
612
-
613
-/* Audio callbacks */
614516 static int hdmi_audio_startup(struct device *dev,
615517 void (*abort_cb)(struct device *dev))
616518 {
....@@ -725,86 +627,49 @@
725627 return 0;
726628 }
727629
728
-/* HDMI HW IP initialisation */
630
+/* -----------------------------------------------------------------------------
631
+ * Component Bind & Unbind
632
+ */
633
+
729634 static int hdmi4_bind(struct device *dev, struct device *master, void *data)
730635 {
731
- struct platform_device *pdev = to_platform_device(dev);
732636 struct dss_device *dss = dss_get_device(master);
733
- struct omap_hdmi *hdmi;
637
+ struct omap_hdmi *hdmi = dev_get_drvdata(dev);
734638 int r;
735
- int irq;
736639
737
- hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
738
- if (!hdmi)
739
- return -ENOMEM;
740
-
741
- hdmi->pdev = pdev;
742640 hdmi->dss = dss;
743
- dev_set_drvdata(&pdev->dev, hdmi);
744641
745
- mutex_init(&hdmi->lock);
746
- spin_lock_init(&hdmi->audio_playing_lock);
747
-
748
- r = hdmi_probe_of(hdmi);
642
+ r = hdmi_runtime_get(hdmi);
749643 if (r)
750
- goto err_free;
644
+ return r;
751645
752
- r = hdmi_wp_init(pdev, &hdmi->wp, 4);
646
+ r = hdmi_pll_init(dss, hdmi->pdev, &hdmi->pll, &hdmi->wp);
753647 if (r)
754
- goto err_free;
648
+ goto err_runtime_put;
755649
756
- r = hdmi_pll_init(dss, pdev, &hdmi->pll, &hdmi->wp);
650
+ r = hdmi4_cec_init(hdmi->pdev, &hdmi->core, &hdmi->wp);
757651 if (r)
758
- goto err_free;
759
-
760
- r = hdmi_phy_init(pdev, &hdmi->phy, 4);
761
- if (r)
762
- goto err_pll;
763
-
764
- r = hdmi4_core_init(pdev, &hdmi->core);
765
- if (r)
766
- goto err_pll;
767
-
768
- r = hdmi4_cec_init(pdev, &hdmi->core, &hdmi->wp);
769
- if (r)
770
- goto err_pll;
771
-
772
- irq = platform_get_irq(pdev, 0);
773
- if (irq < 0) {
774
- DSSERR("platform_get_irq failed\n");
775
- r = -ENODEV;
776
- goto err_pll;
777
- }
778
-
779
- r = devm_request_threaded_irq(&pdev->dev, irq,
780
- NULL, hdmi_irq_handler,
781
- IRQF_ONESHOT, "OMAP HDMI", hdmi);
782
- if (r) {
783
- DSSERR("HDMI IRQ request failed\n");
784
- goto err_pll;
785
- }
786
-
787
- pm_runtime_enable(&pdev->dev);
788
-
789
- hdmi_init_output(hdmi);
652
+ goto err_pll_uninit;
790653
791654 r = hdmi_audio_register(hdmi);
792655 if (r) {
793656 DSSERR("Registering HDMI audio failed\n");
794
- hdmi_uninit_output(hdmi);
795
- pm_runtime_disable(&pdev->dev);
796
- return r;
657
+ goto err_cec_uninit;
797658 }
798659
799660 hdmi->debugfs = dss_debugfs_create_file(dss, "hdmi", hdmi_dump_regs,
800661 hdmi);
801662
663
+ hdmi_runtime_put(hdmi);
664
+
802665 return 0;
803666
804
-err_pll:
667
+err_cec_uninit:
668
+ hdmi4_cec_uninit(&hdmi->core);
669
+err_pll_uninit:
805670 hdmi_pll_uninit(&hdmi->pll);
806
-err_free:
807
- kfree(hdmi);
671
+err_runtime_put:
672
+ hdmi_runtime_put(hdmi);
808673 return r;
809674 }
810675
....@@ -817,15 +682,8 @@
817682 if (hdmi->audio_pdev)
818683 platform_device_unregister(hdmi->audio_pdev);
819684
820
- hdmi_uninit_output(hdmi);
821
-
822685 hdmi4_cec_uninit(&hdmi->core);
823
-
824686 hdmi_pll_uninit(&hdmi->pll);
825
-
826
- pm_runtime_disable(dev);
827
-
828
- kfree(hdmi);
829687 }
830688
831689 static const struct component_ops hdmi4_component_ops = {
....@@ -833,42 +691,152 @@
833691 .unbind = hdmi4_unbind,
834692 };
835693
694
+/* -----------------------------------------------------------------------------
695
+ * Probe & Remove, Suspend & Resume
696
+ */
697
+
698
+static int hdmi4_init_output(struct omap_hdmi *hdmi)
699
+{
700
+ struct omap_dss_device *out = &hdmi->output;
701
+ int r;
702
+
703
+ hdmi4_bridge_init(hdmi);
704
+
705
+ out->dev = &hdmi->pdev->dev;
706
+ out->id = OMAP_DSS_OUTPUT_HDMI;
707
+ out->type = OMAP_DISPLAY_TYPE_HDMI;
708
+ out->name = "hdmi.0";
709
+ out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
710
+ out->owner = THIS_MODULE;
711
+ out->of_port = 0;
712
+
713
+ r = omapdss_device_init_output(out, &hdmi->bridge);
714
+ if (r < 0) {
715
+ hdmi4_bridge_cleanup(hdmi);
716
+ return r;
717
+ }
718
+
719
+ omapdss_device_register(out);
720
+
721
+ return 0;
722
+}
723
+
724
+static void hdmi4_uninit_output(struct omap_hdmi *hdmi)
725
+{
726
+ struct omap_dss_device *out = &hdmi->output;
727
+
728
+ omapdss_device_unregister(out);
729
+ omapdss_device_cleanup_output(out);
730
+
731
+ hdmi4_bridge_cleanup(hdmi);
732
+}
733
+
734
+static int hdmi4_probe_of(struct omap_hdmi *hdmi)
735
+{
736
+ struct platform_device *pdev = hdmi->pdev;
737
+ struct device_node *node = pdev->dev.of_node;
738
+ struct device_node *ep;
739
+ int r;
740
+
741
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
742
+ if (!ep)
743
+ return 0;
744
+
745
+ r = hdmi_parse_lanes_of(pdev, ep, &hdmi->phy);
746
+ of_node_put(ep);
747
+ return r;
748
+}
749
+
836750 static int hdmi4_probe(struct platform_device *pdev)
837751 {
838
- return component_add(&pdev->dev, &hdmi4_component_ops);
752
+ struct omap_hdmi *hdmi;
753
+ int irq;
754
+ int r;
755
+
756
+ hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
757
+ if (!hdmi)
758
+ return -ENOMEM;
759
+
760
+ hdmi->pdev = pdev;
761
+
762
+ dev_set_drvdata(&pdev->dev, hdmi);
763
+
764
+ mutex_init(&hdmi->lock);
765
+ spin_lock_init(&hdmi->audio_playing_lock);
766
+
767
+ r = hdmi4_probe_of(hdmi);
768
+ if (r)
769
+ goto err_free;
770
+
771
+ r = hdmi_wp_init(pdev, &hdmi->wp, 4);
772
+ if (r)
773
+ goto err_free;
774
+
775
+ r = hdmi_phy_init(pdev, &hdmi->phy, 4);
776
+ if (r)
777
+ goto err_free;
778
+
779
+ r = hdmi4_core_init(pdev, &hdmi->core);
780
+ if (r)
781
+ goto err_free;
782
+
783
+ irq = platform_get_irq(pdev, 0);
784
+ if (irq < 0) {
785
+ DSSERR("platform_get_irq failed\n");
786
+ r = -ENODEV;
787
+ goto err_free;
788
+ }
789
+
790
+ r = devm_request_threaded_irq(&pdev->dev, irq,
791
+ NULL, hdmi_irq_handler,
792
+ IRQF_ONESHOT, "OMAP HDMI", hdmi);
793
+ if (r) {
794
+ DSSERR("HDMI IRQ request failed\n");
795
+ goto err_free;
796
+ }
797
+
798
+ hdmi->vdda_reg = devm_regulator_get(&pdev->dev, "vdda");
799
+ if (IS_ERR(hdmi->vdda_reg)) {
800
+ r = PTR_ERR(hdmi->vdda_reg);
801
+ if (r != -EPROBE_DEFER)
802
+ DSSERR("can't get VDDA regulator\n");
803
+ goto err_free;
804
+ }
805
+
806
+ pm_runtime_enable(&pdev->dev);
807
+
808
+ r = hdmi4_init_output(hdmi);
809
+ if (r)
810
+ goto err_pm_disable;
811
+
812
+ r = component_add(&pdev->dev, &hdmi4_component_ops);
813
+ if (r)
814
+ goto err_uninit_output;
815
+
816
+ return 0;
817
+
818
+err_uninit_output:
819
+ hdmi4_uninit_output(hdmi);
820
+err_pm_disable:
821
+ pm_runtime_disable(&pdev->dev);
822
+err_free:
823
+ kfree(hdmi);
824
+ return r;
839825 }
840826
841827 static int hdmi4_remove(struct platform_device *pdev)
842828 {
829
+ struct omap_hdmi *hdmi = platform_get_drvdata(pdev);
830
+
843831 component_del(&pdev->dev, &hdmi4_component_ops);
832
+
833
+ hdmi4_uninit_output(hdmi);
834
+
835
+ pm_runtime_disable(&pdev->dev);
836
+
837
+ kfree(hdmi);
844838 return 0;
845839 }
846
-
847
-static int hdmi_runtime_suspend(struct device *dev)
848
-{
849
- struct omap_hdmi *hdmi = dev_get_drvdata(dev);
850
-
851
- dispc_runtime_put(hdmi->dss->dispc);
852
-
853
- return 0;
854
-}
855
-
856
-static int hdmi_runtime_resume(struct device *dev)
857
-{
858
- struct omap_hdmi *hdmi = dev_get_drvdata(dev);
859
- int r;
860
-
861
- r = dispc_runtime_get(hdmi->dss->dispc);
862
- if (r < 0)
863
- return r;
864
-
865
- return 0;
866
-}
867
-
868
-static const struct dev_pm_ops hdmi_pm_ops = {
869
- .runtime_suspend = hdmi_runtime_suspend,
870
- .runtime_resume = hdmi_runtime_resume,
871
-};
872840
873841 static const struct of_device_id hdmi_of_match[] = {
874842 { .compatible = "ti,omap4-hdmi", },
....@@ -880,7 +848,6 @@
880848 .remove = hdmi4_remove,
881849 .driver = {
882850 .name = "omapdss_hdmi",
883
- .pm = &hdmi_pm_ops,
884851 .of_match_table = hdmi_of_match,
885852 .suppress_bind_attrs = true,
886853 },