hdmirx: set rxsense sync with hpd for every port
authorHang Cheng <hang.cheng@amlogic.com>
Mon, 6 Aug 2018 12:06:08 +0000 (20:06 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 13 Aug 2018 11:04:10 +0000 (04:04 -0700)
PD#159499: hdmirx: set rxsense sync with hpd for every port

Change-Id: Ief053dc7772b12516153ef733d057a6b9a02aca2
Signed-off-by: Hang Cheng <hang.cheng@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_hw.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c

index 8863426..5faf346 100644 (file)
@@ -914,18 +914,18 @@ static long hdmirx_ioctl(struct file *file, unsigned int cmd,
        }
        case HDMI_IOC_HDCP_ON:
                hdcp_enable = 1;
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                fsm_restart();
                break;
        case HDMI_IOC_HDCP_OFF:
                hdcp_enable = 0;
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                hdmirx_hw_config();
                fsm_restart();
                break;
        case HDMI_IOC_EDID_UPDATE:
                if (rx.open_fg) {
-                       rx_set_hpd(0);
+                       rx_set_cur_hpd(0);
                        edid_update_flag = 1;
                }
                #if 0
@@ -1332,7 +1332,7 @@ static ssize_t cec_set_state(struct device *dev,
                hdmi_cec_en = 1;
        else if (val == 2) {
                hdmi_cec_en = 1;
-               rx_force_hpd_cfg(1);
+               rx_set_port_hpd(ALL_PORTS, 1);
        }
        rx_pr("cec sts = %d\n", val);
        return count;
@@ -1916,7 +1916,7 @@ static int hdmirx_suspend(struct platform_device *pdev, pm_message_t state)
        del_timer_sync(&hdevp->timer);
        /* set HPD low when cec off. */
        if (!hdmi_cec_en)
-               rx_force_hpd_cfg(0);
+               rx_set_port_hpd(ALL_PORTS, 0);
 
        if (suspend_pddq_sel == 0)
                rx_pr("don't set phy pddq down\n");
@@ -1977,7 +1977,7 @@ static void hdmirx_shutdown(struct platform_device *pdev)
        del_timer_sync(&hdevp->timer);
        /* set HPD low when cec off. */
        if (!hdmi_cec_en)
-               rx_force_hpd_cfg(0);
+               rx_set_port_hpd(ALL_PORTS, 0);
        /* phy powerdown */
        hdmirx_phy_pddq(1);
        if (hdcp22_on)
index fcac817..6114bff 100644 (file)
@@ -46,7 +46,7 @@
  *
  *
  */
-#define RX_VER2 "ver.2018/07/30a"
+#define RX_VER2 "ver.2018/08/07"
 
 /*print type*/
 #define        LOG_EN          0x01
@@ -134,6 +134,7 @@ struct hdmirx_dev_s {
 #define IOC_AUD_INFO  _BIT(1)
 #define IOC_MPEGS_INFO _BIT(2)
 #define IOC_AVI_INFO _BIT(3)
+#define ALL_PORTS ((1 << E_PORT_NUM) - 1)
 
 enum colorspace_e {
        E_COLOR_RGB,
@@ -415,9 +416,6 @@ extern void skip_frame(unsigned int cnt);
 /* hotplug */
 extern unsigned int pwr_sts;
 extern int pre_port;
-extern void rx_set_hpd(bool en);
-extern unsigned int rx_get_hdmi5v_sts(void);
-extern unsigned int rx_get_hpd_sts(void);
 extern void hotplug_wait_query(void);
 extern void rx_send_hpd_pulse(void);
 
index 314aca0..7d3af12 100644 (file)
@@ -1003,6 +1003,16 @@ static int TOP_init(void)
        /* delay cycles before n/cts update pulse */
        data32 |= 7 << 0;
        hdmirx_wr_top(TOP_ACR_CNTL2, data32);
+
+       data32 = 0;
+       /* bit4: hpd override, bit5: hpd reverse */
+       data32 |= 1 << 4;
+       if (rx.chip_id == CHIP_ID_GXTVBB)
+               data32 |= 0 << 5;
+       else
+               data32 |= 1 << 5;
+       /* pull down all the hpd */
+       hdmirx_wr_top(TOP_HPD_PWR5V, data32);
        return err;
 }
 
@@ -1160,20 +1170,65 @@ void rx_hdcp14_config(const struct hdmi_rx_hdcp *hdcp)
        hdmirx_wr_bits_dwc(DWC_HDCP_CTRL, ENCRIPTION_ENABLE, 1);
 }
 
-void rx_set_hpd(bool en)
+void rx_set_term_enable(bool enable)
 {
-       if (en) {
-               hdmirx_wr_top(TOP_HPD_PWR5V,
-                       hdmirx_rd_top(TOP_HPD_PWR5V)&(~(1<<rx.port)));
-       } else {
-               hdmirx_wr_top(TOP_HPD_PWR5V,
-                       hdmirx_rd_top(TOP_HPD_PWR5V)|(1<<rx.port));
-       }
+       hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1, PHY_TERM_OVERRIDE, enable);
+}
+
+void rx_set_term_value(unsigned char port, bool value)
+{
+       if (port < E_PORT_NUM) {
+               if (value)
+                       hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                               _BIT(port + 4), 1);
+               else
+                       hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                               _BIT(port + 4), 0);
+       } else if (port == ALL_PORTS) {
+               if (value)
+                       hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                               PHY_TERM_OV_VALUE, 0xF);
+               else
+                       hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                               PHY_TERM_OV_VALUE, 0);
+       } else
+               rx_pr("%s port num overflow\n", __func__);
+
+}
+
+int rx_set_port_hpd(uint8_t port_id, bool val)
+{
+       if (port_id < E_PORT_NUM) {
+               if (val) {
+                       hdmirx_wr_bits_top(TOP_HPD_PWR5V, _BIT(port_id), 1);
+                       rx_set_term_value(port_id, 1);
+               } else {
+                       hdmirx_wr_bits_top(TOP_HPD_PWR5V, _BIT(port_id), 0);
+                       rx_set_term_value(port_id, 0);
+               }
+       } else if (port_id == ALL_PORTS) {
+               if (val) {
+                       hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0xF);
+                       rx_set_term_value(port_id, 1);
+               } else {
+                       hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0x0);
+                       rx_set_term_value(port_id, 0);
+               }
+       } else
+               return -1;
+
        if (log_level & LOG_EN)
                rx_pr("%s, port:%d, val:%d\n", __func__,
-                                               rx.port, en);
+                                               port_id, val);
+       return 0;
 }
 
