hdmirx: add ddc idle detection before edid filling
authorLei Yang <lei.yang@amlogic.com>
Wed, 8 Aug 2018 03:11:18 +0000 (11:11 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 22 Aug 2018 11:22:31 +0000 (04:22 -0700)
PD#171215: hdmirx: add ddc idle detection before edid filling

1. add ddc idle detection
2. increase hpd low wait time to 350ms

Change-Id: I59e3bc52af09b41b8567a93d595c2b52233f170a
Signed-off-by: Lei Yang <lei.yang@amlogic.com>
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c

index 6cdec14..6096998 100644 (file)
@@ -925,6 +925,7 @@ static long hdmirx_ioctl(struct file *file, unsigned int cmd,
                hdcp_enable = 0;
                rx_set_cur_hpd(0);
                hdmirx_hw_config();
+               hdmi_rx_top_edid_update();
                fsm_restart();
                break;
        case HDMI_IOC_EDID_UPDATE:
index 862bab0..93db9db 100644 (file)
@@ -34,7 +34,7 @@
 #include "hdmi_rx_edid.h"
 
 
-#define RX_VER0 "ver.2018-08-20"
+#define RX_VER0 "ver.2018-08-22"
 /*
  *
  *
index 545ca57..866642c 100644 (file)
@@ -881,6 +881,44 @@ unsigned int rx_edid_cal_phy_addr(
        return flag;
 }
 
+bool is_ddc_idle(unsigned char port_id)
+{
+       unsigned int sts;
+       unsigned int ddc_sts;
+       unsigned int ddc_offset;
+
+       switch (port_id) {
+       case 0:
+               sts = hdmirx_rd_top(TOP_EDID_GEN_STAT);
+               break;
+       case 1:
+               sts = hdmirx_rd_top(TOP_EDID_GEN_STAT_B);
+               break;
+       case 2:
+               sts = hdmirx_rd_top(TOP_EDID_GEN_STAT_C);
+               break;
+       case 3:
+               sts = hdmirx_rd_top(TOP_EDID_GEN_STAT_D);
+               break;
+       default:
+               sts = 0;
+               break;
+       }
+
+       ddc_sts = (sts >> 20) & 0x1f;
+       ddc_offset = sts & 0xff;
+
+       if ((ddc_sts == 0) &&
+               ((ddc_offset == 0xff) ||
+               (ddc_offset == 0)))
+               return true;
+
+       if (log_level & ERR_LOG)
+               rx_pr("ddc busy\n");
+
+       return false;
+}
+
 void rx_edid_fill_to_register(
                                                u_char *pedid,
                                                u_int brepeat,
index 5b533fd..134f700 100644 (file)
@@ -626,4 +626,5 @@ void rx_modify_edid(unsigned char *buffer,
                                int len, unsigned char *addition);
 void rx_edid_update_audio_info(unsigned char *p_edid,
                                                unsigned int len);
+extern bool is_ddc_idle(unsigned char port_id);
 #endif
index 4f8247f..e4ccab4 100644 (file)
@@ -1891,7 +1891,7 @@ void hdmirx_hw_config(void)
 {
        rx_pr("%s port:%d\n", __func__, rx.port);
        control_reset();
-       hdmi_rx_top_edid_update();
+       /* hdmi_rx_top_edid_update(); */
        rx_hdcp_init();
        hdmirx_audio_init();
        packet_init();
@@ -2342,6 +2342,7 @@ void rx_debug_load22key(void)
                        EXTCON_DISP_HDMI, 1);
                mdelay(100);
                hdmirx_hw_config();
+               hdmi_rx_top_edid_update();
                hpd_to_esm = 1;
                /* mdelay(900); */
                rx_set_cur_hpd(1);
@@ -2353,6 +2354,7 @@ void rx_debug_loadkey(void)
 {
        rx_pr("load hdcp key\n");
        hdmirx_hw_config();
+       hdmi_rx_top_edid_update();
        pre_port = 0xfe;
 }
 
index a31b419..c4c07d8 100644 (file)
@@ -61,8 +61,8 @@ static bool clk_debug;
 
 static int hpd_wait_cnt;
 /* increase time of hpd low, to avoid some source like */
-/* MTK box i2c communicate error */
-static int hpd_wait_max = 20;
+/* MTK box/KaiboerH9 i2c communicate error */
+static int hpd_wait_max = 40;
 
 static int sig_unstable_cnt;
 static int sig_unstable_max = 80;
@@ -194,9 +194,6 @@ static bool hdcp22_stop_auth_enable;
 static bool hdcp22_esm_reset2_enable;
 int sm_pause;
 int pre_port = 0xff;
-/*uint32_t irq_flag;*/
-/*for some device pll unlock too long,send a hpd reset*/
-bool hdmi5v_lost_flag;
 static int hdcp_none_wait_max = 100;
 /* for no signal after esd test issue, phy
  * does't work, cable clock or PLL can't
@@ -1319,6 +1316,7 @@ void fsm_restart(void)
                esm_set_stable(false);
        }
        hdmirx_hw_config();
+       hdmi_rx_top_edid_update();
        set_scdc_cfg(1, 0);
        vic_check_en = true;
        dvi_check_en = true;
@@ -1786,6 +1784,16 @@ void skip_frame(unsigned int cnt)
        rx_pr("rx.skip = %d", rx.skip);
 }
 
+void wait_ddc_idle(void)
+{
+       unsigned char i;
+       /* add delays to avoid the edid communication fail */
+       for (i = 0; i <= 10; i++) {
+               if (!is_ddc_idle(rx.port))
+                       msleep(20);
+       }
+}
+
 /***********************
  * hdmirx_open_port
  ***********************/
