hdmirx: add new EQ setting [1/1]

PD#SWPL-4261

Problem:
some devices have compatibility issues.

Solution:
1.update phy setting;
2.optimize some SW logic;
3.set eess_oess to auto mode;
4.fix black screen(DE fixed error,related with rx phy) issue.

Verify:
TL1 TXLX android P

Change-Id: I842a4782b3e513fa1e483feca98ce05b128d79fc
Signed-off-by: yicheng shen <yicheng.shen@amlogic.com>
Signed-off-by: Lei Yang <lei.yang@amlogic.com>
This commit is contained in:
yicheng shen
2019-01-08 02:38:22 -05:00
committed by Jianxin Pan
parent f613d4bc2b
commit 24fdceff3d
6 changed files with 247 additions and 149 deletions

View File

@@ -34,7 +34,7 @@
#include "hdmi_rx_edid.h"
#define RX_VER0 "ver.2018-12-19"
#define RX_VER0 "ver.2019-01-08"
/*
*
*

View File

@@ -487,13 +487,6 @@ int rx_eq_algorithm(void)
static uint8_t pre_eq_freq = 0xff;
uint8_t pll_rate = hdmirx_rd_phy(PHY_MAINFSM_STATUS1) >> 9 & 3;
/* for tl1 no SW eq */
if (rx.chip_id == CHIP_ID_TL1) {
hdmirx_phy_init();
eq_sts = E_EQ_FINISH;
return 1;
}
if (is_6g_mode())
pll_rate = E_EQ_6G;

View File

