From f4e33f3a319ac83a54874bdde010b72b0c863457 Mon Sep 17 00:00:00 2001 From: "Zhengrong.Zhu" Date: Mon, 6 Jan 2020 15:56:56 +0800 Subject: [PATCH] hdmitx: Connect with Hisense HZ55A65 TV, It will lost resolution [1/1] PD#SWPL-19410 Problem: Connect with Hisense HZ55A65 TV, It will lost resolution Solution: Modify the code using read edid Verify: verify on the board of U212 Change-Id: Iaa2692508db6bcde07578e027e23bbf52399b25c Signed-off-by: Zhengrong Zhu --- .../vout/hdmitx/hdmi_tx_20/hdmi_tx_main.c | 26 +++++++++++++++++++ .../vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c | 8 ++++++ .../media/vout/hdmi_tx/hdmi_tx_module.h | 1 + 3 files changed, 35 insertions(+) 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 407621ea958e..897fe41bbf66 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 @@ -5031,6 +5031,21 @@ static int hdmitx_notify_callback_a(struct notifier_block *block, return 0; } +unsigned int hdmitx_check_edid_all_zeros(unsigned char *buf) +{ + unsigned int i = 0, j = 0; + unsigned int chksum = 0; + + for (j = 0; j < EDID_MAX_BLOCK; j++) { + chksum = 0; + for (i = 0; i < 128; i++) + chksum += buf[i + j * 128]; + if (chksum != 0) + return 0; + } + return 1; +} + static void hdmitx_get_edid(struct hdmitx_dev *hdev) { mutex_lock(&getedid_mutex); @@ -5040,13 +5055,24 @@ static void hdmitx_get_edid(struct hdmitx_dev *hdev) /* start reading edid frist time */ hdev->hwop.cntlddc(hdev, DDC_EDID_READ_DATA, 0); hdev->hwop.cntlddc(hdev, DDC_EDID_GET_DATA, 0); + if (hdmitx_check_edid_all_zeros(hdev->EDID_buf)) { + hdev->hwop.cntlddc(hdev, DDC_GLITCH_FILTER_RESET, 0); + hdev->hwop.cntlddc(hdev, DDC_EDID_READ_DATA, 0); + hdev->hwop.cntlddc(hdev, DDC_EDID_GET_DATA, 0); + } /* If EDID is not correct at first time, then retry */ if (!check_dvi_hdmi_edid_valid(hdev->EDID_buf)) { msleep(100); /* start reading edid second time */ hdev->hwop.cntlddc(hdev, DDC_EDID_READ_DATA, 0); hdev->hwop.cntlddc(hdev, DDC_EDID_GET_DATA, 1); + if (hdmitx_check_edid_all_zeros(hdev->EDID_buf1)) { + hdev->hwop.cntlddc(hdev, DDC_GLITCH_FILTER_RESET, 0); + hdev->hwop.cntlddc(hdev, DDC_EDID_READ_DATA, 0); + hdev->hwop.cntlddc(hdev, DDC_EDID_GET_DATA, 1); + } } + hdmitx_edid_clear(hdev); hdmitx_edid_parse(hdev); hdmitx_edid_buf_compare_print(hdev); 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 83f0a3fa7f5b..5b83233a963c 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 @@ -4959,6 +4959,14 @@ static int hdmitx_cntl_ddc(struct hdmitx_dev *hdev, unsigned int cmd, else hdmitx_getediddata(hdev->EDID_buf1, hdev->tmp_edid_buf); break; + case DDC_GLITCH_FILTER_RESET: + hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 1, 6, 1); + /*keep reseting DDC for some time*/ + usleep_range(1000, 2000); + hdmitx_set_reg_bits(HDMITX_TOP_SW_RESET, 0, 6, 1); + /*wait recover for reseting DDC*/ + usleep_range(1000, 2000); + break; case DDC_PIN_MUX_OP: if (argv == PIN_MUX) hdmitx_ddc_hw_op(DDC_MUX_DDC); 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 b1b5387a4599..9672f961636d 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 @@ -521,6 +521,7 @@ struct hdmitx_dev { #define DDC_HDCP_MUX_INIT (CMD_DDC_OFFSET + 0x0e) #define DDC_HDCP_14_LSTORE (CMD_DDC_OFFSET + 0x0f) #define DDC_HDCP_22_LSTORE (CMD_DDC_OFFSET + 0x10) +#define DDC_GLITCH_FILTER_RESET (CMD_DDC_OFFSET + 0x11) #define DDC_SCDC_DIV40_SCRAMB (CMD_DDC_OFFSET + 0x20) #define DDC_HDCP14_GET_BCAPS_RP (CMD_DDC_OFFSET + 0x30) #define DDC_HDCP14_GET_TOPO_INFO (CMD_DDC_OFFSET + 0x31)