hdmirx: finetune phy setting [1/1]

PD#172587

Problem:
1.eq performacec is not good (v1)
2.capture tmds raw data to ddr
3.skip unstable cable clock report

Solution:
1.dump tmds date and save as a file
2.1s check err counter
3.modify clock monitor function
4.modify fsm for tl1

Verify:
tl1

Change-Id: Iae51ea0cc8528e9c5fd0bc5c58b5dd7246ee68b1
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
This commit is contained in:
Yong Qin
2018-11-14 17:45:55 +08:00
committed by Luke Go
parent e96d6dfb40
commit 8dd28a3577
5 changed files with 281 additions and 173 deletions

View File

@@ -33,6 +33,7 @@
#include <linux/cdev.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_reserved_mem.h>
#include <linux/poll.h>
#include <linux/io.h>
#include <linux/suspend.h>
@@ -40,6 +41,9 @@
#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/dma-contiguous.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/highmem.h>
/* Amlogic headers */
@@ -1790,13 +1794,15 @@ void rx_tmds_resource_allocate(struct device *dev)
rx_pr("allocate tmds data buff fail\n");
rx.empbuff.dump_mode = DUMP_MODE_TMDS;
rx_pr("buffa paddr=0x%x\n", rx.empbuff.p_addr_a);
rx.empbuff.tmdspktcnt = 0;
}
}
/*
* capture emp pkt data save file emp_data.bin
*
*/
void rx_emp_data_capture(void)
{
/* data to terminal or save a file */
struct file *filp = NULL;
loff_t pos = 0;
void *buf = NULL;
@@ -1808,7 +1814,7 @@ void rx_emp_data_capture(void)
filp = filp_open(path, O_RDWR|O_CREAT, 0666);
if (IS_ERR(filp)) {
pr_info("create %s error.\n", path);
rx_pr("create %s error.\n", path);
return;
}
@@ -1817,23 +1823,28 @@ void rx_emp_data_capture(void)
/*write size*/
offset = rx.empbuff.emppktcnt * 32;
vfs_write(filp, buf, offset, &pos);
pr_info("write from 0x%x to 0x%x to %s.\n",
rx_pr("write from 0x%x to 0x%x to %s.\n",
0, 0 + offset, path);
vfs_fsync(filp, 0);
filp_close(filp, NULL);
set_fs(old_fs);
}
/*
* capture tmds data save file emp_data.bin
*
*/
void rx_tmds_data_capture(void)
{
/* data to terminal or save a file */
struct file *filp = NULL;
loff_t pos = 0;
void *buf = NULL;
char *path = "/data/tmds_data.bin";
unsigned int offset = 0;
unsigned char *src_v_addr;
mm_segment_t old_fs = get_fs();
unsigned int recv_pagenum, i;
unsigned int recv_byte_cnt;
set_fs(KERNEL_DS);
filp = filp_open(path, O_RDWR|O_CREAT, 0666);
@@ -1843,23 +1854,32 @@ void rx_tmds_data_capture(void)
return;
}
/* p addr to v addr for cpu access */
src_v_addr = phys_to_virt(rx.empbuff.p_addr_a);
/*start buffer address*/
buf = src_v_addr;
/*write size*/
offset = (rx.empbuff.tmdspktcnt * 15)/4;/*pkt to bytes*/
vfs_write(filp, buf, offset, &pos);
pr_info("write from 0x%x to 0x%x to %s.\n",
0, 0 + offset, path);
recv_byte_cnt = rx.empbuff.tmdspktcnt * 4;
recv_pagenum = (recv_byte_cnt >> PAGE_SHIFT) + 1;
rx_pr("total byte:%d page:%d\n", recv_byte_cnt, recv_pagenum);
for (i = 0; i < recv_pagenum; i++) {
/* one page 4k,tmds data physical address, need map v addr */
src_v_addr = kmap(rx.empbuff.pg_addr + i);
if (recv_byte_cnt >= PAGE_SIZE) {
offset = PAGE_SIZE;
vfs_write(filp, src_v_addr, offset, &pos);
recv_byte_cnt -= PAGE_SIZE;
} else {
offset = recv_byte_cnt;
vfs_write(filp, src_v_addr, offset, &pos);
}
/* release current page */
kunmap(rx.empbuff.pg_addr + i);
rx_pr("%d ", i);
}
rx_pr("write from 0x%x to 0x%x to %s\n",
pos, offset, path);
vfs_fsync(filp, 0);
filp_close(filp, NULL);
set_fs(old_fs);
}
#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
static void hdmirx_early_suspend(struct early_suspend *h)
{
@@ -2107,21 +2127,22 @@ static int hdmirx_probe(struct platform_device *pdev)
clk_prepare_enable(hdevp->cfg_clk);
clk_rate = clk_get_rate(hdevp->cfg_clk);
}
hdcp22_on = rx_is_hdcp22_support();
if (hdcp22_on) {
hdevp->esm_clk = clk_get(&pdev->dev, "hdcp_rx22_esm");
if (IS_ERR(hdevp->esm_clk))
if (IS_ERR(hdevp->esm_clk)) {
rx_pr("get esm_clk err\n");
else {
} else {
clk_set_parent(hdevp->esm_clk, fclk_div7_clk);
clk_set_rate(hdevp->esm_clk, 285714285);
clk_prepare_enable(hdevp->esm_clk);
clk_rate = clk_get_rate(hdevp->esm_clk);
}
hdevp->skp_clk = clk_get(&pdev->dev, "hdcp_rx22_skp");
if (IS_ERR(hdevp->skp_clk))
if (IS_ERR(hdevp->skp_clk)) {
rx_pr("get skp_clk err\n");
else {
} else {
clk_set_parent(hdevp->skp_clk, xtal_clk);
clk_set_rate(hdevp->skp_clk, 24000000);
clk_prepare_enable(hdevp->skp_clk);
@@ -2142,7 +2163,6 @@ static int hdmirx_probe(struct platform_device *pdev)
}
}
#if 0
hdevp->acr_ref_clk = clk_get(&pdev->dev, "hdmirx_acr_ref_clk");
if (IS_ERR(hdevp->acr_ref_clk))
@@ -2234,6 +2254,9 @@ static int hdmirx_probe(struct platform_device *pdev)
disable_port_num = disable_port & 0xF;
}
ret = of_reserved_mem_device_init(&(pdev->dev));
if (ret != 0)
rx_pr("warning: no rev cmd mem\n");
rx_emp_resource_allocate(&(pdev->dev));
hdmirx_hw_probe();
hdmirx_switch_pinmux(&(pdev->dev));

View File

@@ -271,7 +271,7 @@ struct rx_video_info {
/*emp buffer config*/
#define DUMP_MODE_EMP 0
#define DUMP_MODE_TMDS 1
#define TMDS_BUFFER_SIZE 0x1e00000 /*30M*/
#define TMDS_BUFFER_SIZE 0x2000000 /*32M*/
#define EMP_BUFFER_SIZE 0x200000 /*2M*/
#define EMP_BUFF_MAX_PKT_CNT ((EMP_BUFFER_SIZE/2)/32 - 200)
#define TMDS_DATA_BUFFER_SIZE 0x200000

View File

@@ -974,10 +974,17 @@ return hdmirx_rd_top(TOP_HPD_PWR5V) & 0xf;
*/
unsigned int rx_get_scdc_clkrate_sts(void)
{
if (rx.chip_id == CHIP_ID_TXHD)
return 0;
else
return (hdmirx_rd_dwc(DWC_SCDC_REGS0) >> 17) & 1;
uint32_t clk_rate = 0;
if (rx.chip_id == CHIP_ID_TXHD)
return 0;
else {
if (force_clk_rate & 0x10)
clk_rate = force_clk_rate & 1;
else
clk_rate = (hdmirx_rd_dwc(DWC_SCDC_REGS0) >> 17) & 1;
}
return clk_rate;
}
/*
@@ -2130,6 +2137,7 @@ hdmirx_wr_dwc(DWC_SNPS_PHYG3_CTRL, data32);
void hdmirx_phy_init(void)
{
uint32_t data32;
uint32_t cur_cable_clk;
if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1) {
/* give default value */
@@ -2137,8 +2145,12 @@ void hdmirx_phy_init(void)
data32 |= rx.port << 2;
hdmirx_wr_dwc(DWC_SNPS_PHYG3_CTRL, data32);
aml_phy_bw_switch(rx_get_clock(TOP_HDMI_CABLECLK),
rx_get_scdc_clkrate_sts());/*100M,1:10*/
cur_cable_clk = rx_get_clock(TOP_HDMI_CABLECLK);
data32 = rx_get_scdc_clkrate_sts();
if (cur_cable_clk > 0)
aml_phy_bw_switch(cur_cable_clk, data32);
else
aml_phy_bw_switch(PHY_DEFAULT_FRQ, 0);
} else {
snps_phyg3_init();
}
@@ -2649,9 +2661,9 @@ void hdmirx_config_audio(void)
* tl1: have hdmi, cable clock
* other: have hdmi clock
*/
unsigned int rx_get_clock(enum measure_clk_top_e clk_src)
int rx_get_clock(enum measure_clk_top_e clk_src)
{
uint32_t clock = 0;
int clock = -1;
uint32_t tmp_data = 0;
uint32_t meas_cycles = 0;
uint64_t tmp_data2 = 0;
@@ -3177,7 +3189,6 @@ unsigned int aml_check_clk_bandwidth(unsigned int cableclk,
void aml_phy_init(unsigned int bw)
{
unsigned int data32;
static unsigned int cnt;
unsigned int term_value = 0x7;/*all terminal on*/
/* hdmirx_rd_top(TOP_HPD_PWR5V);*/
@@ -3187,13 +3198,13 @@ void aml_phy_init(unsigned int bw)
} else if (bw <= apll_bw_24_40) {
/* enable terminal connect */
data32 = 0x30034078|(term_value & 0x7);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
/* data channel and common block reset */
data32 |= 0xf << 7;
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
rx_pr("MISC_CNTL0=0x%x\n", data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02218000);/*en arc*/
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);/*360*/
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02218000);/*380*/
/* reset and select data port */
data32 = 0x00000010;
data32 |= ((1 << rx.port) << 6);
@@ -3212,169 +3223,166 @@ void aml_phy_init(unsigned int bw)
} else if (bw <= apll_bw_40_80) {
/* enable terminal connect */
data32 = 0x30034078|(term_value & 0x7);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
/* data channel and common block reset */
data32 |= 0xf << 7;
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
rx_pr("MISC_CNTL0=0x%x\n", data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02218000);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);/*360*/
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000);/*380*/
/* reset and select data port */
data32 = 0x00000010;
data32 |= ((1 << rx.port) << 6);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
/* release reset */
data32 |= (1 << 11);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
rx_pr("MISC_CNTL3=0x%x\n", data32);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000182);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a);
if (cnt & 0x1) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e020200);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e420200);
} else {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e060600);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e460600);
}
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x000002a2);/*388*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202);/*38c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126);/*390*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c714a);/*394*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);/*39c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);/*398*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);/*398*/
} else if (bw <= apll_bw_80_150) {
//phy default setting
/* enable terminal connect */
data32 = 0x30034078|(term_value & 0x7);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
/* data channel and common block reset */
data32 |= 0xf << 7;
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
rx_pr("MISC_CNTL0=0x%x\n", data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02218000);
/* reset and select data port */
data32 = 0x00000010;
data32 |= ((1 << rx.port) << 6);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
/* release reset */
data32 |= (1 << 11);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000222);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
if (cnt & 0x1) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e020200);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e420200);
} else {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e060600);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e460600);
}
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x000002a2);/*388*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x4800c202);/*38c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x01009126);/*390*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c714a);/*394*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);/*39c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);/*398*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);/*398*/
} else if (bw <= apll_bw_150_300) {
/* 3G */
/* enable terminal connect */
data32 = 0x30034078|(term_value & 0x7);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
/* data channel and common block reset */
data32 |= 0xf << 7;
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
rx_pr("MISC_CNTL0=0x%x\n", data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x00000080);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02218000);
/* reset and select data port */
data32 = 0x00000010;
data32 |= ((1 << rx.port) << 6);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
/* release reset */
data32 |= (1 << 11);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000042);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x0800c202);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x0100fc31);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x000a0000);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e040410);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e440410);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00120000);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00020000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x000002a2);/*388*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x0800c202);/*38c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x0100fc31);/*390*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c714a);/*394*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);/*39c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);/*398*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);/*398*/
} else {
/*6G*/
/* enable terminal connect */
data32 = 0x30034078|(term_value & 0x7);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
/* data channel and common block reset */
data32 |= 0xf << 7;
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL0, data32);/*35c*/
rx_pr("MISC_CNTL0=0x%x\n", data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL1, 0x007f0080);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL2, 0x02200000);
/* reset and select data port */
data32 = 0x00000010;
data32 |= ((1 << rx.port) << 6);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
/* release reset */
data32 |= (1 << 11);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);
wr_reg_hhi(HHI_HDMIRX_PHY_MISC_CNTL3, data32);/*384*/
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x351842a2);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x0700003c);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x1d00cc31);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c714a);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00180000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x351842a2);/*388*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x0700003c);/*38c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x1d00cc31);/*390*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c714a);/*394*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);/*39c*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e064640);/*398*/
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e464640);/*398*/
}
cnt++;
}
void aml_eq_setting(unsigned int bw)
{
unsigned int data32;
static uint32_t cnt;
if (bw == apll_bw_null) {
return;
} else if (bw <= apll_bw_24_40) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL0, 0x00000182);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL1, 0x2800c202);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHA_CNTL2, 0x010088a2);
#if 0
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL0, 0x002c733a);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e013130);
#endif
} else if (bw <= apll_bw_40_80) {
if (cnt & 0x1) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e022220);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e422220);
} else {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);
}
} else if (bw <= apll_bw_80_150) {
data32 = rd_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, data32);
/*reset*/
data32 = rd_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1);
data32 &= (~(1 << 24));
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, data32);
/*eq reset*/
data32 |= (1 << 24);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, data32);
if (cnt & 0x1) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e022220);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e422220);
} else {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);
}
} else if (bw <= apll_bw_150_300) {
if (cnt & 0x1) {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e022220);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e422220);
} else {
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00028000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e062620);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e462620);
}
} else {
/* 3G , 6G */
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x000a0000);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e040410);
udelay(5);
/*eq reset*/
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e440410);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00120000);
udelay(5);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00020000);
/* 6G */
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL2, 0x00018000);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e064640);
udelay(1);
wr_reg_hhi(HHI_HDMIRX_PHY_DCHD_CNTL1, 0x1e464640);
}
rx_pr("set eq >>>>>\n");
cnt++;
}
/*
@@ -3433,7 +3441,7 @@ void aml_phy_pll_setting(unsigned int bandwidth, unsigned int cable_clk)
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x20000000);
udelay(2);
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x30000000);
rx_pr("APLL_CNTL0 4c:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0));
rx_pr("APLL_CNTL0:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0));
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL1, 0x00000000);
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL2, 0x00001108);
data2 = 0x10058f30|od2;
@@ -3445,12 +3453,12 @@ void aml_phy_pll_setting(unsigned int bandwidth, unsigned int cable_clk)
udelay(2);
/*apll_vctrl_mon_en*/
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL4, data2|0x00800000);
rx_pr("APLL_CNTL4 50:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL4));
rx_pr("APLL_CNTL4:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL4));
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x34000000);
udelay(2);
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL0, data|0x14000000);
rx_pr("APLL_CNTL0 4c:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0));
rx_pr("APLL_CNTL0:0x%x\n", rd_reg_hhi(HHI_HDMIRX_APLL_CNTL0));
wr_reg_hhi(HHI_HDMIRX_APLL_CNTL2, 0x00003008);
@@ -3510,13 +3518,10 @@ void aml_phy_pw_onoff(unsigned int onoff)
/*
* aml phy initial
*/
void aml_phy_bw_switch(unsigned int cableclk_in, unsigned int clkrate)
void aml_phy_bw_switch(unsigned int cableclk, unsigned int clkrate)
{
unsigned int bw;
unsigned int cableclk = cableclk_in;
if (cableclk == 0)
cableclk = 100 * MHz;/*set a default clk*/
bw = aml_check_clk_bandwidth(cableclk, clkrate);
aml_phy_init(bw);
udelay(1);
@@ -3587,13 +3592,21 @@ void rx_emp_to_ddr_init(void)
if (rx.empbuff.pg_addr) {
rx_pr("rx_emp_to_ddr_init\n");
/* emp int enable */
/* config ddr buffer */
hdmirx_wr_top(TOP_EMP_DDR_START_A,
rx.empbuff.p_addr_a);
hdmirx_wr_top(TOP_EMP_DDR_START_B,
rx.empbuff.p_addr_b);
/*disable field done and last pkt interrupt*/
top_intr_maskn_value &= ~(1 << 25);
top_intr_maskn_value &= ~(1 << 26);
hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value);
if (rx.empbuff.p_addr_a) {
/* emp int enable */
/* config ddr buffer */
hdmirx_wr_top(TOP_EMP_DDR_START_A,
rx.empbuff.p_addr_a);
hdmirx_wr_top(TOP_EMP_DDR_START_B,
rx.empbuff.p_addr_b);
}
#if 0
/* instead by clk tree */
data = 0;
/*[10: 9] HDMIRX AXI clock mux select: fclk_div3=667MHz*/
data |= (2 << 9);
@@ -3637,7 +3650,7 @@ void rx_emp_to_ddr_init(void)
rx.empbuff.ready = NULL;
rx.empbuff.irqcnt = 0;
rx.empbuff.emppktcnt = 0;
rx.empbuff.tmdspktcnt = 0;
rx.empbuff.tmdspktcnt = 720*480;
}
void rx_emp_field_done_irq(void)
@@ -3731,13 +3744,17 @@ void rx_tmds_to_ddr_init(void)
{
unsigned int data, data2;
unsigned int i = 0;
unsigned char *src_v_addr;
if (rx.hdmirxdev->data->chip_id != CHIP_ID_TL1)
return;
if (rx.empbuff.pg_addr) {
rx_pr("rx_tmds_to_ddr_init\n");
/*disable field done and last pkt interrupt*/
top_intr_maskn_value &= ~(1 << 25);
top_intr_maskn_value &= ~(1 << 26);
hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value);
/* disable emp rev */
data = hdmirx_rd_top(TOP_EMP_CNTL_1);
data &= ~0x1;
@@ -3754,22 +3771,20 @@ void rx_tmds_to_ddr_init(void)
break;
}
}
/* config ddr buffer */
hdmirx_wr_top(TOP_EMP_DDR_START_A,
rx.empbuff.p_addr_a);
if (rx.empbuff.p_addr_a) {
/* config ddr buffer */
hdmirx_wr_top(TOP_EMP_DDR_START_A,
rx.empbuff.p_addr_a);
hdmirx_wr_top(TOP_EMP_DDR_START_B,
rx.empbuff.p_addr_a);
}
/* max pkt count to avoid buffer overflow */
/* one frame size: HxVx3x1.25 bytes */
/* one pixel 4bytes */
data = ((rx.empbuff.tmdspktcnt/8) * 8) - 1;
hdmirx_wr_top(TOP_EMP_CNTMAX, data);
rx_pr("pkt max cnt limit=0x%x\n", data);
/* clean hw buffer */
/* p addr to v addr for cpu access */
src_v_addr = phys_to_virt(rx.empbuff.p_addr_a);
memset(src_v_addr, 0, TMDS_BUFFER_SIZE);
data = 0;
data |= 0xf << 16;/*[23:16] hs_beat_rate=0xf */
/*[14] buffer_info_mode=0 */
@@ -3807,9 +3822,38 @@ void rx_emp_lastpkt_done_irq(void)
/*need capture data*/
rx_pr("lastpkt_done_irq\n");
rx_pr(">> lastpkt_done_irq >\n");
}
void rx_emp_capture_stop(void)
{
unsigned int i = 0, data, data2;
/*disable field done and last pkt interrupt*/
top_intr_maskn_value &= ~(1 << 25);
top_intr_maskn_value &= ~(1 << 26);
hdmirx_wr_top(TOP_INTR_MASKN, top_intr_maskn_value);
/* disable emp rev */
data = hdmirx_rd_top(TOP_EMP_CNTL_1);
data &= ~0x1;
hdmirx_wr_top(TOP_EMP_CNTL_1, data);
/* wait until emp finish */
data2 = hdmirx_rd_top(TOP_EMP_STAT_0) & 0x7fffffff;
data = hdmirx_rd_top(TOP_EMP_STAT_1);
while (data2 || data) {
mdelay(1);
data2 = hdmirx_rd_top(TOP_EMP_STAT_0) & 0x7fffffff;
data = hdmirx_rd_top(TOP_EMP_STAT_1);
if (i++ > 100) {
rx_pr("warning: wait emp timeout\n");
break;
}
}
rx_pr("emp capture stop\n");
}
/*
* get hdmi data error counter
* for tl1

View File

@@ -18,8 +18,6 @@
#ifndef __HDMI_RX_HW_H__
#define __HDMI_RX_HW_H__
/*#define K_BRINGUP_PTM*/
#define K_TEST_CHK_ERR_CNT
/**
@@ -1225,9 +1223,12 @@ enum measure_clk_src_e {
MEASURE_CLK_ESM,
};
#define MHz 1000000
#define KHz 1000
#define PHY_DEFAULT_FRQ ((100)*MHz)
enum apllbw {
apll_bw_24_40 = 0,
apll_bw_40_80,
@@ -1248,7 +1249,7 @@ struct apll_param {
unsigned int od2_div;
};
extern unsigned int rx_get_clock(enum measure_clk_top_e clk_src);
extern int rx_get_clock(enum measure_clk_top_e clk_src);
extern unsigned int clk_util_clk_msr(unsigned int clk_mux);
extern unsigned int rx_measure_clock(enum measure_clk_src_e clksrc);
extern void aml_phy_init(unsigned int bw);
@@ -1259,11 +1260,13 @@ extern void aml_sw_apll(unsigned int bandwidth, unsigned int cableclk);
extern void aml_phy_bw_switch(unsigned int cableclk, unsigned int clkrate);
extern unsigned int aml_phy_pll_lock(void);
extern unsigned int aml_phy_tmds_valid(void);
extern void aml_eq_setting(unsigned int bw);
extern void rx_emp_to_ddr_init(void);
extern void rx_emp_field_done_irq(void);
extern void rx_emp_status(void);
extern void rx_emp_lastpkt_done_irq(void);
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);
#endif

View File

@@ -91,6 +91,7 @@ static int err_dbg_cnt_max = 500;
#endif
int force_vic;
uint32_t fsm_log_en;
uint32_t err_chk_en;
static int aud_sr_stb_max = 20;
@@ -1746,6 +1747,8 @@ int rx_set_global_variable(const char *buf, int size)
return pr_var(ignore_sscp_tmds, index);
if (set_pr_var(tmpbuf, fsm_log_en, value, &index, ret))
return pr_var(fsm_log_en, index);
if (set_pr_var(tmpbuf, err_chk_en, value, &index, ret))
return pr_var(err_chk_en, index);
if (set_pr_var(tmpbuf, hdcp_enc_mode, value, &index, ret))
return pr_var(hdcp_enc_mode, index);
return 0;
@@ -1853,6 +1856,7 @@ void rx_get_global_variable(const char *buf)
pr_var(ignore_sscp_charerr, i++);
pr_var(ignore_sscp_tmds, i++);
pr_var(fsm_log_en, i++);
pr_var(err_chk_en, i++);
pr_var(hdcp_enc_mode, i++);
}
@@ -2010,31 +2014,31 @@ void rx_5v_monitor(void)
*/
void rx_clk_rate_monitor(void)
{
unsigned int cur_cable_clk;
int cur_cable_clk;
unsigned int clk_diff;
unsigned int cur_phy_bw, i = 0;
static unsigned int phy_bw_cnt;
unsigned int cur_clk_rate;
#ifdef K_BRINGUP_PTM
return;
#endif
/*cur_cable_clk = rx_measure_clock(MEASURE_CLK_CABLE);*/
cur_cable_clk = rx_get_clock(TOP_HDMI_CABLECLK);
if (cur_cable_clk < 0)
return;
clk_diff = diff(rx.physts.cable_clk, cur_cable_clk);
cur_clk_rate = rx_get_scdc_clkrate_sts();
cur_phy_bw = aml_check_clk_bandwidth(cur_cable_clk, cur_clk_rate);
if ((rx.cur_5v_sts) && ((rx.physts.phy_bw != cur_phy_bw) ||
(rx.physts.clk_rate != cur_clk_rate) ||
(clk_diff > (1000 * KHz)))) {
(clk_diff > (1000*KHz)))) {
if (phy_bw_cnt++ > 1) {
phy_bw_cnt = 0;
while (i++ < 3) {
rx_pr("chg phy i=%d, cabclk:%d, clkrate:%d\n",
i, cur_cable_clk, cur_clk_rate);
aml_phy_bw_switch(cur_cable_clk, cur_clk_rate);
udelay(50);/*wait pll lock*/
if ((cur_cable_clk < (20 * MHz)) ||
aml_phy_pll_lock())
break;
@@ -2069,8 +2073,8 @@ void rx_monitor_error_counter(void)
return;
timestap = get_seconds();
if ((timestap - rx.physts.timestap) < 60) {
if ((timestap - rx.physts.timestap) > 1) {
rx.physts.timestap = timestap;
rx_get_error_cnt(&ch0, &ch1, &ch2);
if (ch0 || ch1 || ch2)
rx_pr("err cnt:%d,%d,%d\n", ch0, ch1, ch2);
@@ -2160,6 +2164,7 @@ char *fsm_st[] = {
void rx_main_state_machine(void)
{
int pre_auds_ch_alloc;
uint32_t ch0, ch1, ch2;
if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1)
rx_clk_rate_monitor();
@@ -2177,6 +2182,7 @@ void rx_main_state_machine(void)
break;
case FSM_INIT:
signal_status_init();
rx.physts.cable_clk = 0;
rx.state = FSM_HPD_HIGH;
break;
case FSM_HPD_HIGH:
@@ -2196,6 +2202,7 @@ void rx_main_state_machine(void)
downstream_hpd_flag = 0;
pre_port = rx.port;
rx_set_cur_hpd(1);
rx.physts.cable_clk = 0;
set_scdc_cfg(0, 1);
/* rx.hdcp.hdcp_version = HDCP_VER_NONE; */
rx.state = FSM_WAIT_CLK_STABLE;
@@ -2207,7 +2214,11 @@ void rx_main_state_machine(void)
clk_unstable_cnt = 0;
}
if (++clk_stable_cnt > clk_stable_max) {
rx.state = FSM_EQ_START;
/* for tl1 no SW eq */
if (rx.hdmirxdev->data->chip_id == CHIP_ID_TL1)
rx.state = FSM_SIG_UNSTABLE;/*no sw eq*/
else
rx.state = FSM_EQ_START;
clk_stable_cnt = 0;
rx.err_code = ERR_NONE;
}
@@ -2225,6 +2236,7 @@ void rx_main_state_machine(void)
*/
if (esd_phy_rst_cnt < esd_phy_rst_max) {
hdmirx_phy_init();
rx.physts.cable_clk = 0;
esd_phy_rst_cnt++;
}
rx.err_code = ERR_CLK_UNSTABLE;
@@ -2260,12 +2272,14 @@ void rx_main_state_machine(void)
/* pll unlock after ESD test, phy does't
* work well, do phy reset twice at most.
*/
if (esd_phy_rst_cnt++ < esd_phy_rst_max)
if (esd_phy_rst_cnt++ < esd_phy_rst_max) {
hdmirx_phy_init();
else
rx.physts.cable_clk = 0;
} else
rx.err_rec_mode = ERR_REC_HPD_RST;
} else if (rx.err_rec_mode == ERR_REC_HPD_RST) {
rx_set_cur_hpd(0);
rx.physts.cable_clk = 0;
rx.state = FSM_HPD_HIGH;
rx.err_rec_mode = ERR_REC_END;
} else {
@@ -2320,6 +2334,16 @@ void rx_main_state_machine(void)
dvi_check_en = false;
break;
}
if (rx.hdmirxdev->data->chip_id
== CHIP_ID_TL1) {
rx_get_error_cnt(&ch0, &ch1, &ch2);
if (ch0 || ch1 || ch2) {
rx_pr("have err cnt\n");
aml_phy_bw_switch(
rx.physts.cable_clk,
rx.physts.clk_rate);
}
}
rx.skip = 0;
rx.state = FSM_SIG_READY;
rx.aud_sr_stable_cnt = 0;
@@ -2353,6 +2377,7 @@ void rx_main_state_machine(void)
rx_set_eq_run_state(E_EQ_START);
} else if (rx.err_rec_mode == ERR_REC_HPD_RST) {
rx_set_cur_hpd(0);
rx.physts.cable_clk = 0;
rx.state = FSM_HPD_HIGH;
rx.err_rec_mode = ERR_REC_END;
} else
@@ -2388,6 +2413,7 @@ void rx_main_state_machine(void)
rx.skip = 0;
rx.aud_sr_stable_cnt = 0;
rx.aud_sr_unstable_cnt = 0;
rx.physts.cable_clk = 0;
esd_phy_rst_cnt = 0;
if (hdcp22_on) {
esm_set_stable(false);
@@ -2437,6 +2463,8 @@ void rx_main_state_machine(void)
if (aud_sts == E_REQUESTCLK_ERR) {
hdmirx_phy_init();
rx.state = FSM_WAIT_CLK_STABLE;
/*timing sw at same FRQ*/
rx.physts.cable_clk = 0;
/*rx.pre_state = FSM_SIG_READY;*/
rx_pr("reqclk err->wait_clk\n");
} else if (aud_sts == E_PLLRATE_CHG)
@@ -3245,22 +3273,27 @@ int hdmirx_debug(const char *buf, int size)
} else if (strncmp(input[0], "empsts", 6) == 0) {
rx_emp_status();
} else if (strncmp(input[0], "empstart", 8) == 0) {
rx_emp_capture_stop();
rx_emp_resource_allocate(hdmirx_dev);
rx_emp_to_ddr_init();
} else if (strncmp(input[0], "tmdsstart", 9) == 0) {
rx_emp_capture_stop();
rx_tmds_resource_allocate(hdmirx_dev);
rx_tmds_to_ddr_init();
} else if (strncmp(input[0], "empcapture", 10) == 0) {
rx_emp_data_capture();
} else if (strncmp(input[0], "tmdcapture", 11) == 0) {
} else if (strncmp(input[0], "tmdscapture", 11) == 0) {
rx_tmds_data_capture();
} else if (strncmp(input[0], "phyinit", 7) == 0) {
aml_phy_bw_switch(rx_get_clock(TOP_HDMI_CABLECLK),
rx_get_scdc_clkrate_sts());
} else if (strncmp(input[0], "tmdscnt", 7) == 0) {
if (kstrtol(input[1], 16, &value) < 0)
rx_pr("error input Value\n");
rx_pr("set pkt cnt:0x%x\n", value);
rx.empbuff.emppktcnt = value;
rx.empbuff.tmdspktcnt = value;
} else if (strncmp(input[0], "phyinit", 7) == 0) {
aml_phy_bw_switch(rx_get_clock(TOP_HDMI_CABLECLK),
rx_get_scdc_clkrate_sts());
} else if (strncmp(input[0], "phyeq", 5) == 0) {
aml_eq_setting(rx.physts.phy_bw);
} else if (strncmp(tmpbuf, "audio", 5) == 0) {
hdmirx_audio_fifo_rst();
}
@@ -3284,6 +3317,11 @@ void hdmirx_timer_handler(unsigned long arg)
rx_err_monitor();
rx_clkrate_monitor();
#endif
#ifdef K_TEST_CHK_ERR_CNT
if (err_chk_en || (rx.state != FSM_SIG_READY))
rx_monitor_error_counter();
#endif
}
}
devp->timer.expires = jiffies + TIMER_STATE_CHECK;