@@ -41,6 +41,7 @@
#include <linux/highmem.h>
/* Local include */
#include "hdmi_rx_eq.h"
#include "hdmi_rx_repeater.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_hw.h"
@@ -93,7 +94,7 @@ int aud_ch_map;
int ignore_sscp_charerr = 1;
int ignore_sscp_tmds = 1;
int find_best_eq;
int eq_try_cnt = 50;
int eq_try_cnt = 20;
/*------------------------variable define end------------------------------*/
static int check_regmap_flag(unsigned int addr)
@@ -1388,11 +1389,24 @@ static int DWC_init(void)
data32 |= (HYST_DVI_TO_HDMI << 8);
data32 |= (0 << 6);
data32 |= (0 << 4);
/* Force OESS mode to fix Google Chromecast box black screen issue */
data32 |= (1 << 2);
/* EESS_OESS */
/* 0: new auto mode,check on HDMI mode or 1.1 features en */
/* 1: force OESS */
/* 2: force EESS */
/* 3: auto mode,check CTL[3:0]=d9/d8 during WOO */
data32 |= (0 << 2);
data32 |= (0 << 0);
hdmirx_wr_dwc(DWC_HDMI_MODE_RECOVER, data32);
data32 = hdmirx_rd_dwc(DWC_HDCP_CTRL);
/* 0: Original behaviour */
/* 1: Balance path delay between non-HDCP and HDCP */
data32 |= 1 << 27; /* none & hdcp */
/* 0: Original behaviour */
/* 1: Balance path delay between HDCP14 and HDCP22. */
data32 |= 1 << 26; /* 1.4 & 2.2 */
hdmirx_wr_dwc(DWC_HDCP_CTRL, data32);
return err;
}
@@ -2174,6 +2188,24 @@ void snps_phyg3_init(void)
}
void rx_run_eq(void)
{
if (rx.chip_id < CHIP_ID_TL1)
rx_eq_algorithm();
else
hdmirx_phy_init();
}
bool rx_eq_done(void)
{
bool ret = true;
if (rx.chip_id < CHIP_ID_TL1) {
if (rx_get_eq_run_state() == E_EQ_START)
ret = false;
}
return ret;
}
/*
* hdmirx_phy_init - hdmirx phy initialization
*/
@@ -2194,16 +2226,26 @@ void hdmirx_phy_init(void)
*/
bool rx_clkrate_monitor(void)
{
uint32_t clk_rate;
uint32_t clk_rate, phy_band, pll_band;
bool changed = false;
int i;
int error = 0;
clk_rate = rx_get_scdc_clkrate_sts();
if (rx.state < FSM_WAIT_CLK_STABLE)
return changed;
if (is_clk_stable()) {
rx.phy.cable_clk = rx_measure_clock(MEASURE_CLK_CABLE);
rx.phy.tmds_clk = rx_measure_clock(MEASURE_CLK_TMDS);
rx.phy.phy_bw = aml_cable_clk_band(rx.phy.cable_clk, clk_rate);
rx.phy.pll_bw = aml_phy_pll_band(rx.phy.cable_clk, clk_rate);
pll_band = aml_phy_pll_band(rx.phy.cable_clk, clk_rate);
phy_band = aml_cable_clk_band(rx.phy.cable_clk, clk_rate);
if ((rx.phy.pll_bw != pll_band) ||
(rx.phy.phy_bw != phy_band)) {
rx.phy.cablesel = 0;
rx.phy.phy_bw = phy_band;
rx.phy.pll_bw = pll_band;
}
}
if (clk_rate != rx.phy.clk_rate) {
@@ -2224,32 +2266,10 @@ bool rx_clkrate_monitor(void)
clk_rate, rx.phy.clk_rate);
rx.phy.clk_rate = clk_rate;
}
#if 0
if (rx.chip_id == CHIP_ID_TL1) {
cur_cable_clk = rx_measure_clock(MEASURE_CLK_CABLE);
clk_diff = diff(rx.phy.cable_clk, cur_cable_clk);
/*clk_rate = rx_get_scdc_clkrate_sts();*/
cur_phy_bw = aml_cable_clk_band(cur_cable_clk, clk_rate);
if ((rx.cur_5v_sts) && ((rx.phy.phy_bw != cur_phy_bw) ||
changed || (clk_diff > (1000*KHz)))) {
changed = true;
aml_phy_bw_switch();
udelay(50);/*wait pll lock*/
rx_pr("phy clk chg:cabclk:%d,%d,rate:%d,lock:%d\n",
cur_cable_clk, rx.phy.cable_clk,
clk_rate, aml_phy_pll_lock());
rx.phy.cable_clk = cur_cable_clk;
rx.phy.clk_rate = clk_rate;
rx.phy.phy_bw = cur_phy_bw;
}
}
#endif
if (changed) {
if (rx.state >= FSM_WAIT_CLK_STABLE)
rx.state = FSM_WAIT_CLK_STABLE;
}
return changed;
}
@@ -3243,7 +3263,7 @@ uint32_t aml_cable_clk_band(uint32_t cableclk,
bw = phy_frq_band_4;
else {
bw = phy_frq_band_2;
rx_pr("phy err: bw clk=%d\n", cableclk);
rx_pr("bw err,clk=%d\n", cableclk/MHz);
}
return bw;
}
@@ -3268,10 +3288,8 @@ uint32_t aml_phy_pll_band(uint32_t cableclk,
bw = pll_frq_band_3;
else if (cab_clk < (600*MHz))
bw = pll_frq_band_4;
else {
else
bw = pll_frq_band_2;
rx_pr("phy err: bw clk=%d\n", cableclk);
}
return bw;
}
@@ -3324,7 +3342,7 @@ static const uint32_t phy_dcha[][3] = {
0x000002a2, 0x4800c202, 0x01009126,
},
{ /* 155~340M */
0x000002a2, 0x0800c202, 0x0100fc31,
0x000002a2, 0x0800c202, 0x0100cc31,
},
{ /* 340~600M */
0x000002a2, 0x0700003c, 0x1d00cc31,
@@ -3347,7 +3365,7 @@ static const uint32_t phy_dchd_1[][3] = {
0x002c714a, 0x1e062620, 0x00018000,
},
{ /* 340~600M */
0x002c715a, 0x1e064640, 0x00018000,
0x002c714a, 0x1e051650, 0x00018000,
},
};
@@ -3360,6 +3378,26 @@ static const uint32_t phy_dchd_2[][3] = {
{ /* 45~74.5M */
0x002e712a, 0x1e022220, 0x00018000,
},
{ /* 77~155M */
0x002c715a, 0x1e022220, 0x00018000,
},
{ /* 155~340M */
0x002c715a, 0x1e022220, 0x00018000,
},
{ /* 340~600M */
0x002c715a, 0x1e022220, 0x00018000,
},
};
/* short cable */
static const uint32_t phy_dchd_3[][3] = {
/* 0xe5 0xe6 0xe7 */
{ /* 24~45M */
0x002e712a, 0x1e022220, 0x00018000,
},
{ /* 45~74.5M */
0x002e712a, 0x1e022220, 0x00018000,
},
{ /* 77~155M */
0x002c714a, 0x1e022220, 0x00018000,
},
@@ -3367,7 +3405,27 @@ static const uint32_t phy_dchd_2[][3] = {
0x002c714a, 0x1e022220, 0x00018000,
},
{ /* 340~600M */
0x002c715a, 0x1e012030, 0x00018000,
0x002c714a, 0x1e022220, 0x00018000,
},
};
/* long cable */
static const uint32_t phy_dchd_4[][3] = {
/* 0xe5 0xe6 0xe7 */
{ /* 24~45M */
0x002e712a, 0x1e062620, 0x00018000,
},
{ /* 45~74.5M */
0x002e712a, 0x1e062620, 0x00018000,
},
{ /* 77~155M */
0x002c715a, 0x1e062620, 0x00018000,
},
{ /* 155~340M */
0x002c715a, 0x1e062620, 0x00018000,
},
{ /* 340~600M */
0x002c715a, 0x1e051650, 0x00018000,
},
};
@@ -3428,12 +3486,18 @@ void aml_eq_setting(void)
if (find_best_eq) {
data32 = phy_dchd_1[idx][1] & (~(MSK(16, 4)));
data32 |= find_best_eq << 4;
} else if ((rx.phy.cablesel % 2) == 0)
} else if ((rx.phy.cablesel % 4) == 0)
data32 = phy_dchd_1[idx][1];
else if ((rx.phy.cablesel % 2) == 1) {
else if ((rx.phy.cablesel % 4) == 1)
data32 = phy_dchd_2[idx][1];
rx_pr("longcable\n");
}
else if ((rx.phy.cablesel % 4) == 2)
data32 = phy_dchd_3[idx][1];
else if ((rx.phy.cablesel % 4) == 3)
data32 = phy_dchd_4[idx][1];
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, data32);
udelay(2);
@@ -3484,10 +3548,13 @@ void rx_get_best_eq_setting(void)
}
time_cnt++;
if (time_cnt > 2) {
if (!is_tmds_valid())
return;
}
if (time_cnt > 4) {
rx_get_error_cnt(&ch0, &ch1, &ch2);
err_sum += (ch0 + ch1 + ch2);
}
if (time_cnt > eq_try_cnt) {
time_cnt = 0;
if (err_sum < rx.phy.err_sum) {
@@ -3543,8 +3610,10 @@ void aml_phy_pll_setting(void)
od2 = apll_tab[bw].od2;
vco_clk = (cableclk * M) / N; /*KHz*/
if ((vco_clk < (2970 * KHz)) || (vco_clk > (6000 * KHz)))
rx_pr("err: M=%d,N=%d,vco_clk=%d\n", M, N, vco_clk);
if ((vco_clk < (2970 * KHz)) || (vco_clk > (6000 * KHz))) {
if (log_level & VIDEO_LOG)
rx_pr("err: M=%d,N=%d,vco_clk=%d\n", M, N, vco_clk);
}
/*tmds clk out*/
apll_out = (vco_clk/od_div)/5;
@@ -3664,6 +3733,17 @@ bool is_tmds_clk_stable(void)
return ret;
}
bool is_tmds_valid(void)
{
if (force_vic)
return true;
if (rx.chip_id == CHIP_ID_TL1)
return (aml_phy_tmds_valid() == 1) ? true : false;
else
return (rx_get_pll_lock_sts() == 1) ? true : false;
}
unsigned int aml_phy_tmds_valid(void)
{
unsigned int tmds_valid;

View File

@@ -1284,6 +1284,9 @@ extern void rx_tmds_to_ddr_init(void);
extern void rx_emp_capture_stop(void);
extern void rx_get_error_cnt(uint32_t *ch0, uint32_t *ch1, uint32_t *ch2);
extern void rx_get_audio_N_CTS(uint32_t *N, uint32_t *CTS);
extern void rx_run_eq(void);
extern bool rx_eq_done(void);
extern bool is_tmds_valid(void);
#endif

View File

@@ -188,7 +188,7 @@ int phy_retry_times = 1;
* some out-spec sources whose framerate change a lot(e.g:59.7~60.16hz).
* Other brands of tv can support this,we also need to support.
*/
static int stable_check_lvl = 0x7df;
static int stable_check_lvl;
/* If dvd source received the frequent pulses on HPD line,
* It will sent a length of dirty audio data sometimes.it's TX's issues.
@@ -213,9 +213,13 @@ void hdmirx_init_params(void)
if (rx.chip_id == CHIP_ID_TL1) {
clk_unstable_max = 10;
esd_phy_rst_max = 200;
stable_check_lvl = 0x7df;
pll_lock_max = 1;
} else {
clk_unstable_max = 200;
esd_phy_rst_max = 2;
stable_check_lvl = 0x17df;
pll_lock_max = 2;
}
}
@@ -959,91 +963,108 @@ static bool rx_is_timing_stable(void)
{
bool ret = true;
uint32_t ch0 = 0, ch1 = 0, ch2 = 0;
if ((abs(rx.cur.hactive - rx.pre.hactive) > diff_pixel_th) &&
(stable_check_lvl & HACTIVE_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("hactive(%d=>%d),",
rx.pre.hactive,
rx.cur.hactive);
if (stable_check_lvl & TMDS_VALID_EN) {
if (!is_tmds_valid()) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("TMDS invalid\n");
}
}
if ((abs(rx.cur.vactive - rx.pre.vactive) > diff_line_th) &&
(stable_check_lvl & VACTIVE_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("vactive(%d=>%d),",
rx.pre.vactive,
rx.cur.vactive);
if (stable_check_lvl & HACTIVE_EN) {
if ((diff(rx.cur.hactive, rx.pre.hactive) > diff_pixel_th) ||
(rx.cur.hactive == 0)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("hactive(%d=>%d),",
rx.pre.hactive,
rx.cur.hactive);
}
}
if ((abs(rx.cur.htotal - rx.pre.htotal) > diff_pixel_th) &&
(stable_check_lvl & HTOTAL_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("htotal(%d=>%d),",
rx.pre.htotal,
rx.cur.htotal);
if (stable_check_lvl & VACTIVE_EN) {
if ((diff(rx.cur.vactive, rx.pre.vactive) > diff_line_th) ||
(rx.cur.vactive == 0)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("vactive(%d=>%d),",
rx.pre.vactive,
rx.cur.vactive);
}
}
if ((abs(rx.cur.vtotal - rx.pre.vtotal) > diff_line_th) &&
(stable_check_lvl & VTOTAL_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("vtotal(%d=>%d),",
rx.pre.vtotal,
rx.cur.vtotal);
if (stable_check_lvl & HTOTAL_EN) {
if (diff(rx.cur.htotal, rx.pre.htotal) > diff_pixel_th) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("htotal(%d=>%d),",
rx.pre.htotal,
rx.cur.htotal);
}
}
if ((rx.pre.colorspace != rx.cur.colorspace) &&
(stable_check_lvl & COLSPACE_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("colorspace(%d=>%d),",
rx.pre.colorspace,
rx.cur.colorspace);
if (stable_check_lvl & VTOTAL_EN) {
if (diff(rx.cur.vtotal, rx.pre.vtotal) > diff_line_th) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("vtotal(%d=>%d),",
rx.pre.vtotal,
rx.cur.vtotal);
}
}
if ((abs(rx.pre.frame_rate - rx.cur.frame_rate) > diff_frame_th) &&
(stable_check_lvl & REFRESH_RATE_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("frame_rate(%d=>%d),",
rx.pre.frame_rate,
rx.cur.frame_rate);
if (stable_check_lvl & COLSPACE_EN) {
if (rx.pre.colorspace != rx.cur.colorspace) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("colorspace(%d=>%d),",
rx.pre.colorspace,
rx.cur.colorspace);
}
}
if ((rx.pre.repeat != rx.cur.repeat) &&
(stable_check_lvl & REPEAT_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("repeat(%d=>%d),",
rx.pre.repeat,
rx.cur.repeat);
if (stable_check_lvl & REFRESH_RATE_EN) {
if (diff(rx.pre.frame_rate, rx.cur.frame_rate)
> diff_frame_th) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("frame_rate(%d=>%d),",
rx.pre.frame_rate,
rx.cur.frame_rate);
}
}
if ((rx.pre.hw_dvi != rx.cur.hw_dvi) &&
(stable_check_lvl & DVI_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("dvi(%d=>%d),",
rx.pre.hw_dvi,
rx.cur.hw_dvi);
if (stable_check_lvl & REPEAT_EN) {
if ((rx.pre.repeat != rx.cur.repeat) &&
(stable_check_lvl & REPEAT_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("repeat(%d=>%d),",
rx.pre.repeat,
rx.cur.repeat);
}
}
if ((rx.pre.interlaced != rx.cur.interlaced) &&
(stable_check_lvl & INTERLACED_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("interlaced(%d=>%d),",
rx.pre.interlaced,
rx.cur.interlaced);
if (stable_check_lvl & DVI_EN) {
if (rx.pre.hw_dvi != rx.cur.hw_dvi) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("dvi(%d=>%d),",
rx.pre.hw_dvi,
rx.cur.hw_dvi);
}
}
if ((rx.pre.colordepth != rx.cur.colordepth) &&
(stable_check_lvl & COLOR_DEP_EN)) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("colordepth(%d=>%d),",
rx.pre.colordepth,
rx.cur.colordepth);
if (stable_check_lvl & INTERLACED_EN) {
if (rx.pre.interlaced != rx.cur.interlaced) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("interlaced(%d=>%d),",
rx.pre.interlaced,
rx.cur.interlaced);
}
}
/*for aml phy, check error counter*/
if (rx.chip_id == CHIP_ID_TL1 &&
(stable_check_lvl & ERR_CNT_EN)) {
if (stable_check_lvl & COLOR_DEP_EN) {
if (rx.pre.colordepth != rx.cur.colordepth) {
ret = false;
if (log_level & VIDEO_LOG)
rx_pr("colordepth(%d=>%d),",
rx.pre.colordepth,
rx.cur.colordepth);
}
}
if (stable_check_lvl & ERR_CNT_EN) {
rx_get_error_cnt(&ch0, &ch1, &ch2);
if ((ch0 + ch1 + ch2) > max_err_cnt) {
if (sig_stable_err_cnt++ > sig_stable_err_max) {
@@ -1056,7 +1077,6 @@ static bool rx_is_timing_stable(void)
ret = false;
}
}
if ((ret == false) && (log_level & VIDEO_LOG))
rx_pr("\n");
@@ -1203,6 +1223,20 @@ void rx_dwc_reset(void)
hdmirx_packet_fifo_rst();
}
bool rx_hpd_keep_low(void)
{
bool ret = false;
if (downstream_hpd_flag) {
if (hpd_wait_cnt <= hpd_wait_max*5)
ret = true;
} else {
if (hpd_wait_cnt <= hpd_wait_max)
ret = true;
}
return ret;
}
int rx_get_cur_hpd_sts(void)
{
int tmp;
@@ -1212,17 +1246,6 @@ int rx_get_cur_hpd_sts(void)
return tmp;
}
bool is_tmds_valid(void)
{
if (force_vic)
return true;
if (rx.chip_id == CHIP_ID_TL1)
return (aml_phy_tmds_valid() == 1) ? true : false;
else
return (rx_get_pll_lock_sts() == 1) ? true : false;
}
void esm_set_reset(bool reset)
{
if (log_level & HDCP_LOG)
@@ -2063,14 +2086,9 @@ void rx_main_state_machine(void)
break;
case FSM_HPD_HIGH:
hpd_wait_cnt++;
if (rx_get_cur_hpd_sts() == 0) {
if (downstream_hpd_flag) {
if (hpd_wait_cnt <= hpd_wait_max*5)
break;
} else {
if (hpd_wait_cnt <= hpd_wait_max)
break;
}
if ((rx_get_cur_hpd_sts() == 0) &&
rx_hpd_keep_low()) {
break;
}
hpd_wait_cnt = 0;
clk_unstable_cnt = 0;
@@ -2111,11 +2129,11 @@ void rx_main_state_machine(void)
}
break;
case FSM_EQ_START:
rx_eq_algorithm();
rx_run_eq();
rx.state = FSM_WAIT_EQ_DONE;
break;
case FSM_WAIT_EQ_DONE:
if (rx_get_eq_run_state() != E_EQ_START) {
if (rx_eq_done()) {
rx.state = FSM_SIG_UNSTABLE;
pll_lock_cnt = 0;
pll_unlock_cnt = 0;
@@ -2138,9 +2156,10 @@ void rx_main_state_machine(void)
if (rx.err_rec_mode == ERR_REC_EQ_RETRY) {
rx.state = FSM_WAIT_CLK_STABLE;
if (esd_phy_rst_cnt++ < esd_phy_rst_max) {
hdmirx_phy_init();
rx.phy.cablesel++;
rx_pr("cablesel=%d\n", rx.phy.cablesel);
rx.phy.cable_clk = 0;
/* hdmirx_phy_init(); */
} else
rx.err_rec_mode = ERR_REC_HPD_RST;
} else if (rx.err_rec_mode == ERR_REC_HPD_RST) {
@@ -2229,6 +2248,7 @@ void rx_main_state_machine(void)
if (rx.err_rec_mode == ERR_REC_EQ_RETRY) {
rx.state = FSM_WAIT_CLK_STABLE;
rx.phy.cablesel++;
rx_pr("cablesel1=%d\n", rx.phy.cablesel);
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) {

View File

@@ -31,6 +31,7 @@
#define HDCP_ENC_EN 0x200
#define COLOR_DEP_EN 0x400
#define ERR_CNT_EN 0x800
#define TMDS_VALID_EN 0x1000
/* aud sample rate stable range */
/* #define AUD_SR_RANGE 2000 */
@@ -113,6 +114,7 @@ enum dumpinfo_e {
};
/* signal */
extern int force_vic;
extern enum tvin_sig_fmt_e hdmirx_hw_get_fmt(void);
extern void rx_main_state_machine(void);
extern void rx_err_monitor(void);