hdmirx: add feature of disable specific port
authorHang Cheng <hang.cheng@amlogic.com>
Fri, 22 Jun 2018 11:47:20 +0000 (19:47 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Tue, 21 Aug 2018 07:27:33 +0000 (00:27 -0700)
PD#162498: hdmirx: add feature of disable specific port

1.disable termination and hpd of specific port to avoid
interference to adjacent non-hdmi source
2.use dts to control this feature, disable feature by default
3.side effect: cec function of disabled port will not work

Change-Id: Ie52b187185277ee4e900b4de6db1da0da65bb1b9
Signed-off-by: Hang Cheng <hang.cheng@amlogic.com>
14 files changed:
arch/arm64/boot/dts/amlogic/txl_t950_p341.dts
arch/arm64/boot/dts/amlogic/txl_t960_p346.dts
arch/arm64/boot/dts/amlogic/txl_t962_p320.dts
arch/arm64/boot/dts/amlogic/txl_t962_p321.dts
arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
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 077d56f..983efb4 100644 (file)
                        //"clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xc0800000 0x0 0xa00000
                        0x0 0xC883C000 0x0 0x2000
                        0x0 0xd0076000 0x0 0x2000
index 92eecde..cd62b53 100644 (file)
                        //"clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xc0800000 0x0 0xa00000
                        0x0 0xC883C000 0x0 0x2000
                        0x0 0xd0076000 0x0 0x2000
index 433b8ed..22b7465 100644 (file)
                        //"clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xc0800000 0x0 0xa00000
                        0x0 0xC883C000 0x0 0x2000
                        0x0 0xd0076000 0x0 0x2000
index a94d200..fb2070e 100644 (file)
                        //"clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xc0800000 0x0 0xa00000
                        0x0 0xC883C000 0x0 0x2000
                        0x0 0xd0076000 0x0 0x2000
index 586ee97..5b17117 100644 (file)
                //              "clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xffd26000 0x0 0xa00000
                        0x0 0xff63C000 0x0 0x2000
                        0x0 0xffe0d000 0x0 0x2000
index b64332b..e11e46b 100644 (file)
                //              "clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xffd26000 0x0 0xa00000
                        0x0 0xff63C000 0x0 0x2000
                        0x0 0xffe0d000 0x0 0x2000
index ef7afc3..b912ccb 100644 (file)
                //              "clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xffd26000 0x0 0xa00000
                        0x0 0xff63C000 0x0 0x2000
                        0x0 0xffe0d000 0x0 0x2000
index 2bc6dbd..e122b49 100644 (file)
                //              "clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xffd26000 0x0 0xa00000
                        0x0 0xff63C000 0x0 0x2000
                        0x0 0xffe0d000 0x0 0x2000
index 0da4647..74d823f 100644 (file)
                //              "clk_aud_out";
                hdmirx_id = <0>;
                en_4k_2_2k = <0>;
+               hpd_low_cec_off = <1>;
+               /* bit4: enable feature, bit3~0: port number */
+               disable_port = <0x0>;
                reg = <0x0 0xffd26000 0x0 0xa00000
                        0x0 0xff63C000 0x0 0x2000
                        0x0 0xffe0d000 0x0 0x2000
index a75901c..6cdec14 100644 (file)
@@ -133,6 +133,10 @@ int vdin_drop_frame_cnt = 1;
  * other value: keep previous logic
  */
 int suspend_pddq_sel = 1;
+/* as cvt required, set hpd low if cec off when boot */
+static int hpd_low_cec_off = 1;
+int disable_port_num;
+int disable_port_en;
 
 struct reg_map reg_maps[MAP_ADDR_MODULE_NUM];
 
@@ -1335,14 +1339,20 @@ static ssize_t cec_set_state(struct device *dev,
        cnt = kstrtoint(buf, 0, &val);
        if (cnt < 0 || val > 0xff)
                return -EINVAL;
-       if (val == 0)
+       if (val == 0) {
                hdmi_cec_en = 0;
-       else if (val == 1)
+               /* fix source can't get edid if cec off */
+               if (rx.boot_flag) {
+                       if (hpd_low_cec_off == 0)
+                               rx_force_hpd_rxsense_cfg(1);
+               }
+       } else if (val == 1)
                hdmi_cec_en = 1;
        else if (val == 2) {
                hdmi_cec_en = 1;
-               rx_set_port_hpd(ALL_PORTS, 1);
+               rx_force_hpd_rxsense_cfg(1);
        }
+       rx.boot_flag = false;
        rx_pr("cec sts = %d\n", val);
        return count;
 }
@@ -1542,6 +1552,7 @@ static int hdmirx_probe(struct platform_device *pdev)
        struct clk *tmds_clk_fs;
        int clk_rate;
        const struct of_device_id *of_id;
+       int disable_port;
 
        log_init(DEF_LOG_BUF_SIZE);
        pEdid_buffer = (unsigned char *) pdev->dev.platform_data;
@@ -1805,6 +1816,20 @@ static int hdmirx_probe(struct platform_device *pdev)
        if (ret)
                en_4k_timing = 1;
 
+       ret = of_property_read_u32(pdev->dev.of_node,
+                               "hpd_low_cec_off", &hpd_low_cec_off);
+       if (ret)
+               hpd_low_cec_off = 1;
+       ret = of_property_read_u32(pdev->dev.of_node,
+                               "disable_port", &disable_port);
+       if (ret) {
+               /* don't disable port if dts not indicate */
+               disable_port_en = 0;
+       } else {
+               /* bit4: enable feature, bit3~0: port_num */
+               disable_port_en = (disable_port >> 4) & 0x1;
+               disable_port_num = disable_port & 0xF;
+       }
        hdmirx_hw_probe();
        hdmirx_switch_pinmux(&(pdev->dev));
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -1966,13 +1991,13 @@ static int hdmirx_resume(struct platform_device *pdev)
                        mdelay(50);
                }
        }
