mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
hdmirx: i2c monitor [1/1]
PD#SWPL-132152 Problem: support to dump i2c data Solution: support to dump i2c data Verify: t3x Change-Id: I127e91f84297daddee6b720eba2bff17f53104e2 Signed-off-by: Gaowei Zhao <gaowei.zhao@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
2bab1d3389
commit
c19d943134
@@ -628,7 +628,7 @@
|
||||
0x0 0x0 0x0 0x0
|
||||
0x0 0x0 0x0 0x0
|
||||
0x0 0xfe390000 0x0 0x20000
|
||||
0x0 0xfe000000 0x0 0x1fff
|
||||
0x0 0xfe000000 0x0 0x15000
|
||||
0x0 0xfe008000 0x280 0x334>;
|
||||
};
|
||||
|
||||
|
||||
@@ -770,6 +770,11 @@ struct emp_info_s {
|
||||
u8 data_ver;
|
||||
};
|
||||
|
||||
struct i2c_info_s {
|
||||
phys_addr_t phy_addr;
|
||||
struct page *pg_addr;
|
||||
};
|
||||
|
||||
struct spkts_rcvd_sts {
|
||||
u32 pkt_vsi_rcvd:1;
|
||||
u32 pkt_drm_rcvd:1;
|
||||
@@ -840,6 +845,7 @@ struct rx_info_s {
|
||||
struct rx_aml_phy aml_phy_21;
|
||||
struct emp_info_s emp_buff_a; //for vid0
|
||||
struct emp_info_s emp_buff_b; //for vid1
|
||||
struct i2c_info_s i2c_buff;
|
||||
struct edid_capacity edid_cap;
|
||||
bool suspend_flag;
|
||||
};
|
||||
|
||||
@@ -6026,6 +6026,9 @@ int rx_debug_wr_reg(const char *buf, char *tmpbuf, int i, u8 port)
|
||||
} else if (buf[2] == 'A') {
|
||||
hdmirx_wr_amlphy_t3x(adr, value, port);
|
||||
rx_pr("write %x to port%d [%x]\n", value, port, adr);
|
||||
} else if (buf[2] == 'c') {
|
||||
wr_reg_clk_ctl(adr, value);
|
||||
rx_pr("write %x to [%x]\n", value, adr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -6072,6 +6075,9 @@ int rx_debug_rd_reg(const char *buf, char *tmpbuf, u8 port)
|
||||
} else if (buf[2] == 'A') {
|
||||
value = hdmirx_rd_amlphy_t3x(adr, port);
|
||||
rx_pr("port%d, amlphy [%x]=%x\n", port, adr, value);
|
||||
} else if (buf[2] == 'c') {
|
||||
value = rd_reg_clk_ctl(adr);
|
||||
rx_pr("amlphy [%x]=%x\n", adr, value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -3430,6 +3430,7 @@ unsigned int hdmirx_rd_amlphy(unsigned int addr);
|
||||
unsigned int hdmirx_rd_amlphy_t3x(unsigned int addr, u8 port);
|
||||
void hdmirx_irq_hdcp_enable(bool enable, u8 port);
|
||||
u8 rx_get_avmute_sts(u8 port);
|
||||
void wr_reg_ana_ctl(u32 offset, u32 val);
|
||||
u8 hdmirx_rd_cor(u32 addr, u8 port);
|
||||
void hdmirx_wr_cor(u32 addr, u8 data, u8 port);
|
||||
bool hdmirx_poll_cor(u32 addr, u8 exp_data, u8 mask, u32 max_try, u8 port);
|
||||
|
||||
@@ -60,7 +60,8 @@ int vga_tuning_min = 0x21;
|
||||
int vga_tuning_max = 0x26;
|
||||
int cal_phy_time;
|
||||
enum frl_train_sts_e frl_train_sts = E_FRL_TRAIN_START;
|
||||
|
||||
/* i2c monitor */
|
||||
#define I2C_BUFF_SIZE 0x1000
|
||||
/* for T3X 2.0 */
|
||||
static const u32 phy_misc_t3x_20[][2] = {
|
||||
/* 0x18 0x1c */
|
||||
@@ -4825,6 +4826,208 @@ bool is_frl_train_finished(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rx_i2c_dbg_monitor(void)
|
||||
{
|
||||
u32 data32;
|
||||
|
||||
if (rx_info.chip_id != CHIP_ID_T3X)
|
||||
return;
|
||||
data32 = rd_reg_clk_ctl(T3X_I2C_MONITOR_INTR_STATUS);
|
||||
|
||||
if (data32 > 3) { //ignore start abnormal
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_START, 0x0);
|
||||
rx_i2c_dump();
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_INTR_STATUS, data32);
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_parse_i2c_data(u8 *buf, int size)
|
||||
{
|
||||
static const char * const ack_print[] = {"ACK", "NAK"};
|
||||
static const char * const wr_print[] = {"Write", "Read"};
|
||||
u8 type, data, ack, wr;
|
||||
int i;
|
||||
|
||||
if (!buf || size < 4)
|
||||
return;
|
||||
for (i = 0; i < size; i += 4) {
|
||||
/*
|
||||
* |31..29|28.......9|8..1| 0|
|
||||
* |type |delta time|data|ack|
|
||||
*/
|
||||
if (!buf[i] && !buf[i + 1] && !buf[i + 2] && !buf[i + 3])
|
||||
break;
|
||||
type = (buf[i + 3] & MSK(3, 5)) >> 5;
|
||||
data = (buf[i] & MSK(7, 1)) >> 1 | (buf[i + 1] & 0x1) << 7;
|
||||
ack = buf[i] & 0x1;
|
||||
wr = data & 0x1;
|
||||
|
||||
switch (type) {
|
||||
case E_DATA:
|
||||
rx_pr("0x%x + %s\n", data, ack_print[ack]);
|
||||
break;
|
||||
case E_START_DATA:
|
||||
rx_pr("%s to [0x%x] + %s\n", wr_print[wr], data, ack_print[ack]);
|
||||
break;
|
||||
case E_STOP_DATA:
|
||||
rx_pr("0x%x + %s + Stop\n", data, ack_print[ack]);
|
||||
break;
|
||||
case E_START_DATA_STOP:
|
||||
rx_pr("%s to [0x%x] + %s + Stop\n", wr_print[wr], data, ack_print[ack]);
|
||||
break;
|
||||
case E_STOP_ABNORMAL:
|
||||
rx_pr("!!STOP Abnormal(incomplete data)\n");
|
||||
break;
|
||||
case E_START_ABNORMAL:
|
||||
if (ack) {
|
||||
rx_pr("!!Start Abnormal: %s to [0x%x] + %s\n",
|
||||
wr_print[wr], data, ack_print[ack]);
|
||||
} else {
|
||||
rx_pr("!!Start Abnormal(incomplete data)\n");
|
||||
}
|
||||
break;
|
||||
case E_TIME_OUT:
|
||||
if (ack)
|
||||
rx_pr("!!time out(no data)\n");
|
||||
else
|
||||
rx_pr("!!time out + 0x%x\n", data);
|
||||
break;
|
||||
default:
|
||||
if ((data >> 5) == 0) {
|
||||
if (ack)
|
||||
rx_pr("HPD rise\n");
|
||||
else
|
||||
rx_pr("HPD fall\n");
|
||||
} else {
|
||||
rx_pr("!!other type:0x%x\n", data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
rx_pr("i:0x%x\n", i);
|
||||
}
|
||||
|
||||
void rx_i2c_monitor(u8 sel, u8 smp_mod, u8 trig_mod, u8 dump_mod)
|
||||
{
|
||||
u8 *src = NULL;
|
||||
u32 data32;
|
||||
|
||||
data32 = 0;
|
||||
data32 |= (smp_mod == 3 ? 1 : 0) << 31; //[31] bist_mode exist bug, can't use
|
||||
data32 |= (dump_mod & 0x1f) << 16; //[20-16]dump mode
|
||||
data32 |= 0x0 << 4; //[4] clk_free
|
||||
data32 |= (smp_mod & 0x3) << 2; //[3:2] smp_mode
|
||||
data32 |= 0x1 << 1; //[1] hpd_en
|
||||
data32 |= (trig_mod & 0x1) << 0; //[0] trig_mode
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_CNTL, data32);
|
||||
|
||||
data32 = 0;
|
||||
data32 |= (sel >= 6 ? 1 << (sel - 6) : 0) << 24; //[31:24] sel input hpd to monitor
|
||||
data32 |= (1 << sel) << 0; //[23:0] sel input scl to monitor
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_SEL, data32);
|
||||
|
||||
data32 = 0;
|
||||
data32 |= 0x2008 << 16; //[31:16] scl filter control
|
||||
data32 |= 0x2008 << 0; //[15: 0] sda filter control
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_FLT, data32);
|
||||
|
||||
data32 = 0;
|
||||
data32 |= 0x7 << 0; //[15: 0] sda filter control
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_FLT_HPD, data32);
|
||||
|
||||
data32 = 0;
|
||||
data32 |= 0xa << 16; //[31:16] time tick in smp_clk
|
||||
data32 |= 0x1 << 8; //[ 8] smp_clk enable
|
||||
data32 |= 0x5 << 0; //[ 7: 0] smp_clk div, cec sample:0x48
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_CLK, data32);
|
||||
|
||||
data32 = 0;
|
||||
data32 |= 0x3ff << 0; //[10:0]
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_INTR_MASK, data32);
|
||||
|
||||
rx_info.i2c_buff.pg_addr = alloc_pages(GFP_KERNEL, 0);
|
||||
src = (u8 *)kmap_atomic(rx_info.i2c_buff.pg_addr);
|
||||
memset(src, 0x0, I2C_BUFF_SIZE);
|
||||
kunmap_atomic(src);
|
||||
rx_info.i2c_buff.phy_addr = page_to_phys(rx_info.i2c_buff.pg_addr);
|
||||
|
||||
if (rx_info.i2c_buff.phy_addr) {
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_DDR_START_ADDR,
|
||||
rx_info.i2c_buff.phy_addr >> 4);
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_DDR_END_ADDR,
|
||||
(rx_info.i2c_buff.phy_addr + I2C_BUFF_SIZE) >> 4);
|
||||
}
|
||||
|
||||
data32 = 0;
|
||||
data32 |= 0x1 << 4; //[ 4] endian in 32 bit
|
||||
data32 |= 0x0 << 0; //[3:0] burst length
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_DDR_CNTL, data32);
|
||||
|
||||
//smp start,config this bit after all the other reg has been ready
|
||||
wr_reg_clk_ctl(T3X_I2C_MONITOR_SMP_START, 0x1);
|
||||
}
|
||||
|
||||
static void rx_i2c_reg_dump(void)
|
||||
{
|
||||
rx_pr("T3X_I2C_MONITOR_SMP_CNTL: 0x%x-0x%x\n", T3X_I2C_MONITOR_SMP_CNTL,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_SMP_CNTL));
|
||||
rx_pr("T3X_I2C_MONITOR_SMP_SEL: 0x%x-0x%x\n", T3X_I2C_MONITOR_SMP_SEL,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_SMP_SEL));
|
||||
rx_pr("T3X_I2C_MONITOR_SMP_FLT: 0x%x-0x%x\n", T3X_I2C_MONITOR_SMP_FLT,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_SMP_FLT));
|
||||
rx_pr("T3X_I2C_MONITOR_SMP_FLT_HPD: 0x%x-0x%x\n", T3X_I2C_MONITOR_SMP_FLT_HPD,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_SMP_FLT_HPD));
|
||||
rx_pr("T3X_I2C_MONITOR_SMP_CLK: 0x%x-0x%x\n", T3X_I2C_MONITOR_SMP_CLK,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_SMP_CLK));
|
||||
rx_pr("T3X_I2C_MONITOR_INTR_MASK: 0x%x-0x%x\n", T3X_I2C_MONITOR_INTR_MASK,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_INTR_MASK));
|
||||
rx_pr("T3X_I2C_MONITOR_DDR_START_ADDR: 0x%x-0x%x\n", T3X_I2C_MONITOR_DDR_START_ADDR,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_START_ADDR));
|
||||
rx_pr("T3X_I2C_MONITOR_DDR_END_ADDR: 0x%x-0x%x\n", T3X_I2C_MONITOR_DDR_END_ADDR,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_END_ADDR));
|
||||
rx_pr("T3X_I2C_MONITOR_DDR_CNTL: 0x%x-0x%x\n", T3X_I2C_MONITOR_DDR_CNTL,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_CNTL));
|
||||
}
|
||||
|
||||
void rx_i2c_dump(void)
|
||||
{
|
||||
//int i, j;
|
||||
u8 *i2c_buff = NULL;
|
||||
u8 *src_buf = NULL;
|
||||
int buf_cnt;
|
||||
|
||||
if (log_level & REG_LOG)
|
||||
rx_i2c_reg_dump();
|
||||
|
||||
i2c_buff = kmalloc(I2C_BUFF_SIZE, GFP_KERNEL);
|
||||
if (!i2c_buff)
|
||||
return;
|
||||
memset(i2c_buff, 0, I2C_BUFF_SIZE);
|
||||
src_buf = (u8 *)kmap_atomic(rx_info.i2c_buff.pg_addr);
|
||||
if (!src_buf) {
|
||||
kfree(i2c_buff);
|
||||
return;
|
||||
}
|
||||
memcpy(i2c_buff, src_buf, I2C_BUFF_SIZE);
|
||||
/*
|
||||
*for (i = 0; i < 128; i++) {
|
||||
* for (j = 0; j < 32; j++)
|
||||
* pr_cont("%02X ", i2c_buff[i * 32 + j]);
|
||||
* rx_pr("\n");
|
||||
*}
|
||||
*/
|
||||
kunmap_atomic(src_buf);
|
||||
|
||||
buf_cnt = (rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_WPTR) -
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_START_ADDR)) << 4;
|
||||
rx_pr("buf_cnt:wptr:0x%x-start:0x%x=0x%x\n",
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_WPTR) << 4,
|
||||
rd_reg_clk_ctl(T3X_I2C_MONITOR_DDR_START_ADDR) << 4,
|
||||
buf_cnt);
|
||||
rx_parse_i2c_data(i2c_buff, I2C_BUFF_SIZE);
|
||||
kfree(i2c_buff);
|
||||
}
|
||||
|
||||
void rx_frl_train_handler(struct work_struct *work)
|
||||
{
|
||||
hdmi_tx_rx_frl_training_main(E_PORT2);
|
||||
|
||||
@@ -134,6 +134,59 @@
|
||||
#define T3X_CLKCTRL_AUD21_PLL_CTRL3 (0x02ed << 2)
|
||||
#define T3X_CLKCTRL_AUD21_PLL_STS (0x02ee << 2)
|
||||
|
||||
/* i2c monitor reg */
|
||||
#define T3X_I2C_MONITOR_BASE 0xfe014000
|
||||
#define T3X_I2C_MONITOR_SMP_START (0x14000 + (0x000 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_SEL (0x14000 + (0x001 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_CNTL (0x14000 + (0x002 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_FLT (0x14000 + (0x003 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_FLT_HPD (0x14000 + (0x004 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_I2C_TIMEOUT_TH (0x14000 + (0x005 << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_CLK (0x14000 + (0x006 << 2))
|
||||
#define T3X_I2C_MONITOR_DDR_START_ADDR (0x14000 + (0x007 << 2))
|
||||
#define T3X_I2C_MONITOR_DDR_END_ADDR (0x14000 + (0x008 << 2))
|
||||
#define T3X_I2C_MONITOR_DDR_CNTL (0x14000 + (0x009 << 2))
|
||||
#define T3X_I2C_MONITOR_INTR_MASK (0x14000 + (0x00a << 2))
|
||||
#define T3X_I2C_MONITOR_DDR_WPTR (0x14000 + (0x00b << 2))
|
||||
#define T3X_I2C_MONITOR_DDR_BOUND_CNT (0x14000 + (0x00c << 2))
|
||||
#define T3X_I2C_MONITOR_AXI_CMD_PENDING (0x14000 + (0x00d << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_STATUS (0x14000 + (0x00e << 2))
|
||||
#define T3X_I2C_MONITOR_SMP_I2C_BUSY_CNT (0x14000 + (0x00f << 2))
|
||||
#define T3X_I2C_MONITOR_AXI_STATUS (0x14000 + (0x010 << 2))
|
||||
#define T3X_I2C_MONITOR_INTR_STATUS (0x14000 + (0x011 << 2))
|
||||
#define T3X_I2C_MONITOR_AXI_CMD_CNT (0x14000 + (0x012 << 2))
|
||||
|
||||
enum i2c_sample_mode_e {
|
||||
E_FUNC_SAMPLE,
|
||||
E_I2C_WAVE_SAMPLE,
|
||||
E_CEC_WAVE_SAMPLE,
|
||||
E_BIST_MODE
|
||||
};
|
||||
|
||||
enum i2c_trigger_mode_e {
|
||||
E_HW_TRIGGER,
|
||||
E_SW_TRIGGER
|
||||
};
|
||||
|
||||
enum i2c_dump_mode_e {
|
||||
E_ABNORMAL_START0 = 0x1,
|
||||
E_ABNORMAL_START1 = 0x2,
|
||||
E_ABNORMAL_STOP = 0x4,
|
||||
E_I2C_TIMEOUT = 0x8,
|
||||
E_HPD_CHANGE = 0x10,
|
||||
E_DUMP_ALL = 0x1f
|
||||
};
|
||||
|
||||
enum i2c_data_type_e {
|
||||
E_DATA,
|
||||
E_START_DATA,
|
||||
E_STOP_DATA,
|
||||
E_START_DATA_STOP,
|
||||
E_STOP_ABNORMAL,
|
||||
E_START_ABNORMAL,
|
||||
E_TIME_OUT
|
||||
};
|
||||
|
||||
enum frl_train_sts_e {
|
||||
E_FRL_TRAIN_START,
|
||||
E_FRL_TRAIN_FINISH,
|
||||
@@ -230,6 +283,9 @@ bool is_fsm_ready_t3x(void);
|
||||
bool rx_get_clkready_sts(u8 port);
|
||||
bool rx_get_valid_m_sts(u8 port);
|
||||
|
||||
void rx_i2c_dbg_monitor(void);
|
||||
void rx_i2c_monitor(u8 sel, u8 smp_mod, u8 trig_mod, u8 dump_mod);
|
||||
void rx_i2c_dump(void);
|
||||
//void reset_pcs(void);
|
||||
|
||||
/*function declare end*/
|
||||
|
||||
@@ -8413,6 +8413,12 @@ int hdmirx_debug(const char *buf, int size)
|
||||
rx_pr("phy_addr = 0x%x, size = 0x%x, maped:%px\n",
|
||||
rx_reg_maps[i].phy_addr, size, rx_reg_maps[i].p);
|
||||
}
|
||||
} else if (strncmp(tmpbuf, "i2c_monitor", 10) == 0) {
|
||||
rx_i2c_monitor(6 + port, E_FUNC_SAMPLE, E_SW_TRIGGER, E_DUMP_ALL);
|
||||
rx_pr("i2c_monitor start\n");
|
||||
} else if (strncmp(tmpbuf, "i2c_dump", 7) == 0) {
|
||||
rx_pr("i2c_dump\n");
|
||||
rx_i2c_dump();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -8699,6 +8705,7 @@ void hdmirx_timer_handler(struct timer_list *t)
|
||||
rx_clkmsr_monitor();
|
||||
rx_hpd_monitor();
|
||||
rx_edid_monitor();
|
||||
rx_i2c_dbg_monitor();
|
||||
if (rx_info.chip_id == CHIP_ID_T3X)
|
||||
hdmirx_timer_t3x();
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user