hdmirx: set rxsense sync with hpd for every port

PD#159499: hdmirx: set rxsense sync with hpd for every port

Change-Id: Ief053dc7772b12516153ef733d057a6b9a02aca2
Signed-off-by: Hang Cheng <hang.cheng@amlogic.com>
This commit is contained in:
Hang Cheng
2018-08-06 20:06:08 +08:00
committed by Jianxin Pan
parent 2a2a5305a7
commit 923bf48f16
5 changed files with 108 additions and 44 deletions

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

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

View 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;
}
}

View File

@@ -72,6 +72,12 @@
#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

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