summaryrefslogtreecommitdiff
authorKaifu Hu <kaifu.hu@amlogic.com>2018-04-23 06:29:06 (GMT)
committer Xindong Xu <xindong.xu@amlogic.com>2018-05-02 02:10:00 (GMT)
commit81d4e869a840681a9caa3a6118d3de08f0e04740 (patch)
tree2b90ae34d3979c5c9cd527eb3467e0d3c1b477dd
parent29b92fb3e7d4f508d0467f3c8889321bb1218414 (diff)
downloadcommon-81d4e869a840681a9caa3a6118d3de08f0e04740.zip
common-81d4e869a840681a9caa3a6118d3de08f0e04740.tar.gz
common-81d4e869a840681a9caa3a6118d3de08f0e04740.tar.bz2
hdmitx: fix HDR compatibility
PD#161939: HDMITX: fix HDR compatibility. Fix HDR compatibility for the samsung TV of need to disable and enable hdmi phy when sdr to hdr. Change-Id: I5fa648a35ff32f1d4eb544cc12ce759d4c7bcfae Signed-off-by: Kaifu Hu <kaifu.hu@amlogic.com>
Diffstat
-rw-r--r--drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c120
-rw-r--r--drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c42
-rw-r--r--include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h3
3 files changed, 126 insertions, 39 deletions
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 66b5010..7d7fda9 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
@@ -962,22 +962,45 @@ void hdmitx_video_mute_op(unsigned int flag)
}
EXPORT_SYMBOL(hdmitx_video_mute_op);
+/*
+ * SDR/HDR uevent
+ * 1: SDR to HDR
+ * 0: HDR to SDR
+ */
+static void hdmitx_sdr_hdr_uevent(struct hdmitx_dev *hdev)
+{
+ if ((hdev->hdmi_last_hdr_mode == 0) &&
+ (hdev->hdmi_current_hdr_mode != 0)) {
+ /* SDR -> HDR*/
+ hdev->hdmi_last_hdr_mode = hdev->hdmi_current_hdr_mode;
+ extcon_set_state_sync(hdmitx_extcon_hdr, EXTCON_DISP_HDMI, 1);
+ } else if ((hdev->hdmi_last_hdr_mode != 0) &&
+ (hdev->hdmi_current_hdr_mode == 0)) {
+ /* HDR -> SDR*/
+ hdev->hdmi_last_hdr_mode = hdev->hdmi_current_hdr_mode;
+ extcon_set_state_sync(hdmitx_extcon_hdr, EXTCON_DISP_HDMI, 0);
+ }
+}
+
static void hdr_work_func(struct work_struct *work)
{
struct hdmitx_dev *hdev =
container_of(work, struct hdmitx_dev, work_hdr);
- 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);/*delay 1.5s*/
-
if (hdev->hdr_transfer_feature == T_BT709 &&
- hdev->hdr_color_feature == C_BT709)
+ hdev->hdr_color_feature == C_BT709) {
+ 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);/*delay 1.5s*/
hdev->HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
- /* switch_set_state(&hdmi_hdr, hdev->hdr_src_feature); */
+ hdev->hdmi_current_hdr_mode = 0;
+ hdmitx_sdr_hdr_uevent(hdev);
+ } else {
+ hdmitx_sdr_hdr_uevent(hdev);
+ }
}
#define GET_LOW8BIT(a) ((a) & 0xff)
@@ -1043,8 +1066,6 @@ 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);
- /*eliminate the work of work_hdr*/
- cancel_work(&hdev->work_hdr);
/* bt2020 + gamma transfer */
if (hdev->hdr_transfer_feature == T_BT709 &&
hdev->hdr_color_feature == C_BT2020) {
@@ -1069,45 +1090,65 @@ static void hdmitx_set_drm_pkt(struct master_display_info_s *data)
return;
}
+ /*must clear hdr mode*/
+ hdev->hdmi_current_hdr_mode = 0;
+
/* 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;
- }
+ hdev->hdr_color_feature == C_BT2020)
+ hdev->hdmi_current_hdr_mode = 1;
+ else if (hdev->hdr_transfer_feature == T_SMPTE_ST_2084 &&
+ hdev->hdr_color_feature != C_BT2020)
+ hdev->hdmi_current_hdr_mode = 2;
}
/*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;
- }
+ hdev->hdr_transfer_feature == T_HLG))
+ hdev->hdmi_current_hdr_mode = 3;
}
- /*other case*/
- hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
- hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020,
+ switch (hdev->hdmi_current_hdr_mode) {
+ case 1:
+ /*standard HDR*/
+ 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);
+ break;
+ case 2:
+ /*non standard*/
+ 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);
+ break;
+ case 3:
+ /*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);
+ break;
+ case 0:
+ default:
+ /*other case*/
+ hdmitx_device.HWOp.SetPacket(HDMI_PACKET_DRM, NULL, NULL);
+ hdmitx_device.HWOp.CntlConfig(&hdmitx_device, CONF_AVI_BT2020,
CLR_AVI_BT2020);
+ break;
+ }
+
+ /* if sdr/hdr mode change ,notify uevent to userspace*/
+ if (hdev->hdmi_current_hdr_mode != hdev->hdmi_last_hdr_mode)
+ schedule_work(&hdev->work_hdr);
+
}
static void hdmitx_set_vsif_pkt(enum eotf_type type,
@@ -3446,7 +3487,8 @@ static int amhdmitx_device_init(struct hdmitx_dev *hdmi_dev)
/* init para for NULL protection */
hdmitx_device.para = hdmi_get_fmt_name("invalid",
hdmitx_device.fmt_attr);
-
+ hdmitx_device.hdmi_last_hdr_mode = 0;
+ hdmitx_device.hdmi_current_hdr_mode = 0;
hdmitx_device.unplug_powerdown = 0;
hdmitx_device.vic_count = 0;
hdmitx_device.auth_process_timer = 0;
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 2f022c1..fea6667 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
@@ -2730,6 +2730,37 @@ static void hdmitx_set_fake_vic(struct hdmitx_dev *hdev)
set_vmode_clk(hdev);
}
+static void hdmitx_dump_drm_reg(void)
+{
+ unsigned int reg_val;
+ unsigned int reg_addr;
+
+ reg_addr = HDMITX_DWC_FC_AVICONF1;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+ reg_addr = HDMITX_DWC_FC_AVICONF2;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+ reg_addr = HDMITX_DWC_FC_DRM_HB01;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+ reg_addr = HDMITX_DWC_FC_DRM_HB02;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+
+ for (reg_addr = HDMITX_DWC_FC_DRM_PB00;
+ reg_addr <= HDMITX_DWC_FC_DRM_PB26; reg_addr++) {
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+ }
+ reg_addr = HDMITX_DWC_FC_DATAUTO3;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+ reg_addr = HDMITX_DWC_FC_PACKET_TX_EN;
+ reg_val = hdmitx_rd_reg(reg_addr);
+ pr_info("[0x%x]: 0x%x\n", reg_addr, reg_val);
+}
+
static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf)
{
char tmpbuf[128];
@@ -2973,6 +3004,17 @@ static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf)
default:
break;
}
+ } else if (strncmp(tmpbuf, "hdr_info", 8) == 0) {
+ pr_info("hdev->hdr_transfer_feature: 0x%x\n",
+ hdev->hdr_transfer_feature);
+ pr_info("hdev->hdr_color_feature: 0x%x\n",
+ hdev->hdr_color_feature);
+ pr_info("hdev->hdmi_current_hdr_mode: %d\n",
+ hdev->hdmi_current_hdr_mode);
+ pr_info("hdev->hdmi_last_hdr_mode: %d\n",
+ hdev->hdmi_last_hdr_mode);
+ hdmitx_dump_drm_reg();
+ return;
}
}
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 df03d15..9781a9f 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
@@ -358,6 +358,9 @@ struct hdmitx_dev {
unsigned char hdmi_audio_off_flag;
enum hdmi_hdr_transfer hdr_transfer_feature;
enum hdmi_hdr_color hdr_color_feature;
+ /* 0: sdr 1:standard HDR 2:non standard 3:HLG*/
+ unsigned int hdmi_last_hdr_mode;
+ unsigned int hdmi_current_hdr_mode;
unsigned int dv_src_feature;
unsigned int sdr_hdr_feature;
unsigned int flag_3dfp:1;