hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
....@@ -49,6 +49,7 @@
4949 #define DDC_SEGMENT_ADDR 0x30
5050
5151 #define HDMI_EDID_LEN 512
52
+#define HDMI_EDID_BLOCK_LEN 128
5253
5354 /* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
5455 #define SCDC_MIN_SOURCE_VERSION 0x1
....@@ -320,6 +321,7 @@
320321 struct drm_display_mode previous_mode;
321322
322323 struct i2c_adapter *ddc;
324
+ struct cec_adapter *cec_adap;
323325 void __iomem *regs;
324326 bool sink_is_hdmi;
325327 bool sink_has_audio;
....@@ -358,10 +360,13 @@
358360 struct cec_notifier *cec_notifier;
359361
360362 bool initialized; /* hdmi is enabled before bind */
363
+ bool logo_plug_out; /* hdmi is plug out when kernel logo */
361364 hdmi_codec_plugged_cb plugged_cb;
362365 struct device *codec_dev;
363366 enum drm_connector_status last_connector_result;
364367 bool rgb_quant_range_selectable;
368
+ bool update;
369
+ bool hdr2sdr; /* from hdr to sdr */
365370 };
366371
367372 #define HDMI_IH_PHY_STAT0_RX_SENSE \
....@@ -456,10 +461,11 @@
456461 change = drm_helper_hpd_irq_event(hdmi->bridge.dev);
457462
458463 #ifdef CONFIG_CEC_NOTIFIER
459
- if (change)
464
+ if (change) {
460465 cec_notifier_repo_cec_hpd(hdmi->cec_notifier,
461466 hdmi->hpd_state,
462467 ktime_get());
468
+ }
463469 #endif
464470 }
465471 }
....@@ -568,7 +574,8 @@
568574 unsigned char *buf, unsigned int length)
569575 {
570576 struct dw_hdmi_i2c *i2c = hdmi->i2c;
571
- int stat;
577
+ int stat, retry, i;
578
+ bool read_edid = false;
572579
573580 if (!i2c->is_regaddr) {
574581 dev_dbg(hdmi->dev, "set read register address to 0\n");
....@@ -576,27 +583,81 @@
576583 i2c->is_regaddr = true;
577584 }
578585
579
- while (length--) {
580
- reinit_completion(&i2c->cmp);
586
+ /* edid reads are in 128 bytes. scdc reads are in 1 byte */
587
+ if (length == HDMI_EDID_BLOCK_LEN)
588
+ read_edid = true;
581589
582
- hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
583
- if (i2c->is_segment)
584
- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT,
585
- HDMI_I2CM_OPERATION);
586
- else
587
- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
588
- HDMI_I2CM_OPERATION);
590
+ while (length > 0) {
591
+ retry = 100;
592
+ hdmi_writeb(hdmi, i2c->slave_reg, HDMI_I2CM_ADDRESS);
589593
590
- stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
591
- if (!stat)
592
- return -EAGAIN;
594
+ if (read_edid) {
595
+ i2c->slave_reg += 8;
596
+ length -= 8;
597
+ } else {
598
+ i2c->slave_reg++;
599
+ length--;
600
+ }
593601
594
- /* Check for error condition on the bus */
595
- if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR)
602
+ while (retry > 0) {
603
+ if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
604
+ void *data = hdmi->plat_data->phy_data;
605
+
606
+ dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc read\n");
607
+ if (hdmi->plat_data->set_ddc_io)
608
+ hdmi->plat_data->set_ddc_io(data, false);
609
+ return -EPERM;
610
+ }
611
+ reinit_completion(&i2c->cmp);
612
+ if (i2c->is_segment) {
613
+ if (read_edid)
614
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8_EXT,
615
+ HDMI_I2CM_OPERATION);
616
+ else
617
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT,
618
+ HDMI_I2CM_OPERATION);
619
+ } else {
620
+ if (read_edid)
621
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8,
622
+ HDMI_I2CM_OPERATION);
623
+ else
624
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
625
+ HDMI_I2CM_OPERATION);
626
+ }
627
+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
628
+ if (!stat) {
629
+ dev_dbg(hdmi->dev, "ddc read time out\n");
630
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
631
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
632
+ HDMI_I2CM_OPERATION);
633
+ retry -= 10;
634
+ continue;
635
+ }
636
+ /* Check for error condition on the bus */
637
+ if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) {
638
+ dev_dbg(hdmi->dev, "ddc read err\n");
639
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
640
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
641
+ HDMI_I2CM_OPERATION);
642
+ retry--;
643
+ usleep_range(10000, 11000);
644
+ continue;
645
+ }
646
+ /* read success */
647
+ break;
648
+ }
649
+ if (retry <= 0) {
650
+ dev_err(hdmi->dev, "ddc read failed\n");
596651 return -EIO;
652
+ }
597653
598
- *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
654
+ if (read_edid)
655
+ for (i = 0; i < 8; i++)
656
+ *buf++ = hdmi_readb(hdmi, HDMI_I2CM_READ_BUFF0 + i);
657
+ else
658
+ *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
599659 }
660
+
600661 i2c->is_segment = false;
601662
602663 return 0;
....@@ -606,7 +667,7 @@
606667 unsigned char *buf, unsigned int length)
607668 {
608669 struct dw_hdmi_i2c *i2c = hdmi->i2c;
609
- int stat;
670
+ int stat, retry;
610671
611672 if (!i2c->is_regaddr) {
612673 /* Use the first write byte as register address */
....@@ -617,20 +678,53 @@
617678 }
618679
619680 while (length--) {
620
- reinit_completion(&i2c->cmp);
681
+ retry = 100;
621682
622683 hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO);
623684 hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
624
- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE,
625
- HDMI_I2CM_OPERATION);
626685
627
- stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
628
- if (!stat)
629
- return -EAGAIN;
686
+ while (retry > 0) {
687
+ if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)) {
688
+ void *data = hdmi->plat_data->phy_data;
630689
631
- /* Check for error condition on the bus */
632
- if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR)
690
+ dev_dbg(hdmi->dev, "hdmi disconnect, stop ddc write\n");
691
+ if (hdmi->plat_data->set_ddc_io)
692
+ hdmi->plat_data->set_ddc_io(data, false);
693
+ return -EPERM;
694
+ }
695
+ reinit_completion(&i2c->cmp);
696
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE,
697
+ HDMI_I2CM_OPERATION);
698
+
699
+ stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
700
+ if (!stat) {
701
+ dev_dbg(hdmi->dev, "ddc write time out\n");
702
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
703
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
704
+ HDMI_I2CM_OPERATION);
705
+ retry -= 10;
706
+ continue;
707
+ }
708
+
709
+ /* Check for error condition on the bus */
710
+ if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR) {
711
+ dev_dbg(hdmi->dev, "ddc write err\n");
712
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
713
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
714
+ HDMI_I2CM_OPERATION);
715
+ retry--;
716
+ usleep_range(10000, 11000);
717
+ continue;
718
+ }
719
+
720
+ /* write success */
721
+ break;
722
+ }
723
+
724
+ if (retry <= 0) {
725
+ dev_err(hdmi->dev, "ddc write failed\n");
633726 return -EIO;
727
+ }
634728 }
635729
636730 return 0;
....@@ -642,6 +736,7 @@
642736 struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
643737 struct dw_hdmi_i2c *i2c = hdmi->i2c;
644738 u8 addr = msgs[0].addr;
739
+ void *data = hdmi->plat_data->phy_data;
645740 int i, ret = 0;
646741
647742 if (addr == DDC_CI_ADDR)
....@@ -665,6 +760,12 @@
665760 }
666761
667762 mutex_lock(&i2c->lock);
763
+
764
+ if (hdmi->plat_data->set_ddc_io)
765
+ hdmi->plat_data->set_ddc_io(data, true);
766
+
767
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
768
+ udelay(100);
668769
669770 /* Unmute DONE and ERROR interrupts */
670771 hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0);
....@@ -1378,14 +1479,7 @@
13781479 HDMI_VP_CONF_PR_EN_MASK |
13791480 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
13801481
1381
- if ((color_depth == 5 && hdmi->previous_mode.htotal % 4) ||
1382
- (color_depth == 6 && hdmi->previous_mode.htotal % 2))
1383
- hdmi_modb(hdmi, 0, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
1384
- HDMI_VP_STUFF);
1385
- else
1386
- hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
1387
- HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
1388
-
1482
+ hdmi_modb(hdmi, 0, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
13891483 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
13901484
13911485 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
....@@ -1943,10 +2037,22 @@
19432037 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
19442038 break;
19452039 }
2040
+ frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
19462041 } else {
1947
- frame.colorimetry = HDMI_COLORIMETRY_NONE;
1948
- frame.extended_colorimetry =
1949
- HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
2042
+ if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_BT2020) {
2043
+ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
2044
+ frame.extended_colorimetry =
2045
+ HDMI_EXTENDED_COLORIMETRY_BT2020;
2046
+ } else {
2047
+ frame.colorimetry = HDMI_COLORIMETRY_NONE;
2048
+ frame.extended_colorimetry =
2049
+ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
2050
+ }
2051
+
2052
+ if (is_hdmi2 && frame.quantization_range == HDMI_QUANTIZATION_RANGE_FULL)
2053
+ frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_FULL;
2054
+ else
2055
+ frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
19502056 }
19512057
19522058 frame.scan_mode = HDMI_SCAN_MODE_NONE;
....@@ -1986,7 +2092,11 @@
19862092 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
19872093
19882094 /* AVI data byte 4 differences: none */
1989
- val = frame.video_code & 0x7f;
2095
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) ||
2096
+ hdmi->connector.display_info.hdmi.scdc.supported)
2097
+ val = hdmi->vic;
2098
+ else
2099
+ val = frame.video_code & 0x7f;
19902100 hdmi_writeb(hdmi, val, HDMI_FC_AVIVID);
19912101
19922102 /* AVI Data Byte 5- set up input and output pixel repetition */
....@@ -2023,6 +2133,14 @@
20232133 struct hdmi_vendor_infoframe frame;
20242134 u8 buffer[10];
20252135 ssize_t err;
2136
+
2137
+ /* if sink support hdmi2.0, don't send vsi */
2138
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) ||
2139
+ hdmi->connector.display_info.hdmi.scdc.supported) {
2140
+ hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
2141
+ HDMI_FC_DATAUTO0_VSD_MASK);
2142
+ return;
2143
+ }
20262144
20272145 err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
20282146 &hdmi->connector,
....@@ -2188,6 +2306,11 @@
21882306 hdmi_writeb(hdmi, HDR_LSB(frame.max_fall), HDMI_FC_DRM_PB24);
21892307 hdmi_writeb(hdmi, HDR_MSB(frame.max_fall), HDMI_FC_DRM_PB25);
21902308 hdmi_writeb(hdmi, 1, HDMI_FC_DRM_UP);
2309
+ /*
2310
+ * avi and hdr infoframe cannot be sent at the same time
2311
+ * for compatibility with Huawei TV
2312
+ */
2313
+ msleep(300);
21912314 hdmi_modb(hdmi, HDMI_FC_PACKET_DRM_TX_EN,
21922315 HDMI_FC_PACKET_DRM_TX_EN_MASK, HDMI_FC_PACKET_TX_EN);
21932316
....@@ -2215,6 +2338,9 @@
22152338 vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi, vmode->mpixelclock);
22162339 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
22172340 vmode->mtmdsclock /= 2;
2341
+
2342
+ if (hdmi->update)
2343
+ return;
22182344
22192345 /* Set up HDMI_FC_INVIDCONF
22202346 * Some display equipments require that the interval
....@@ -2373,11 +2499,13 @@
23732499 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
23742500
23752501 /* Enable pixel clock and tmds data path */
2376
- hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
2377
- HDMI_MC_CLKDIS_CSCCLK_DISABLE |
2378
- HDMI_MC_CLKDIS_AUDCLK_DISABLE |
2379
- HDMI_MC_CLKDIS_PREPCLK_DISABLE |
2380
- HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
2502
+
2503
+ if (!hdmi->update)
2504
+ hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
2505
+ HDMI_MC_CLKDIS_CSCCLK_DISABLE |
2506
+ HDMI_MC_CLKDIS_AUDCLK_DISABLE |
2507
+ HDMI_MC_CLKDIS_PREPCLK_DISABLE |
2508
+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
23812509 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
23822510 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
23832511
....@@ -2455,11 +2583,42 @@
24552583 HDMI_IH_MUTE_FC_STAT2);
24562584 }
24572585
2586
+static void dw_hdmi_force_output_pattern(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
2587
+{
2588
+ /* force output black */
2589
+ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
2590
+ enum hdmi_quantization_range rgb_quant_range = drm_default_rgb_quant_range(mode);
2591
+
2592
+ if (hdmi->hdmi_data.quant_range == HDMI_QUANTIZATION_RANGE_FULL) {
2593
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS2); /*R*/
2594
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS1); /*G*/
2595
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS0); /*B*/
2596
+ } else if (hdmi->hdmi_data.quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) {
2597
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS2); /*R*/
2598
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS1); /*G*/
2599
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS0); /*B*/
2600
+ } else if (hdmi->hdmi_data.quant_range == HDMI_QUANTIZATION_RANGE_DEFAULT) {
2601
+ if (rgb_quant_range == HDMI_QUANTIZATION_RANGE_FULL) {
2602
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS2); /*R*/
2603
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS1); /*G*/
2604
+ hdmi_writeb(hdmi, 0x00, HDMI_FC_DBGTMDS0); /*B*/
2605
+ } else if (rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED) {
2606
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS2); /*R*/
2607
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS1); /*G*/
2608
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS0); /*B*/
2609
+ }
2610
+ }
2611
+ } else {
2612
+ hdmi_writeb(hdmi, 0x80, HDMI_FC_DBGTMDS2); /*Cr*/
2613
+ hdmi_writeb(hdmi, 0x10, HDMI_FC_DBGTMDS1); /*Y*/
2614
+ hdmi_writeb(hdmi, 0x80, HDMI_FC_DBGTMDS0); /*Cb*/
2615
+ }
2616
+}
2617
+
24582618 static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
24592619 {
24602620 int ret;
24612621 void *data = hdmi->plat_data->phy_data;
2462
- bool need_delay = false;
24632622
24642623 hdmi_disable_overflow_interrupts(hdmi);
24652624
....@@ -2508,6 +2667,9 @@
25082667 hdmi->hdmi_data.enc_out_bus_format =
25092668 MEDIA_BUS_FMT_RGB888_1X24;
25102669
2670
+ if (hdmi->plat_data->set_prev_bus_format)
2671
+ hdmi->plat_data->set_prev_bus_format(data, hdmi->hdmi_data.enc_out_bus_format);
2672
+
25112673 /* TOFIX: Get input encoding from plat data or fallback to none */
25122674 if (hdmi->plat_data->get_enc_in_encoding)
25132675 hdmi->hdmi_data.enc_in_encoding =
....@@ -2537,23 +2699,11 @@
25372699 (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0;
25382700 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
25392701
2702
+ dw_hdmi_force_output_pattern(hdmi, mode);
2703
+
25402704 /* HDMI Initialization Step B.1 */
25412705 hdmi_av_composer(hdmi, mode);
25422706
2543
- /* HDMI Initializateion Step B.2 */
2544
- if (!hdmi->phy.enabled ||
2545
- hdmi->hdmi_data.video_mode.previous_pixelclock !=
2546
- hdmi->hdmi_data.video_mode.mpixelclock ||
2547
- hdmi->hdmi_data.video_mode.previous_tmdsclock !=
2548
- hdmi->hdmi_data.video_mode.mtmdsclock) {
2549
- ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
2550
- &hdmi->previous_mode);
2551
- if (ret)
2552
- return ret;
2553
- hdmi->phy.enabled = true;
2554
- } else {
2555
- need_delay = true;
2556
- }
25572707 /* HDMI Initialization Step B.3 */
25582708 dw_hdmi_enable_video_path(hdmi);
25592709
....@@ -2582,11 +2732,31 @@
25822732 hdmi_video_sample(hdmi);
25832733 hdmi_tx_hdcp_config(hdmi, mode);
25842734
2735
+ /* HDMI Enable phy output */
2736
+ if (!hdmi->phy.enabled ||
2737
+ hdmi->hdmi_data.video_mode.previous_pixelclock !=
2738
+ hdmi->hdmi_data.video_mode.mpixelclock ||
2739
+ hdmi->hdmi_data.video_mode.previous_tmdsclock !=
2740
+ hdmi->hdmi_data.video_mode.mtmdsclock) {
2741
+ ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data,
2742
+ &hdmi->previous_mode);
2743
+ if (ret)
2744
+ return ret;
2745
+ hdmi->phy.enabled = true;
2746
+ }
2747
+
25852748 dw_hdmi_clear_overflow(hdmi);
25862749
2587
- /* XXX: Add delay to make csc work before unmute video. */
2588
- if (need_delay)
2750
+ /*
2751
+ * konka tv should switch pattern after set to yuv420 10bit or
2752
+ * the TV might not recognize the signal.
2753
+ */
2754
+ if (!hdmi->update) {
2755
+ hdmi_writeb(hdmi, 1, HDMI_FC_DBGFORCE);
25892756 msleep(50);
2757
+ hdmi_writeb(hdmi, 0, HDMI_FC_DBGFORCE);
2758
+ }
2759
+
25902760 return 0;
25912761 }
25922762
....@@ -2686,6 +2856,7 @@
26862856 if (hdmi->initialized) {
26872857 hdmi->initialized = false;
26882858 hdmi->disabled = true;
2859
+ hdmi->logo_plug_out = true;
26892860 }
26902861 if (hdmi->bridge_is_on)
26912862 dw_hdmi_poweroff(hdmi);
....@@ -2793,6 +2964,8 @@
27932964
27942965 edid = drm_get_edid(connector, hdmi->ddc);
27952966 if (edid) {
2967
+ int vic = 0;
2968
+
27962969 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
27972970 edid->width_cm, edid->height_cm);
27982971
....@@ -2802,7 +2975,18 @@
28022975 drm_connector_update_edid_property(connector, edid);
28032976 cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
28042977 ret = drm_add_edid_modes(connector, edid);
2805
- dw_hdmi_update_hdr_property(connector);
2978
+
2979
+ list_for_each_entry(mode, &connector->probed_modes, head) {
2980
+ vic = drm_match_cea_mode(mode);
2981
+
2982
+ if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_NONE) {
2983
+ if (vic >= 93 && vic <= 95)
2984
+ mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
2985
+ else if (vic == 98)
2986
+ mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_256_135;
2987
+ }
2988
+ }
2989
+
28062990 kfree(edid);
28072991 } else {
28082992 hdmi->support_hdmi = true;
....@@ -2815,11 +2999,8 @@
28152999
28163000 mode = drm_mode_duplicate(connector->dev, ptr);
28173001 if (mode) {
2818
- if (!i) {
3002
+ if (!i)
28193003 mode->type = DRM_MODE_TYPE_PREFERRED;
2820
- mode->picture_aspect_ratio =
2821
- HDMI_PICTURE_ASPECT_NONE;
2822
- }
28233004 drm_mode_probed_add(connector, mode);
28243005 ret++;
28253006 }
....@@ -2830,6 +3011,7 @@
28303011
28313012 dev_info(hdmi->dev, "failed to get edid\n");
28323013 }
3014
+ dw_hdmi_update_hdr_property(connector);
28333015 dw_hdmi_check_output_type_changed(hdmi);
28343016
28353017 return ret;
....@@ -2892,19 +3074,86 @@
28923074 return ret;
28933075 }
28943076
2895
-static bool hdr_metadata_equal(const struct drm_connector_state *old_state,
3077
+static bool hdr_metadata_equal(struct dw_hdmi *hdmi, const struct drm_connector_state *old_state,
28963078 const struct drm_connector_state *new_state)
28973079 {
28983080 struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
28993081 struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
3082
+ int i, ret;
3083
+ u8 *data;
29003084
2901
- if (!old_blob || !new_blob)
2902
- return old_blob == new_blob;
3085
+ hdmi->hdr2sdr = false;
3086
+
3087
+ if (!old_blob && !new_blob)
3088
+ return true;
3089
+
3090
+ if (!old_blob) {
3091
+ data = (u8 *)new_blob->data;
3092
+
3093
+ for (i = 0; i < new_blob->length; i++)
3094
+ if (data[i])
3095
+ return false;
3096
+
3097
+ return true;
3098
+ }
3099
+
3100
+ if (!new_blob) {
3101
+ data = (u8 *)old_blob->data;
3102
+
3103
+ for (i = 0; i < old_blob->length; i++)
3104
+ if (data[i])
3105
+ return false;
3106
+
3107
+ return true;
3108
+ }
29033109
29043110 if (old_blob->length != new_blob->length)
29053111 return false;
29063112
2907
- return !memcmp(old_blob->data, new_blob->data, old_blob->length);
3113
+ ret = !memcmp(old_blob->data, new_blob->data, old_blob->length);
3114
+
3115
+ if (!ret && new_blob) {
3116
+ data = (u8 *)new_blob->data;
3117
+
3118
+ for (i = 0; i < new_blob->length; i++)
3119
+ if (data[i])
3120
+ break;
3121
+
3122
+ if (i == new_blob->length)
3123
+ hdmi->hdr2sdr = true;
3124
+ }
3125
+
3126
+ return ret;
3127
+}
3128
+
3129
+static bool check_hdr_color_change(struct drm_connector_state *old_state,
3130
+ struct drm_connector_state *new_state,
3131
+ struct dw_hdmi *hdmi)
3132
+{
3133
+ void *data = hdmi->plat_data->phy_data;
3134
+
3135
+ if (!hdr_metadata_equal(hdmi, old_state, new_state)) {
3136
+ hdmi->plat_data->check_hdr_color_change(new_state, data);
3137
+ return true;
3138
+ }
3139
+
3140
+ return false;
3141
+}
3142
+
3143
+static bool check_hdmi_format_change(struct drm_connector_state *old_state,
3144
+ struct drm_connector_state *new_state,
3145
+ struct drm_connector *connector,
3146
+ struct dw_hdmi *hdmi)
3147
+{
3148
+ bool hdr_change, color_change;
3149
+
3150
+ hdr_change = check_hdr_color_change(old_state, new_state, hdmi);
3151
+ color_change = dw_hdmi_color_changed(connector);
3152
+
3153
+ if (hdr_change || color_change)
3154
+ return true;
3155
+
3156
+ return false;
29083157 }
29093158
29103159 static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
....@@ -2925,12 +3174,19 @@
29253174 if (!crtc)
29263175 return 0;
29273176
3177
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
3178
+ if (IS_ERR(crtc_state))
3179
+ return PTR_ERR(crtc_state);
3180
+
3181
+ mode = &crtc_state->mode;
3182
+
29283183 /*
29293184 * If HDMI is enabled in uboot, it's need to record
29303185 * drm_display_mode and set phy status to enabled.
29313186 */
29323187 if (!vmode->mpixelclock) {
2933
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
3188
+ u8 val;
3189
+
29343190 if (hdmi->plat_data->get_enc_in_encoding)
29353191 hdmi->hdmi_data.enc_in_encoding =
29363192 hdmi->plat_data->get_enc_in_encoding(data);
....@@ -2944,27 +3200,84 @@
29443200 hdmi->hdmi_data.enc_out_bus_format =
29453201 hdmi->plat_data->get_output_bus_format(data);
29463202
2947
- mode = &crtc_state->mode;
29483203 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
29493204 vmode->mpixelclock = mode->crtc_clock * 1000;
2950
- vmode->previous_pixelclock = mode->clock;
2951
- vmode->previous_tmdsclock = mode->clock;
3205
+ vmode->previous_pixelclock = mode->clock * 1000;
3206
+ vmode->previous_tmdsclock = mode->clock * 1000;
29523207 vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi,
29533208 vmode->mpixelclock);
29543209 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
29553210 vmode->mtmdsclock /= 2;
3211
+
3212
+ dw_hdmi_force_output_pattern(hdmi, mode);
3213
+
3214
+ hdmi_clk_regenerator_update_pixel_clock(hdmi);
3215
+ hdmi_enable_audio_clk(hdmi, hdmi->audio_enable);
3216
+
3217
+ drm_scdc_readb(hdmi->ddc, SCDC_TMDS_CONFIG, &val);
3218
+
3219
+ /* if plug out before hdmi bind, reset hdmi */
3220
+ if (vmode->mtmdsclock >= 340000000 && !(val & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40))
3221
+ hdmi->logo_plug_out = true;
29563222 }
29573223
2958
- if (!hdr_metadata_equal(old_state, new_state) ||
2959
- dw_hdmi_color_changed(connector)) {
2960
- crtc_state = drm_atomic_get_crtc_state(state, crtc);
2961
- if (IS_ERR(crtc_state))
2962
- return PTR_ERR(crtc_state);
3224
+ if (check_hdmi_format_change(old_state, new_state, connector, hdmi) ||
3225
+ hdmi->logo_plug_out) {
3226
+ u32 mtmdsclk;
29633227
2964
- crtc_state->mode_changed = true;
3228
+ if (hdmi->plat_data->update_color_format)
3229
+ hdmi->plat_data->update_color_format(new_state, data);
3230
+ if (hdmi->plat_data->get_enc_in_encoding)
3231
+ hdmi->hdmi_data.enc_in_encoding =
3232
+ hdmi->plat_data->get_enc_in_encoding(data);
3233
+ if (hdmi->plat_data->get_enc_out_encoding)
3234
+ hdmi->hdmi_data.enc_out_encoding =
3235
+ hdmi->plat_data->get_enc_out_encoding(data);
3236
+ if (hdmi->plat_data->get_input_bus_format)
3237
+ hdmi->hdmi_data.enc_in_bus_format =
3238
+ hdmi->plat_data->get_input_bus_format(data);
3239
+ if (hdmi->plat_data->get_output_bus_format)
3240
+ hdmi->hdmi_data.enc_out_bus_format =
3241
+ hdmi->plat_data->get_output_bus_format(data);
3242
+
3243
+ mtmdsclk = hdmi_get_tmdsclock(hdmi, mode->clock);
3244
+
3245
+ if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
3246
+ mtmdsclk /= 2;
3247
+
3248
+ if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD))
3249
+ return 0;
3250
+
3251
+ if (hdmi->hdmi_data.video_mode.mpixelclock == (mode->clock * 1000) &&
3252
+ hdmi->hdmi_data.video_mode.mtmdsclock == (mtmdsclk * 1000) &&
3253
+ !hdmi->logo_plug_out && !hdmi->disabled) {
3254
+ hdmi->update = true;
3255
+ hdmi_writeb(hdmi, HDMI_FC_GCP_SET_AVMUTE, HDMI_FC_GCP);
3256
+ mdelay(180);
3257
+ handle_plugged_change(hdmi, false);
3258
+ } else {
3259
+ hdmi->update = false;
3260
+ crtc_state->mode_changed = true;
3261
+ hdmi->logo_plug_out = false;
3262
+ }
29653263 }
29663264
29673265 return 0;
3266
+}
3267
+
3268
+static void dw_hdmi_connector_atomic_commit(struct drm_connector *connector,
3269
+ struct drm_connector_state *state)
3270
+{
3271
+ struct dw_hdmi *hdmi =
3272
+ container_of(connector, struct dw_hdmi, connector);
3273
+
3274
+ if (hdmi->update) {
3275
+ dw_hdmi_setup(hdmi, &hdmi->previous_mode);
3276
+ mdelay(50);
3277
+ handle_plugged_change(hdmi, true);
3278
+ hdmi_writeb(hdmi, HDMI_FC_GCP_CLEAR_AVMUTE, HDMI_FC_GCP);
3279
+ hdmi->update = false;
3280
+ }
29683281 }
29693282
29703283 void dw_hdmi_set_quant_range(struct dw_hdmi *hdmi)
....@@ -3006,6 +3319,15 @@
30063319 }
30073320 EXPORT_SYMBOL_GPL(dw_hdmi_get_output_type_cap);
30083321
3322
+void dw_hdmi_set_hpd_wake(struct dw_hdmi *hdmi)
3323
+{
3324
+ if (!hdmi->cec)
3325
+ return;
3326
+
3327
+ dw_hdmi_hpd_wake_up(hdmi->cec);
3328
+}
3329
+EXPORT_SYMBOL_GPL(dw_hdmi_set_hpd_wake);
3330
+
30093331 static void dw_hdmi_connector_force(struct drm_connector *connector)
30103332 {
30113333 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
....@@ -3045,6 +3367,7 @@
30453367 .get_modes = dw_hdmi_connector_get_modes,
30463368 .best_encoder = drm_atomic_helper_best_encoder,
30473369 .atomic_check = dw_hdmi_connector_atomic_check,
3370
+ .atomic_commit = dw_hdmi_connector_atomic_commit,
30483371 };
30493372
30503373 static void dw_hdmi_attach_properties(struct dw_hdmi *hdmi)
....@@ -3172,6 +3495,9 @@
31723495 if (hdmi->next_bridge)
31733496 return MODE_OK;
31743497
3498
+ if (!(hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD) && hdmi->hdr2sdr)
3499
+ return MODE_OK;
3500
+
31753501 if (hdmi->plat_data->mode_valid)
31763502 mode_status = hdmi->plat_data->mode_valid(connector, mode);
31773503
....@@ -3195,12 +3521,21 @@
31953521 static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
31963522 {
31973523 struct dw_hdmi *hdmi = bridge->driver_private;
3524
+ void *data = hdmi->plat_data->phy_data;
31983525
31993526 mutex_lock(&hdmi->mutex);
32003527 hdmi->disabled = true;
3528
+ handle_plugged_change(hdmi, false);
32013529 dw_hdmi_update_power(hdmi);
32023530 dw_hdmi_update_phy_mask(hdmi);
3531
+ if (hdmi->plat_data->dclk_set)
3532
+ hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, false, 0);
32033533 mutex_unlock(&hdmi->mutex);
3534
+
3535
+ mutex_lock(&hdmi->i2c->lock);
3536
+ if (hdmi->plat_data->set_ddc_io)
3537
+ hdmi->plat_data->set_ddc_io(data, false);
3538
+ mutex_unlock(&hdmi->i2c->lock);
32043539 }
32053540
32063541 static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
....@@ -3209,8 +3544,11 @@
32093544
32103545 mutex_lock(&hdmi->mutex);
32113546 hdmi->disabled = false;
3547
+ if (hdmi->plat_data->dclk_set)
3548
+ hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, true, 0);
32123549 dw_hdmi_update_power(hdmi);
32133550 dw_hdmi_update_phy_mask(hdmi);
3551
+ handle_plugged_change(hdmi, true);
32143552 mutex_unlock(&hdmi->mutex);
32153553 }
32163554
....@@ -3456,6 +3794,7 @@
34563794 static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
34573795 .write = hdmi_writeb,
34583796 .read = hdmi_readb,
3797
+ .mod = hdmi_modb,
34593798 .enable = dw_hdmi_cec_enable,
34603799 .disable = dw_hdmi_cec_disable,
34613800 };
....@@ -3464,14 +3803,14 @@
34643803 .reg_bits = 32,
34653804 .val_bits = 8,
34663805 .reg_stride = 1,
3467
- .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR,
3806
+ .max_register = HDMI_I2CM_SCDC_UPDATE1,
34683807 };
34693808
34703809 static const struct regmap_config hdmi_regmap_32bit_config = {
34713810 .reg_bits = 32,
34723811 .val_bits = 32,
34733812 .reg_stride = 4,
3474
- .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2,
3813
+ .max_register = HDMI_I2CM_SCDC_UPDATE1 << 2,
34753814 };
34763815
34773816 static int dw_hdmi_status_show(struct seq_file *s, void *v)
....@@ -3852,6 +4191,7 @@
38524191 hdmi->connector.stereo_allowed = 1;
38534192 hdmi->plat_data = plat_data;
38544193 hdmi->dev = dev;
4194
+ hdmi->audio_enable = true;
38554195 hdmi->sample_rate = 48000;
38564196 hdmi->disabled = true;
38574197 hdmi->rxsense = true;
....@@ -3983,6 +4323,7 @@
39834323 if (ret)
39844324 goto err_iahb;
39854325
4326
+ hdmi->logo_plug_out = false;
39864327 hdmi->initialized = false;
39874328 ret = hdmi_readb(hdmi, HDMI_PHY_STAT0);
39884329 if (((ret & HDMI_PHY_TX_PHY_LOCK) && (ret & HDMI_PHY_HPD) &&
....@@ -3992,8 +4333,14 @@
39924333 hdmi->bridge_is_on = true;
39934334 hdmi->phy.enabled = true;
39944335 hdmi->initialized = true;
4336
+ if (hdmi->plat_data->set_ddc_io)
4337
+ hdmi->plat_data->set_ddc_io(hdmi->plat_data->phy_data, true);
4338
+ if (hdmi->plat_data->dclk_set)
4339
+ hdmi->plat_data->dclk_set(hdmi->plat_data->phy_data, true, 0);
39954340 } else if (ret & HDMI_PHY_TX_PHY_LOCK) {
39964341 hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
4342
+ if (hdmi->plat_data->set_ddc_io)
4343
+ hdmi->plat_data->set_ddc_io(hdmi->plat_data->phy_data, false);
39974344 }
39984345
39994346 init_hpd_work(hdmi);
....@@ -4007,7 +4354,7 @@
40074354
40084355 hdmi->irq = irq;
40094356 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
4010
- dw_hdmi_irq, IRQF_SHARED,
4357
+ dw_hdmi_irq, IRQF_SHARED | IRQF_ONESHOT,
40114358 dev_name(dev), hdmi);
40124359 if (ret)
40134360 goto err_iahb;
....@@ -4126,6 +4473,12 @@
41264473 cec.ops = &dw_hdmi_cec_ops;
41274474 cec.irq = irq;
41284475
4476
+ irq = platform_get_irq(pdev, 1);
4477
+ if (irq < 0)
4478
+ dev_dbg(hdmi->dev, "can't get cec wake up irq\n");
4479
+
4480
+ cec.wake_irq = irq;
4481
+
41294482 pdevinfo.name = "dw-hdmi-cec";
41304483 pdevinfo.data = &cec;
41314484 pdevinfo.size_data = sizeof(cec);
....@@ -4136,7 +4489,8 @@
41364489
41374490 hdmi->extcon = devm_extcon_dev_allocate(hdmi->dev, dw_hdmi_cable);
41384491 if (IS_ERR(hdmi->extcon)) {
4139
- dev_err(hdmi->dev, "allocate extcon failed\n");
4492
+ ret = PTR_ERR(hdmi->extcon);
4493
+ dev_err(hdmi->dev, "allocate extcon failed: %d\n", ret);
41404494 goto err_iahb;
41414495 }
41424496