diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c index 0c90ccb8d78a..76ff26ba7bbd 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_edid.c @@ -909,7 +909,7 @@ static int Edid_ParsingDRMBlock(struct rx_cap *pRXCap, pRXCap->hdr_sup_eotf_sdr = !!(buf[pos] & (0x1 << 0)); pRXCap->hdr_sup_eotf_hdr = !!(buf[pos] & (0x1 << 1)); pRXCap->hdr_sup_eotf_smpte_st_2084 = !!(buf[pos] & (0x1 << 2)); - pRXCap->hdr_sup_eotf_future = !!(buf[pos] & (0x1 << 3)); + pRXCap->hdr_sup_eotf_hlg = !!(buf[pos] & (0x1 << 3)); pos++; pRXCap->hdr_sup_SMD_type1 = !!(buf[pos] & (0x1 << 0)); pos++; @@ -1974,7 +1974,8 @@ int hdmitx_edid_parse(struct hdmitx_dev *hdmitx_device) info->hdr_info.hdr_support = (pRXCap->hdr_sup_eotf_sdr << 0) | (pRXCap->hdr_sup_eotf_hdr << 1) | - (pRXCap->hdr_sup_eotf_smpte_st_2084 << 2); + (pRXCap->hdr_sup_eotf_smpte_st_2084 << 2) | + (pRXCap->hdr_sup_eotf_hlg << 3); info->hdr_info.lumi_max = pRXCap->hdr_lum_max; info->hdr_info.lumi_avg = pRXCap->hdr_lum_avg; info->hdr_info.lumi_min = pRXCap->hdr_lum_min; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c index e94978650d8f..0d73af4b350f 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c @@ -1002,16 +1002,16 @@ static void hdr_work_func(struct work_struct *work) struct hdmitx_dev *hdev = container_of(work, struct hdmitx_dev, work_hdr); - if (hdev->hdr_src_feature == 0) { - unsigned char DRM_HB[3] = {0x87, 0x1, 26}; - unsigned char DRM_DB[26] = {0x0}; + unsigned char DRM_HB[3] = {0x87, 0x1, 26}; + unsigned char DRM_DB[26] = {0x0}; - hdev->HWOp.SetPacket(HDMI_PACKET_DRM, DRM_DB, DRM_HB); - hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020); - msleep(1500); - if (hdev->hdr_src_feature == 0) - hdev->HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL); - } + hdev->HWOp.SetPacket(HDMI_PACKET_DRM, DRM_DB, DRM_HB); + hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, CLR_AVI_BT2020); + msleep(1500);/*delay 1.5s*/ + + if (hdev->hdr_transfer_feature == T_BT709 && + hdev->hdr_color_feature == C_BT709) + hdev->HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL); /* switch_set_state(&hdmi_hdr, hdev->hdr_src_feature); */ } @@ -1022,12 +1022,21 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) struct hdmitx_dev *hdev = &hdmitx_device; unsigned char DRM_HB[3] = {0x87, 0x1, 26}; unsigned char DRM_DB[26] = {0x0}; - static int hdr_state; + /* + *hdr_color_feature: bit 23-16: color_primaries + * 1:bt709 0x9:bt2020 + *hdr_transfer_feature: bit 15-8: transfer_characteristic + * 1:bt709 0xe:bt2020-10 0x10:smpte-st-2084 0x12:hlg(todo) + */ + if (data) { + hdev->hdr_transfer_feature = (data->features >> 8) & 0xff; + hdev->hdr_color_feature = (data->features >> 16) & 0xff; + } if ((!data) || (!(hdev->RXCap.hdr_sup_eotf_smpte_st_2084) && !(hdev->RXCap.hdr_sup_eotf_hdr) && - !(hdev->RXCap.hdr_sup_eotf_sdr))) { - hdev->hdr_src_feature = 0; + !(hdev->RXCap.hdr_sup_eotf_sdr) && + !(hdev->RXCap.hdr_sup_eotf_hlg))) { DRM_HB[1] = 0; DRM_HB[2] = 0; hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL); @@ -1036,22 +1045,13 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) return; } - hdev->hdr_src_feature = (((data->features >> 16) & 0xff) == 0x9); - if (hdr_state != hdev->hdr_src_feature) { - hdr_state = hdev->hdr_src_feature; + /*SDR*/ + if (hdev->hdr_transfer_feature == T_BT709 && + hdev->hdr_color_feature == C_BT709) { schedule_work(&hdev->work_hdr); + return; } - /* update DRM data */ - if ((hdev->RXCap.hdr_sup_eotf_smpte_st_2084) && hdev->hdr_src_feature) - DRM_DB[0] = 0x02; /* SMPTE ST 2084 */ - else { - memset(DRM_DB, 0, sizeof(DRM_DB)); - hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL); - hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020, - CLR_AVI_BT2020); - return; - } DRM_DB[1] = 0x0; DRM_DB[2] = GET_LOW8BIT(data->primaries[0][0]); DRM_DB[3] = GET_HIGH8BIT(data->primaries[0][0]); @@ -1078,9 +1078,70 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data) DRM_DB[24] = GET_LOW8BIT(data->max_frame_average); DRM_DB[25] = GET_HIGH8BIT(data->max_frame_average); - hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, DRM_DB, DRM_HB); + /* bt2020 + gamma transfer */ + if (hdev->hdr_transfer_feature == T_BT709 && + hdev->hdr_color_feature == C_BT2020) { + if (hdev->sdr_hdr_feature == 0) { + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, + NULL, NULL); + hdmitx_device.HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, SET_AVI_BT2020); + } else if (hdev->sdr_hdr_feature == 1) { + memset(DRM_DB, 0, sizeof(DRM_DB)); + hdev->HWOp.SetPacket(HDMI_PACKET_DRM, + DRM_DB, DRM_HB); + hdev->HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, SET_AVI_BT2020); + } else { + DRM_DB[0] = 0x02; /* SMPTE ST 2084 */ + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, + DRM_DB, DRM_HB); + hdmitx_device.HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, SET_AVI_BT2020); + } + return; + } + + /* SMPTE ST 2084 and (BT2020 or NON_STANDARD) */ + if (hdev->RXCap.hdr_sup_eotf_smpte_st_2084) { + if (hdev->hdr_transfer_feature == T_SMPTE_ST_2084 && + hdev->hdr_color_feature == C_BT2020) { + DRM_DB[0] = 0x02; /* SMPTE ST 2084 */ + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, + DRM_DB, DRM_HB); + hdmitx_device.HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, SET_AVI_BT2020); + return; + } else if (hdev->hdr_transfer_feature == T_SMPTE_ST_2084 && + hdev->hdr_color_feature != C_BT2020) { + DRM_DB[0] = 0x02; /* no standard SMPTE ST 2084 */ + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, + DRM_DB, DRM_HB); + hdmitx_device.HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, CLR_AVI_BT2020); + return; + } + } + + /*HLG and BT2020*/ + if (hdev->RXCap.hdr_sup_eotf_hlg) { + if (hdev->hdr_color_feature == C_BT2020 && + (hdev->hdr_transfer_feature == T_BT2020_10 || + hdev->hdr_transfer_feature == T_HLG)) { + DRM_DB[0] = 0x03;/* HLG is 0x03 */ + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, + DRM_DB, DRM_HB); + hdmitx_device.HWOp.CntlConfig(&hdmitx_device, + CONF_AVI_BT2020, SET_AVI_BT2020); + return; + } + } + + /*other case*/ + hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL); hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020, - SET_AVI_BT2020); + CLR_AVI_BT2020); + return; } static void hdmitx_set_vsif_pkt(enum eotf_type type, uint8_t tunnel_mode) @@ -1674,8 +1735,8 @@ static ssize_t show_hdr_cap(struct device *dev, pRXCap->hdr_sup_eotf_hdr); pos += snprintf(buf + pos, PAGE_SIZE, " SMPTE ST 2084: %d\n", pRXCap->hdr_sup_eotf_smpte_st_2084); - pos += snprintf(buf + pos, PAGE_SIZE, " Future EOTF: %d\n", - pRXCap->hdr_sup_eotf_future); + pos += snprintf(buf + pos, PAGE_SIZE, " Hybrif Log-Gamma: %d\n", + pRXCap->hdr_sup_eotf_hlg); pos += snprintf(buf + pos, PAGE_SIZE, "Supported SMD type1: %d\n", pRXCap->hdr_sup_SMD_type1); pos += snprintf(buf + pos, PAGE_SIZE, "Luminance Data\n"); diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 801c517e3051..27f69bc1d396 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -4287,7 +4287,7 @@ static void config_hdmi20_tx(enum hdmi_vic vic, hdmitx_set_reg_bits(HDMITX_DWC_FC_AVICONF1, 0x8, 0, 4); hdmitx_set_avi_colorimetry(para); - if (hdev->hdr_src_feature) + if (hdev->hdr_color_feature == C_BT2020) hdev->HWOp.CntlConfig(hdev, CONF_AVI_BT2020, SET_AVI_BT2020); data32 = 0; @@ -4361,19 +4361,18 @@ static void config_hdmi20_tx(enum hdmi_vic vic, /* packet scheduller configuration for AVI, GCP, AUDI, ACR. */ hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0xe, 0, 6); - /* If RX not support HDR, then disable HDR send out */ - if (!hdev->RXCap.hdr_sup_eotf_smpte_st_2084) { + /* If RX support 2084 or hlg , and the hdr_src_feature is 2020 + * then enable HDR send out + */ + if ((hdev->RXCap.hdr_sup_eotf_smpte_st_2084 || + hdev->RXCap.hdr_sup_eotf_hlg) && + (hdev->hdr_color_feature == C_BT2020)) { + hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 6, 1); + hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 1, 7, 1); + } else { + /* If RX don't support HDR, then enable HDR send out*/ hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 0, 6, 1); hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, 0, 7, 1); - } else { - /* If RX support HDR, and feature is HDR, - * then enable HDR send out - */ - if (hdev->hdr_src_feature) { - hdmitx_set_reg_bits(HDMITX_DWC_FC_DATAUTO3, 1, 6, 1); - hdmitx_set_reg_bits(HDMITX_DWC_FC_PACKET_TX_EN, - 1, 7, 1); - } } hdmitx_wr_reg(HDMITX_DWC_FC_RDRB0, 0); diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index 60ab5bdce3d7..4c6b040fad50 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -81,7 +81,7 @@ struct rx_cap { unsigned int hdr_sup_eotf_sdr:1; unsigned int hdr_sup_eotf_hdr:1; unsigned int hdr_sup_eotf_smpte_st_2084:1; - unsigned int hdr_sup_eotf_future:1; + unsigned int hdr_sup_eotf_hlg:1; unsigned int hdr_sup_SMD_type1:1; unsigned char hdr_lum_max; unsigned char hdr_lum_avg; @@ -159,6 +159,41 @@ struct frac_rate_table { u32 sync_den_dec; }; +enum hdmi_hdr_transfer { + T_UNKNOWN = 0, + T_BT709, + T_UNDEF, + T_BT601, + T_BT470M, + T_BT470BG, + T_SMPTE170M, + T_SMPTE240M, + T_LINEAR, + T_LOG100, + T_LOG316, + T_IEC61966_2_4, + T_BT1361E, + T_IEC61966_2_1, + T_BT2020_10, + T_BT2020_12, + T_SMPTE_ST_2084, + T_SMPTE_ST_28, + T_HLG, +}; + +enum hdmi_hdr_color { + C_UNKNOWN = 0, + C_BT709, + C_UNDEF, + C_BT601, + C_BT470M, + C_BT470BG, + C_SMPTE170M, + C_SMPTE240M, + C_FILM, + C_BT2020, +}; + #define EDID_MAX_BLOCK 4 #define HDMI_TMP_BUF_SIZE 1024 struct hdmitx_dev { @@ -277,7 +312,9 @@ struct hdmitx_dev { /* configure for I2S: 8ch in, 2ch out */ /* 0: default setting 1:ch0/1 2:ch2/3 3:ch4/5 4:ch6/7 */ unsigned int aud_output_ch; - unsigned int hdr_src_feature; + enum hdmi_hdr_transfer hdr_transfer_feature; + enum hdmi_hdr_color hdr_color_feature; + unsigned int sdr_hdr_feature; unsigned int flag_3dfp:1; unsigned int flag_3dtb:1; unsigned int flag_3dss:1;