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 <hang.cheng@amlogic.com>
This commit is contained in:
Hang Cheng
2018-06-22 19:47:20 +08:00
committed by Jianxin Pan
parent 67f70cd542
commit 752b2765ca
14 changed files with 116 additions and 14 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View 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, ...);

View 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,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

View 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

View 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)