+       rx.boot_flag = true;
        hdmirx_phy_init();
        add_timer(&hdevp->timer);
        if (hdcp22_on)
                hdcp22_resume();
        rx_pr("hdmirx: resume\n");
        pre_port = 0xff;
-       rx.boot_flag = true;
        return 0;
 }
 #endif
index 3827547..862bab0 100644 (file)
@@ -46,7 +46,7 @@
  *
  *
  */
-#define RX_VER2 "ver.2018/8/13"
+#define RX_VER2 "ver.2018/8/20"
 
 /*print type*/
 #define        LOG_EN          0x01
@@ -442,6 +442,8 @@ extern bool hdcp_enable;
 extern int log_level;
 extern int sm_pause;
 extern int suspend_pddq_sel;
+extern int disable_port_num;
+extern int disable_port_en;
 extern int rx_set_global_variable(const char *buf, int size);
 extern void rx_get_global_variable(const char *buf);
 extern int rx_pr(const char *fmt, ...);
index b31aa49..4f8247f 100644 (file)
@@ -56,7 +56,7 @@
 static DEFINE_SPINLOCK(reg_rw_lock);
 /* should enable fast switching, since some devices in non-current port */
 /* will suspend because of RxSense = 0, such as xiaomi-mtk box */
-static bool phy_fast_switching = true;
+static bool phy_fast_switching;
 static bool phy_fsm_enhancement = true;
 unsigned int last_clk_rate;
 
@@ -1260,20 +1260,61 @@ 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
  */
 void rx_force_hpd_cfg(uint8_t hpd_level)
 {
-       if (hpd_level)
-               hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0xf);
-       else
+       unsigned int hpd_value;
+
+       if (hpd_level) {
+               if (disable_port_en)
+                       hpd_value = (~(1 << disable_port_num)) & 0xF;
+               else
+                       hpd_value = 0xF;
+
+               hdmirx_wr_bits_top(TOP_HPD_PWR5V,
+                       MSK(4, 0), hpd_value);
+       } else
                hdmirx_wr_bits_top(TOP_HPD_PWR5V, MSK(4, 0), 0x0);
 }
 
 /*
+ * rx_force_rxsense_cfg - force config rxsense level on all ports
+ * @level: rxsense level
+ */
+void rx_force_rxsense_cfg(uint8_t level)
+{
+       unsigned int term_ovr_value;
+
+       if (level) {
+               if (disable_port_en)
+                       term_ovr_value = (~(1 << disable_port_num)) & 0xF;
+               else
+                       term_ovr_value = 0xF;
+
+               hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                       PHY_TERM_OV_VALUE, term_ovr_value);
+       } else
+               hdmirx_wr_bits_phy(PHY_MAIN_FSM_OVERRIDE1,
+                       PHY_TERM_OV_VALUE, 0x0);
+}
+
+/*
+ * rx_force_hpd_rxsense_cfg - force config
+ * hpd & rxsense level on all ports
+ * @level: hpd & rxsense level
+ */
+void rx_force_hpd_rxsense_cfg(uint8_t level)
+{
+       rx_force_hpd_cfg(level);
+       rx_force_rxsense_cfg(level);
+       if (log_level & LOG_EN)
+               rx_pr("hpd & rxsense force val:%d\n", level);
+}
+
+/*
  * control_reset - hdmirx controller reset
  */
 void control_reset(void)
@@ -1754,10 +1795,10 @@ void hdmirx_phy_init(void)
        last_clk_rate = 0;
 
        #if 1
-       /* enable all ports's termination*/
+       /* enable all ports's termination */
        data32 = 0;
        data32 |= 1 << 8;
-       data32 |= ((term_value  & 0xF) << 4);
+       data32 |= ((term_value & 0xF) << 4);
        hdmirx_wr_phy(PHY_MAIN_FSM_OVERRIDE1, data32);
        #endif
 
index 828adf6..fe3fb38 100644 (file)
@@ -1098,6 +1098,9 @@ extern unsigned int rx_get_hdmi5v_sts(void);
 extern unsigned int rx_get_hpd_sts(void);
 
 extern void cec_hw_reset(void);
+extern void rx_force_hpd_cfg(uint8_t hpd_level);
+extern void rx_force_rxsense_cfg(uint8_t level);
+extern void rx_force_hpd_rxsense_cfg(uint8_t level);
 #endif
 
 
index 9f3108f..a31b419 100644 (file)
@@ -1177,7 +1177,6 @@ void rx_dwc_reset(void)
        hdmirx_packet_fifo_rst();
 }
 
-
 int rx_get_cur_hpd_sts(void)
 {
        int tmp;
@@ -1803,7 +1802,9 @@ void hdmirx_open_port(enum tvin_port_e port)
                rx.hdcp.repeat = 0;
 
        if ((pre_port != rx.port) ||
-               (rx_get_cur_hpd_sts()) == 0) {
+               (rx_get_cur_hpd_sts() == 0) ||
+               /* when open specific port, force to enable it */
+               (disable_port_en && (rx.port == disable_port_num))) {
                if (hdcp22_on) {
                        esm_set_stable(false);
                        esm_set_reset(true);
@@ -1836,6 +1837,9 @@ void hdmirx_close_port(void)
        /* if (sm_pause) */
        /*      return; */
        /* External_Mute(1); */
+       /* when exit hdmi, disable termination & hpd of specific port */
+       if (disable_port_en)
+               rx_set_port_hpd(disable_port_num, 0);
 }
 
 void rx_nosig_monitor(void)