+void rx_set_cur_hpd(uint8_t val)
+{
+       rx_set_port_hpd(rx.port, val);
+}
+
+
 /*
  * rx_force_hpd_config - force config hpd level on all ports
  * @hpd_level: hpd level
@@ -1181,9 +1236,9 @@ void rx_set_hpd(bool en)
 void rx_force_hpd_cfg(uint8_t hpd_level)
 {
        if (hpd_level)
-               hdmirx_wr_top(TOP_HPD_PWR5V, 0x10);
+               hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0xf);
        else
-               hdmirx_wr_top(TOP_HPD_PWR5V, 0x1f);
+               hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0x0);
 }
 
 /*
@@ -1297,7 +1352,7 @@ void hdcp22_suspend(void)
        hdcp22_clk_en(0);
        /* note: can't pull down hpd before enter suspend */
        /* it will stop cec wake up func if EE domain still working */
-       /* rx_set_hpd(0); */
+       /* rx_set_cur_hpd(0); */
        hpd_to_esm = 0;
        hdmirx_wr_dwc(DWC_HDCP22_CONTROL,
                                0x0);
@@ -1327,7 +1382,7 @@ void hdcp22_resume(void)
        /* dont need to delay 900ms to wait sysctl start hdcp_rx22,*/
        /*sysctl is userspace it wakes up later than driver */
        /* mdelay(900); */
-       /* rx_set_hpd(1); */
+       /* rx_set_cur_hpd(1); */
        rx_pr("hdcp22 on\n");
 }
 
