#include "hdmi_rx_edid.h"
-#define RX_VER0 "ver.2018-12-19"
+#define RX_VER0 "ver.2019-01-08"
/*
*
*
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;
#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"
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)
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;
}
}
+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
*/
*/
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) {
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;
}
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;
}
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;
}
0x000002a2, 0x4800c202, 0x01009126,
},
{ /* 155~340M */
- 0x000002a2, 0x0800c202, 0x0100fc31,
+ 0x000002a2, 0x0800c202, 0x0100cc31,
},
{ /* 340~600M */
0x000002a2, 0x0700003c, 0x1d00cc31,
0x002c714a, 0x1e062620, 0x00018000,
},
{ /* 340~600M */
- 0x002c715a, 0x1e064640, 0x00018000,
+ 0x002c714a, 0x1e051650, 0x00018000,
},
};
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,
},
{ /* 155~340M */
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,
},
};
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);
}
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) {
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;
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;
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
* 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.
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;
}
}
{
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) {
ret = false;
}
}
-
if ((ret == false) && (log_level & VIDEO_LOG))
rx_pr("\n");
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;
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)
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;
}
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;
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) {
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) {
#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 */
};
/* 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);