From 752b2765ca955a9bb7d2da30b4ea7c8ecfd8da44 Mon Sep 17 00:00:00 2001 From: Hang Cheng Date: Fri, 22 Jun 2018 19:47:20 +0800 Subject: [PATCH] hdmirx: add feature of disable specific port 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 --- arch/arm64/boot/dts/amlogic/txl_t950_p341.dts | 3 + arch/arm64/boot/dts/amlogic/txl_t960_p346.dts | 3 + arch/arm64/boot/dts/amlogic/txl_t962_p320.dts | 3 + arch/arm64/boot/dts/amlogic/txl_t962_p321.dts | 3 + .../boot/dts/amlogic/txlx_t962e_r321.dts | 3 + .../dts/amlogic/txlx_t962e_r321_buildroot.dts | 3 + .../boot/dts/amlogic/txlx_t962x_r311_1g.dts | 3 + .../boot/dts/amlogic/txlx_t962x_r311_2g.dts | 3 + .../boot/dts/amlogic/txlx_t962x_r311_720p.dts | 3 + .../media/vin/tvin/hdmirx/hdmi_rx_drv.c | 33 +++++++++-- .../media/vin/tvin/hdmirx/hdmi_rx_drv.h | 4 +- .../media/vin/tvin/hdmirx/hdmi_rx_hw.c | 55 ++++++++++++++++--- .../media/vin/tvin/hdmirx/hdmi_rx_hw.h | 3 + .../media/vin/tvin/hdmirx/hdmi_rx_wrapper.c | 8 ++- 14 files changed, 116 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts b/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts index 077d56f1f075..983efb4cb577 100644 --- a/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts +++ b/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts @@ -315,6 +315,9 @@ //"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 diff --git a/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts b/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts index 92eecde62141..cd62b534f72b 100644 --- a/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts +++ b/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts @@ -316,6 +316,9 @@ //"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 diff --git a/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts b/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts index 433b8edf6873..22b7465d1a1e 100644 --- a/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts +++ b/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts @@ -307,6 +307,9 @@ //"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 diff --git a/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts b/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts index a94d2001ceb9..fb2070e073e6 100644 --- a/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts +++ b/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts @@ -306,6 +306,9 @@ //"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 diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts index 586ee974412a..5b1711781ee8 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts @@ -473,6 +473,9 @@ // "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 diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts index b64332b9048d..e11e46b95253 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts @@ -518,6 +518,9 @@ // "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 diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts index ef7afc34a824..b912ccbfa266 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -466,6 +466,9 @@ // "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 diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index 2bc6dbda3c39..e122b496f2fc 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -466,6 +466,9 @@ // "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 diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts index 0da464778829..74d823f9f925 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -465,6 +465,9 @@ // "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 diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c index a75901c6643a..6cdec147822d 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -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 diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 382754786391..862bab0323cc 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -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, ...); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index b31aa492cb12..4f8247f7cffe 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -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,19 +1260,60 @@ 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 */ @@ -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 diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index 828adf6e5df8..fe3fb38ed8a0 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -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 diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index 9f3108fbbcff..a31b419faa4d 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -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)