hdmirx: add fpll sw calculation method [1/1]

PD#SWPL-124667

Problem:
1.fpll uses fix setting method,should use sw calculation method;
2.optimize frl training work queue logic;
3.audio pll is not correct in frl mode

Solution:
1.add fpll sw calculation method
2.optimize frl training work queue logic;
3.optimize audio pll setting in frl mode

Verify:
t3x

Change-Id: Ia0d17fdd4d6d2878b7218160c602611880bdf9ce
Signed-off-by: yicheng shen <yicheng.shen@amlogic.com>
This commit is contained in:
yicheng shen
2023-05-18 19:58:31 +08:00
committed by gerrit autosubmit
parent 603a57c9f3
commit deca1747e9
6 changed files with 733 additions and 162 deletions
@@ -356,6 +356,7 @@ struct rx_var_param {
u32 avi_rcv_cnt;
bool force_pattern;
int frl_rate;
int fpll_stable_cnt;
};
struct rx_aml_phy {
@@ -677,6 +678,7 @@ struct phy_sts {
ulong timestap;
u32 err_sum;
u32 eq_data[256];
u32 aud_div_1;
};
struct clk_msr {
+31 -30
View File
@@ -905,6 +905,11 @@ void wr_reg_ana_ctl(u32 offset, u32 val)
spin_unlock_irqrestore(&reg_rw_lock, flags);
}
void wr_bits_reg_ana_ctl(u32 addr, u32 mask, u32 value)
{
wr_reg_ana_ctl(addr, rx_set_bits(rd_reg_ana_ctl(addr), mask, value));
}
/*
* rd_reg_hhi
* @offset: offset address of hhi physical addr
@@ -4523,37 +4528,29 @@ void rx_aud_pll_ctl(bool en, u8 port)
tmp = rd_reg_clk_ctl(RX_CLK_CTRL2);
tmp |= (1 << 24);
wr_reg_clk_ctl(RX_CLK_CTRL2, tmp);
//hdmirx_wr_bits_clk_ctl(RX_CLK_CTRL2, _BIT(8), 0);
wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL0_21, 0x40009540);
wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL1_21, 0x100);
tmp = 0;
tmp |= 2 << 2; /* 0:tmds_clk 1:ref_clk 2:mpll_clk */
wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL2_21, tmp);
wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL3_21,
wr_reg_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL0, 0x40009540);
/* 0:tmds_clk 1:ref_clk 2:mpll_clk */
wr_reg_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL1,
rx[port].phy.aud_div_1);
wr_reg_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL3,
rx[port].phy.aud_div);
wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL0_21, 0x6000d540);
//frl to do
//if (frl_rate) {
//if (frl_rate == 1) {
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL1_21,
//0x400);
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL2_21,
//0x0008080b);
//} else if (frl_rate == 2 || frl_rate == 3) {
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL1_21,
//0x200);
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL2_21,
//0x0008080b);
//} else {
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL1_21,
//0x0);
//wr_reg_clk_ctl(ANACTL_AUD_PLL_CNTL2_21,
//0x0008080b);
//}
//}
tmp = hdmirx_rd_amlphy_t3x(T3X_HDMIRX21PLL_CTRL2, port);
hdmirx_wr_amlphy_t3x(T3X_HDMIRX21PLL_CTRL2,
(tmp | (1 << 30)), port);
if (rx[port].var.frl_rate)
audio_setting_for_aud21(rx[port].var.frl_rate,
port);
//wr_reg_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL0, 0x6000d540);
hdmirx_wr_bits_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL0,
_BIT(14), 1);
hdmirx_wr_bits_clk_ctl(T3X_CLKCTRL_AUD21_PLL_CTRL0,
_BIT(29), 1);
if (rx[E_PORT2].var.frl_rate || rx[E_PORT3].var.frl_rate) {
tmp = hdmirx_rd_amlphy_t3x(T3X_HDMIRX21PLL_CTRL2,
port);
hdmirx_wr_amlphy_t3x(T3X_HDMIRX21PLL_CTRL2,
(tmp | (1 << 30)), port);
} else {
hdmirx_wr_amlphy_t3x(T3X_HDMIRX21PLL_CTRL2,
0, port);
}
rx_audio_pll_sw_update();
rx_pr("21 audio cfg\n");
return;
@@ -5139,7 +5136,11 @@ void hdmirx_config_video(u8 port)
rx_sw_reset_t7(2, port);
//frl_debug
if (rx_info.chip_id >= CHIP_ID_T3X && rx[port].var.frl_rate)
/* 2ppc */
hdmirx_wr_bits_cor(RX_PWD0_CLK_DIV_0, _BIT(0), 0, port);
else
/* 1ppc */
hdmirx_wr_bits_cor(RX_PWD0_CLK_DIV_0, _BIT(0), 1, port);
}
/*
+8 -1
View File
@@ -336,6 +336,8 @@
#define TOP_SHFT_PTTN_13 0x05d
#define TOP_SHFT_ANA_CNTL 0x5e
#define TOP_SHFT_ANA_STAT 0x5f
#define TOP_FPLL21_STAT0 0x90
#define TOP_FPLL21_STAT1 0x91
#define TOP_AXI_STAT_0 0x083
#define TOP_MISC_STAT0 0x084
@@ -3257,6 +3259,7 @@ void hdmirx_wr_bits_dwc(unsigned int addr,
unsigned int hdmirx_wr_phy(unsigned int add,
unsigned int data);
unsigned int hdmirx_rd_phy(unsigned int addr);
u32 hdmirx_rd_bits_clk_ctl(u32 addr, u32 mask);
unsigned int rx_get_bits(unsigned int data,
unsigned int mask);
@@ -3391,6 +3394,10 @@ u32 hdmirx_rd_bits_amlphy(u16 addr, u32 mask);
u32 hdmirx_rd_bits_amlphy_t3x(u16 addr, u32 mask, u8 port);
void wr_reg_clk_ctl(unsigned int offset, unsigned int val);
unsigned int rd_reg_clk_ctl(unsigned int offset);
void hdmirx_wr_bits_clk_ctl(u32 addr, u32 mask, u32 value);
void wr_reg_clk_ctl(u32 offset, u32 val);
u32 hdmirx_rd_bits_clk_ctl(u32 addr, u32 mask);
u32 rd_reg_clk_ctl(u32 offset);
unsigned int hdmirx_rd_amlphy(unsigned int addr);
unsigned int hdmirx_rd_amlphy_t3x(unsigned int addr, u8 port);
@@ -3450,5 +3457,5 @@ void hdmirx_frl_config(u8 port);
void rx_edid_module_reset(void);
u32 hdmirx_rd_top_common_1(u32 addr);
void hdmirx_wr_bits_top_common_1(u32 addr, u32 mask, u32 value);
void cor_init(u8 port);
#endif
File diff suppressed because it is too large Load Diff
@@ -156,7 +156,8 @@ extern u32 odn_reg_n_mul;
extern u32 ext_cnt;
extern int tr_delay0;
extern int tr_delay1;
extern int fpll_sel;
extern int fpll_chk_lvl;
/*--------------------------function declare------------------*/
/* T3X */
void aml_phy_init_t3x(u8 port);
@@ -191,7 +192,11 @@ bool is_frl_train_finished(void);
void rx_long_bist_t3x(void);
void rx_t3x_prbs(void);
void dump_aud21_param(u8 port);
void frate_monitor(u8 port);
void rx_21_fpll_cfg(int f_rate, u8 port);
bool is_fpll_err(u8 port);
void audio_setting_for_aud21(int frl_rate, u8 port);
void frate_monitor(void);
void frate_monitor1(void);
//void reset_pcs(void);
/*function declare end*/
@@ -67,6 +67,7 @@ static int clk_unstable_max;
static int clk_stable_max;
static int unnormal_wait_max = 200;
static int wait_no_sig_max = 600;
static int fpll_stable_max = 50;
u32 vrr_func_en = 1;
typedef void (*pf_callback)(int earc_port, bool st);
@@ -190,6 +191,7 @@ int clk_chg_max = 3;
// 3. for hdcp1.4 cts. need to wait for hdcp start.
// waiting time cannot be reduced 1S
static int hdcp_none_wait_max = 80;
int fpll_chk_cnt;
void hdmirx_phy_var_init(void)
{
@@ -3172,6 +3174,10 @@ static void signal_status_init(u8 port)
latency_info.allm_mode = 0;
latency_info.it_content = 0;
latency_info.cn_type = 0;
if (rx_info.chip_id >= CHIP_ID_T3X && port >= E_PORT2) {
rx_set_frl_train_sts(E_FRL_TRAIN_START);
rx[port].var.frl_rate = FRL_OFF;
}
#ifdef CONFIG_AMLOGIC_HDMITX
if (rx_info.chip_id == CHIP_ID_T7)
hdmitx_update_latency_info(&latency_info);
@@ -3292,12 +3298,15 @@ void rx_dwc_reset(u8 port)
if (port >= E_PORT2) {
if (rx[port].var.frl_rate) {
hdmirx_wr_cor(DPLL_CFG6_DPLL_IVCRX, 0x0, port);
/* for 2.1 hdcp */
hdmirx_wr_cor(CP2PA_AESCTL0_HDCP2X_IVCRX, 0xf0, port);
hdmirx_wr_bits_top(TOP_CLK_CNTL, _BIT(14), 1, port);
} else {
hdmirx_wr_cor(DPLL_CFG6_DPLL_IVCRX, 0x10, port);
hdmirx_wr_cor(RX_H21_CTRL_PWD_IVCRX, 0, port);
hdmirx_wr_bits_top(TOP_CLK_CNTL, _BIT(14), 0, port);
hdmirx_wr_bits_cor(RX_VP_INPUT_FORMAT_LO, _BIT(0), 1, port);
hdmirx_wr_cor(CP2PA_AESCTL0_HDCP2X_IVCRX, 0x0, port);
}
}
}
@@ -3708,6 +3717,8 @@ void rx_get_global_variable(const char *buf)
pr_var(force_clk_stable, i++);
pr_var(audio_debug, i++);
pr_var(port_debug_en, i++);
pr_var(fpll_sel, i++);
pr_var(fpll_chk_lvl, i++);
}
bool str_cmp(unsigned char *buff, unsigned char *str)
@@ -4223,6 +4234,12 @@ int rx_set_global_variable(const char *buf, int size)
if (set_pr_var(tmpbuf, var_to_str(rx_info.aml_phy_21.dfe_hold),
&rx_info.aml_phy_21.dfe_hold, value))
return pr_var(rx_info.aml_phy_21.dfe_hold, index);
if (set_pr_var(tmpbuf, var_to_str(fpll_sel),
&fpll_sel, value))
return pr_var(fpll_sel, index);
if (set_pr_var(tmpbuf, var_to_str(fpll_chk_lvl),
&fpll_chk_lvl, value))
return pr_var(fpll_chk_lvl, index);
return 0;
}
@@ -5937,7 +5954,7 @@ void rx_port2_main_state_machine(void)
int one_frame_cnt;
u8 port = E_PORT2;
frate_monitor(port);
frate_monitor();
if ((dbg_port - 1 != port) &&
dbg_port)
return;
@@ -5983,6 +6000,7 @@ void rx_port2_main_state_machine(void)
break;
case FSM_FRL_TRN:
rx_frl_train();
rx[port].var.fpll_stable_cnt = 0;
if (hdmirx_get_frl_rate(port) == FRL_OFF)
rx[port].state = FSM_WAIT_CLK_STABLE;
else
@@ -5991,6 +6009,10 @@ void rx_port2_main_state_machine(void)
case FSM_WAIT_FRL_TRN_DONE:
if (!is_frl_train_finished())
break;
if (is_fpll_err(port)) {
if (rx[port].var.fpll_stable_cnt++ < fpll_stable_max)
break;
}
rx[port].state = FSM_PCS_RESET;
rx[port].var.clk_stable_cnt = 0;
break;
@@ -6061,6 +6083,7 @@ void rx_port2_main_state_machine(void)
rx[port].var.pll_lock_cnt = 0;
rx[port].var.pll_unlock_cnt = 0;
rx[port].var.clk_chg_cnt = 0;
rx[port].var.fpll_stable_cnt = 0;
break;
case FSM_SIG_UNSTABLE:
if (!rx[port].cableclk_stb_flg) {
@@ -6411,6 +6434,7 @@ void rx_port3_main_state_machine(void)
int one_frame_cnt;
u8 port = E_PORT3;
frate_monitor1();
if ((dbg_port - 1 != port) &&
dbg_port)
return;
@@ -6457,6 +6481,7 @@ void rx_port3_main_state_machine(void)
break;
case FSM_FRL_TRN:
rx_frl_train();
rx[port].var.fpll_stable_cnt = 0;
if (hdmirx_get_frl_rate(port) == FRL_OFF)
rx[port].state = FSM_WAIT_CLK_STABLE;
else
@@ -6465,6 +6490,10 @@ void rx_port3_main_state_machine(void)
case FSM_WAIT_FRL_TRN_DONE:
if (!is_frl_train_finished())
break;
if (is_fpll_err(port)) {
if (rx[port].var.fpll_stable_cnt++ < fpll_stable_max)
break;
}
rx[port].state = FSM_PCS_RESET;
rx[port].var.clk_stable_cnt = 0;
break;
@@ -6535,6 +6564,7 @@ void rx_port3_main_state_machine(void)
rx[port].var.pll_lock_cnt = 0;
rx[port].var.pll_unlock_cnt = 0;
rx[port].var.clk_chg_cnt = 0;
rx[port].var.fpll_stable_cnt = 0;
break;
case FSM_SIG_UNSTABLE:
if (!rx[port].cableclk_stb_flg) {
@@ -7039,7 +7069,7 @@ static void dump_clk_status(u8 port)
rx[port].clk.mpll_clk);
}
static void dump_video_status(u8 port)
void dump_video_status(u8 port)
{
enum edid_ver_e edid_slt = (edid_select >> (4 * port)) & 0xF;
enum edid_ver_e edid_ver =
@@ -7433,10 +7463,12 @@ int hdmirx_debug(const char *buf, int size)
hdmi_tx_rx_frl_training_main(port);
} else if (strncmp(tmpbuf, "prbs", 4) == 0) {
rx_long_bist_t3x();
} else if (strncmp(tmpbuf, "lbist", 5) == 0) {
} else if (strncmp(tmpbuf, "l_bist", 6) == 0) {
rx_long_bist_t3x();
} else if (strncmp(tmpbuf, "aud21", 5) == 0) {
dump_aud21_param(E_PORT2);
} else if (strncmp(tmpbuf, "fpll", 4) == 0) {
rx_21_fpll_cfg(rx[port].var.frl_rate, port);
}
return 0;
}