@@ -1820,6 +1828,8 @@ void hdmirx_open_port(enum tvin_port_e port)
                rx_set_cur_hpd(0);
                /* need reset the whole module when switch port */
                hdmirx_hw_config();
+               wait_ddc_idle();
+               hdmi_rx_top_edid_update();
        } else {
                if (rx.state >= FSM_SIG_STABLE)
                        rx.state = FSM_SIG_STABLE;
@@ -1993,13 +2003,8 @@ void rx_main_state_machine(void)
        case FSM_HPD_HIGH:
                hpd_wait_cnt++;
                if (rx_get_cur_hpd_sts() == 0) {
-                       if (edid_update_flag) {
-                               if (hpd_wait_cnt <= hpd_wait_max*10)
-                                       break;
-                       } else {
-                               if (hpd_wait_cnt <= hpd_wait_max)
-                                       break;
-                       }
+                       if (hpd_wait_cnt <= hpd_wait_max)
+                               break;
                }
                hpd_wait_cnt = 0;
                clk_unstable_cnt = 0;
@@ -2113,6 +2118,7 @@ void rx_main_state_machine(void)
                                if (fmt_vic_abnormal() &&
                                        (vic_check_en == true)) {
                                        hdmirx_hw_config();
+                                       hdmi_rx_top_edid_update();
                                        rx.state = FSM_HPD_LOW;
                                        vic_check_en = false;
                                        break;
@@ -2430,6 +2436,7 @@ void rx_main_state_machine(void)
                                if (fmt_vic_abnormal() &&
                                        (vic_check_en == true)) {
                                        hdmirx_hw_config();
+                                       hdmi_rx_top_edid_update();
                                        rx.state = FSM_HPD_LOW;
                                        vic_check_en = false;
                                        break;
@@ -2888,6 +2895,7 @@ int hdmirx_debug(const char *buf, int size)
                if (tmpbuf[5] == '0') {
                        rx_pr(" hdmirx hw config\n");
                        hdmirx_hw_config();
+                       hdmi_rx_top_edid_update();
                } else if (tmpbuf[5] == '1') {
                        rx_pr(" hdmirx phy init 8bit\n");
                        hdmirx_phy_init();