hdmitx: add non-standard hdr treatment mechanism

PD#154082: hdmitx: add non-standard hdr treatment mechanism

1.add non-standard hdr
2.add hlg function

Change-Id: I8a1dbbd1583809b25ef50d6e0bfbfb6e6403b60c
Signed-off-by: Yi Zhou <yi.zhou@amlogic.com>
This commit is contained in:
Yi Zhou
2017-11-14 15:32:21 +08:00
committed by Jianxin Pan
parent ee46236755
commit f0f00eddbf
4 changed files with 143 additions and 45 deletions

View File

@@ -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;

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;