hdmitx: Fix parsing of HDR10plus and Dovi VSVDBs [1/1]
authorZongdong Jiao <zongdong.jiao@amlogic.com>
Tue, 3 Dec 2019 07:53:48 +0000 (15:53 +0800)
committerZongdong Jiao <zongdong.jiao@amlogic.com>
Wed, 4 Dec 2019 03:25:49 +0000 (20:25 -0700)
PD#SWPL-17786

Problem:
No dolby vision on latest Vizio TVs providing an EDID containing
both dolby vision and HDR10plus VSVDBs in the EDID.

Solution:
If an EDID contains both HDR10plus and Dovi VSVDBs, we are
incorrectly resetting both dovi and hdr10plus parsed info structs.
As a result, we are only left with the parsed info of the later
VSVDB in the EDID. So, if we have a hdr10plus VSVDB after dovi
VSVDB, dovi info will be reset while parsing for hdr10plus, and
we will not report any dovi capabilities to the frameworks. This
is what is happening on these TVs in question.

Parse HDR10plus and Dovi VSVDBs independently of one another. Do
not reset parsed info of one while parsing for the other.

Since Dovi->HDR10+->Dovi transitions are not defined, send zero
drm/vsif packets while exiting HDR10+ playback if going to dovi
mode next.

Verify:
HDR10plus and Dovi capabilities can be simultaneously and correctly
reported to the frameworks.

Change-Id: I7a344638e5a923c88ef23f0b3a03480c5a564548
Signed-off-by: Zongdong Jiao <zongdong.jiao@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amcsc.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c

index ff34654181df109232a29e128ad3d08feee7662e..384839ff11d3525f90007ac0692c225a3b8b2624 100644 (file)
@@ -6591,10 +6591,21 @@ void update_hdr10_plus_pkt(bool enable,
        } else {
                if (!vdev)
                        return;
-               vdev->fresh_tx_hdr_pkt(
-                       &cur_send_info);
-               vdev->fresh_tx_hdr10plus_pkt(0,
-                       &cur_hdr10plus_params);
+               if ((get_dolby_vision_policy() ==
+                    DOLBY_VISION_FOLLOW_SINK) &&
+                   sink_support_hdr(vinfo) &&
+                   (!sink_support_dolby_vision(vinfo))) {
+                       pr_csc(2, "update_hdr10_plus_pkt: DISABLE_VSIF\n");
+                       vdev->fresh_tx_hdr10plus_pkt(
+                               HDR10_PLUS_DISABLE_VSIF,
+                               &cur_hdr10plus_params);
+               } else {
+                       pr_csc(2, "update_hdr10_plus_pkt: ZERO_VSIF\n");
+                       vdev->fresh_tx_hdr_pkt(send_info);
+                       vdev->fresh_tx_hdr10plus_pkt(
+                               HDR10_PLUS_ZERO_VSIF,
+                               &cur_hdr10plus_params);
+               }
                hdr10_plus_pkt_update = HDRPLUS_PKT_IDLE;
                pr_csc(2, "update_hdr10_plus_pkt off\n");
        }
index cbc50b82e3755a89a933c0fe37f756d69b1f4e16..1deffe6b060e21988154f61b61a941a16c7885dc 100644 (file)
@@ -867,14 +867,9 @@ static void Edid_ParsingVendSpec(struct rx_cap *prxcap,
        unsigned char *dat = buf;
        unsigned char pos = 0;
        unsigned int ieeeoui = 0;
+       u8 length = 0;
 
-       memset(dv, 0, sizeof(struct dv_info));
-       memset(hdr10_plus, 0, sizeof(struct hdr10_plus_info));
-
-       dv->block_flag = CORRECT;
-       dv->length = dat[pos] & 0x1f;
-       hdr10_plus->length = dat[pos] & 0x1f;
-       memcpy(dv->rawdata, dat, dv->length + 1);
+       length = dat[pos] & 0x1f;
        pos++;
 
        if (dat[pos] != 1) {
@@ -887,9 +882,12 @@ static void Edid_ParsingVendSpec(struct rx_cap *prxcap,
        ieeeoui = dat[pos++];
        ieeeoui += dat[pos++] << 8;
        ieeeoui += dat[pos++] << 16;
+       pr_info("Edid_ParsingVendSpec:ieeeoui=0x%x,len=%u\n", ieeeoui, length);
 
 /*HDR10+ use vsvdb*/
        if (ieeeoui == HDR10_PLUS_IEEE_OUI) {
+               memset(hdr10_plus, 0, sizeof(struct hdr10_plus_info));
+               hdr10_plus->length = length;
                hdr10_plus->ieeeoui = ieeeoui;
                hdr10_plus->application_version = dat[pos] & 0x3;
                pos++;
@@ -900,6 +898,12 @@ static void Edid_ParsingVendSpec(struct rx_cap *prxcap,
                dv->block_flag = ERROR_OUI;
                return;
        }
+
+/* it is a Dovi block*/
+       memset(dv, 0, sizeof(struct dv_info));
+       dv->block_flag = CORRECT;
+       dv->length = length;
+       memcpy(dv->rawdata, dat, dv->length + 1);
        dv->ieeeoui = ieeeoui;
        dv->ver = (dat[pos] >> 5) & 0x7;
        if ((dv->ver) > 2) {