@@ -1589,6 +1644,8 @@ int hdmirx_audio_init(void)
 void hdmirx_phy_init(void)
 {
        unsigned int data32;
+       unsigned int term_value =
+               hdmirx_rd_top(TOP_HPD_PWR5V);
 
        data32 = 0;
        data32 |= 1 << 6;
@@ -1664,11 +1721,11 @@ void hdmirx_phy_init(void)
        hdmirx_wr_bits_phy(PHY_CDR_CTRL_CNT, CLK_RATE_BIT, 0);
        last_clk_rate = 0;
 
-       #if 0
+       #if 1
        /* enable all ports's termination*/
        data32 = 0;
        data32 |= 1 << 8;
-       data32 |= 0x0f << 4;
+       data32 |= ((term_value  & 0xF) << 4);
        hdmirx_wr_phy(PHY_MAIN_FSM_OVERRIDE1, data32);
        #endif
 
@@ -1783,12 +1840,10 @@ void hdmirx_hw_probe(void)
        hdmirx_wr_top(TOP_INTR_MASKN, 0);
        hdmirx_wr_top(TOP_SW_RESET, 0);
        clk_init();
-       hdmirx_wr_top(TOP_HPD_PWR5V, 0x1f);
-       hdmi_rx_top_edid_update();
        TOP_init();
        control_reset();
        DWC_init();
-
+       hdmi_rx_top_edid_update();
        /*hdmirx_irq_enable(FALSE);*/
        /*hdmirx_irq_hdcp22_enable(FALSE);*/
        hdcp22_clk_en(1);
@@ -2189,7 +2244,7 @@ void rx_debug_load22key(void)
        if (ret == 1) {
                rx_pr("load 2.2 key\n");
                sm_pause = 1;
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                hdcp22_on = 1;
                hdcp22_kill_esm = 1;
                while (wait_kill_done_cnt++ < 10) {
@@ -2214,7 +2269,7 @@ void rx_debug_load22key(void)
                hdmirx_hw_config();
                hpd_to_esm = 1;
                /* mdelay(900); */
-               rx_set_hpd(1);
+               rx_set_cur_hpd(1);
                sm_pause = 0;
        }
 }
index d70df95..947111a 100644 (file)
 
 #define PHY_RESISTOR_CALIBRATION_1 (0x10UL)
 #define PHY_MAIN_FSM_OVERRIDE1 (0x07UL)
+#define PHY_TERM_OVERRIDE _BIT(8)
+#define PHY_TERM_OV_VALUE MSK(4, 4)
+#define PHY_TERM_OV_PORT0 _BIT(4)
+#define PHY_TERM_OV_PORT1 _BIT(5)
+#define PHY_TERM_OV_PORT2 _BIT(6)
+#define PHY_TERM_OV_PORT3 _BIT(7)
 #define PHY_MAIN_FSM_OVERRIDE2 (0x08UL)
 
 #define PHY_MAIN_BIST_CONTROL  (0x0BUL)
@@ -1069,6 +1075,10 @@ extern unsigned char rx_get_hdcp14_sts(void);
 extern unsigned int rx_hdcp22_rd_reg_bits(unsigned int addr, unsigned int mask);
 extern int rx_get_aud_pll_err_sts(void);
 extern void rx_force_hpd_cfg(uint8_t hpd_level);
+extern int rx_set_port_hpd(uint8_t port_id, bool val);
+extern void rx_set_cur_hpd(uint8_t val);
+extern unsigned int rx_get_hdmi5v_sts(void);
+extern unsigned int rx_get_hpd_sts(void);
 #endif
 
 
index 513a05d..7329a3f 100644 (file)
@@ -1172,12 +1172,13 @@ void rx_dwc_reset(void)
 }
 
 
-uint32_t rx_get_cur_hpd_sts(void)
+int rx_get_cur_hpd_sts(void)
 {
-       uint32_t ret = rx_get_hpd_sts() & (1 << rx.port);
+       int tmp;
 
-       ret = (ret == 0) ? 1 : 0;
-       return ret;
+       tmp = hdmirx_rd_top(TOP_HPD_PWR5V) & (1 << rx.port);
+       tmp >>= rx.port;
+       return tmp;
 }
 
 bool is_tmds_valid(void)
@@ -1374,7 +1375,7 @@ void dump_unnormal_info(void)
 
 void rx_send_hpd_pulse(void)
 {
-       rx_set_hpd(0);
+       rx_set_cur_hpd(0);
        fsm_restart();
 }
 
@@ -1809,7 +1810,7 @@ void hdmirx_open_port(enum tvin_port_e port)
                }
                if (rx.state > FSM_HPD_LOW)
                        rx.state = FSM_HPD_LOW;
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                /* need reset the whole module when switch port */
                hdmirx_hw_config();
        } else {
@@ -1971,7 +1972,7 @@ void rx_main_state_machine(void)
                fsm_restart();
                break;
        case FSM_HPD_LOW:
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                set_scdc_cfg(1, 0);
                rx.state = FSM_INIT;
                break;
@@ -1994,7 +1995,7 @@ void rx_main_state_machine(void)
                clk_unstable_cnt = 0;
                esd_phy_rst_cnt = 0;
                pre_port = rx.port;
-               rx_set_hpd(1);
+               rx_set_cur_hpd(1);
                set_scdc_cfg(0, 1);
                /* rx.hdcp.hdcp_version = HDCP_VER_NONE; */
                rx.state = FSM_WAIT_CLK_STABLE;
@@ -2064,7 +2065,7 @@ void rx_main_state_machine(void)
                                else
                                        rx.err_rec_mode = ERR_REC_HPD_RST;
                        } else if (rx.err_rec_mode == ERR_REC_HPD_RST) {
-                               rx_set_hpd(0);
+                               rx_set_cur_hpd(0);
                                rx.state = FSM_HPD_HIGH;
                                rx.err_rec_mode = ERR_REC_END;
                        } else {
@@ -2146,7 +2147,7 @@ void rx_main_state_machine(void)
                                rx.err_rec_mode = ERR_REC_HPD_RST;
                                rx_set_eq_run_state(E_EQ_START);
                        } else if (rx.err_rec_mode == ERR_REC_HPD_RST) {
-                               rx_set_hpd(0);
+                               rx_set_cur_hpd(0);
                                rx.state = FSM_HPD_HIGH;
                                rx.err_rec_mode = ERR_REC_END;
                        } else
@@ -2273,7 +2274,7 @@ void rx_main_state_machine(void)
        switch (rx.state) {
        case FSM_HPD_LOW:
                /* set_scdc_cfg(1, 1); */
-               rx_set_hpd(0);
+               rx_set_cur_hpd(0);
                rx_irq_en(false);
                rx.state = FSM_INIT;
                set_scdc_cfg(1, 0);
@@ -2302,7 +2303,7 @@ void rx_main_state_machine(void)
                }
                hpd_wait_cnt = 0;
                pre_port = rx.port;
-               rx_set_hpd(1);
+               rx_set_cur_hpd(1);
                set_scdc_cfg(0, 1);
                /* some box init hdcp authentication too early
                 * and it may make the hdcp_version error
@@ -2463,7 +2464,7 @@ void rx_main_state_machine(void)
                                        if (sig_unstable_reset_hpd_cnt >=
                                                sig_unstable_reset_hpd_max) {
                                                rx.state = FSM_HPD_HIGH;
-                                               rx_set_hpd(0);
+                                               rx_set_cur_hpd(0);
                                                sig_unstable_reset_hpd_cnt = 0;
                                                rx_pr(
                                                "unstable->HDMI5V_HIGH\n");
@@ -2866,7 +2867,7 @@ int hdmirx_debug(const char *buf, int size)
                rx_pr("duk--dump duk\n");
                rx_pr("*****************\n");
        } else if (strncmp(tmpbuf, "hpd", 3) == 0)
-               rx_set_hpd(tmpbuf[3] == '0' ? 0 : 1);
+               rx_set_cur_hpd(tmpbuf[3] == '0' ? 0 : 1);
        else if (strncmp(tmpbuf, "cable_status", 12) == 0) {
                size = hdmirx_rd_top(TOP_HPD_PWR5V) >> 20;
                rx_pr("cable_status = %x\n", size);