From fb83d82f3475c5f8c5fa6145e5584c87c9990d26 Mon Sep 17 00:00:00 2001 From: Zongdong Jiao Date: Mon, 12 Mar 2018 21:56:27 +0800 Subject: [PATCH] hdmitx: update phy/clk parameters PD#160984: hdmitx: update phy/clk parameters of g12a 1. use 5.94G instead of 2.97G to get high performance 2. add workaround of setting 4.5~6GHz 3. fine tune phy parameters Change-Id: I99a7bb428e835316bd464aae421e074841156670 Signed-off-by: Zongdong Jiao --- .../media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c | 16 +-- .../media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c | 16 +-- .../media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c | 141 +++++++++++++++------ 3 files changed, 115 insertions(+), 58 deletions(-) diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 3154df3..1cae83c 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -1667,21 +1667,21 @@ static void set_phy_by_mode(unsigned int mode) switch (hdev->chip_type) { case MESON_CPU_ID_G12A: switch (mode) { - case 1: /* 5.94Gbps, 3.7125Gbsp */ + case 1: /* 5.94/4.5/3.7Gbps */ hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb65c4); hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); - hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x080b); + hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0000080b); break; case 2: /* 2.97Gbps */ - hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb8282); - hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x28b0ff3b); - hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x0800); + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262); + hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003); break; case 3: /* 1.485Gbps, and below */ default: - hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x37eb8282); - hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x28b0ff3b); - hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0); + hd_write_reg(P_HHI_HDMI_PHY_CNTL0, 0x33eb6262); + hd_write_reg(P_HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hd_write_reg(P_HHI_HDMI_PHY_CNTL5, 0x00000003); break; } break; diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c index ddeeeaa..94c064c 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c @@ -700,20 +700,20 @@ static struct hw_enc_clk_val_group setting_enc_clk_val_24[] = { {{HDMI_1280x720p50_16x9, HDMI_1280x720p60_16x9, HDMI_VIC_END}, - 2970000, 4, 1, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, + 5940000, 4, 2, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, {{HDMI_1920x1080i60_16x9, HDMI_1920x1080i50_16x9, HDMI_VIC_END}, - 2970000, 4, 1, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, + 5940000, 4, 2, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, {{HDMI_1920x1080p60_16x9, HDMI_1920x1080p50_16x9, HDMI_VIC_END}, - 2970000, 1, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, + 5940000, 4, 1, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, {{HDMI_1920x1080p30_16x9, HDMI_1920x1080p24_16x9, HDMI_1920x1080p25_16x9, HDMI_VIC_END}, - 2970000, 2, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, + 5940000, 4, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, {{HDMI_3840x2160p30_16x9, HDMI_3840x2160p25_16x9, HDMI_3840x2160p24_16x9, @@ -721,7 +721,7 @@ static struct hw_enc_clk_val_group setting_enc_clk_val_24[] = { HDMI_4096x2160p25_256x135, HDMI_4096x2160p30_256x135, HDMI_VIC_END}, - 2970000, 1, 1, 1, VID_PLL_DIV_5, 2, 1, 1, -1}, + 5940000, 2, 1, 1, VID_PLL_DIV_5, 2, 1, 1, -1}, {{HDMI_3840x2160p60_16x9, HDMI_3840x2160p50_16x9, HDMI_4096x2160p60_256x135, @@ -733,7 +733,7 @@ static struct hw_enc_clk_val_group setting_enc_clk_val_24[] = { HDMI_3840x2160p60_16x9_Y420, HDMI_3840x2160p50_16x9_Y420, HDMI_VIC_END}, - 2970000, 1, 1, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, + 5940000, 2, 1, 1, VID_PLL_DIV_5, 1, 2, 1, -1}, {{HDMI_VIC_FAKE, HDMI_VIC_END}, 3450000, 1, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, @@ -839,14 +839,14 @@ static struct hw_enc_clk_val_group setting_3dfp_enc_clk_val[] = { {{HDMI_1920x1080p60_16x9, HDMI_1920x1080p50_16x9, HDMI_VIC_END}, - 2970000, 1, 1, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, + 5940000, 2, 1, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, {{HDMI_1280x720p50_16x9, HDMI_1280x720p60_16x9, HDMI_1920x1080p30_16x9, HDMI_1920x1080p24_16x9, HDMI_1920x1080p25_16x9, HDMI_VIC_END}, - 2970000, 1, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, + 5940000, 2, 2, 2, VID_PLL_DIV_5, 1, 1, 1, -1}, /* NO 2160p mode*/ {{HDMI_VIC_FAKE, HDMI_VIC_END}, diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c index 48d9b55..4fb43bb 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c @@ -54,21 +54,22 @@ #undef WAIT_FOR_PLL_LOCKED #endif -#define WAIT_FOR_PLL_LOCKED(reg) \ - do { \ - unsigned int st = 0, cnt = 10; \ - while (cnt--) { \ - udelay(50); \ - st = !!(hd_read_reg(reg) & (1 << 31)); \ - if (st) \ - break; \ - else { \ - /* reset hpll */ \ - hd_set_reg_bits(reg, 1, 29, 1); \ - hd_set_reg_bits(reg, 0, 29, 1); \ - } \ - } \ - if (cnt < 9) \ +#define WAIT_FOR_PLL_LOCKED(reg) \ + do { \ + unsigned int st = 0; \ + int cnt = 10; \ + while (cnt--) { \ + udelay(50); \ + st = (((hd_read_reg(reg) >> 30) & 0x3) == 3); \ + if (st) \ + break; \ + else { \ + /* reset hpll */ \ + hd_set_reg_bits(reg, 1, 29, 1); \ + hd_set_reg_bits(reg, 0, 29, 1); \ + } \ + } \ + if (cnt < 9) \ pr_info("pll[0x%x] reset %d times\n", reg, 9 - cnt);\ } while (0) @@ -82,23 +83,79 @@ #define P_HHI_HDMI_PLL_CNTL6 HHI_REG_ADDR(0xce) #define P_HHI_HDMI_PLL_STS HHI_REG_ADDR(0xcf) +/* + * When VCO outputs 6.0 GHz, if VCO unlock with default v1 + * steps, then need reset with v2 or v3 + */ +static bool set_hpll_hclk_v1(unsigned int m, unsigned int frac_val) +{ + int ret = 0; + + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b3a0400 | (m & 0xff)); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, frac_val); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a29dc00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLLv1: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + + ret = (((hd_read_reg(P_HHI_HDMI_PLL_CNTL0) >> 30) & 0x3) == 0x3); + return ret; /* return hpll locked status */ +} + +static bool set_hpll_hclk_v2(unsigned int m, unsigned int frac_val) +{ + int ret = 0; + + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b3a0400 | (m & 0xff)); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, frac_val); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0xeaa9dc00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x95771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x55540028); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLLv2: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + + ret = (((hd_read_reg(P_HHI_HDMI_PLL_CNTL0) >> 30) & 0x3) == 0x3); + return ret; /* return hpll locked status */ +} + +static bool set_hpll_hclk_v3(unsigned int m, unsigned int frac_val) +{ + int ret = 0; + + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b3a0400 | (m & 0xff)); + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, frac_val); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0xea29dc00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x55540000); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLLv3: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + + ret = (((hd_read_reg(P_HHI_HDMI_PLL_CNTL0) >> 30) & 0x3) == 0x3); + return ret; /* return hpll locked status */ +} + void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk) { switch (clk) { case 5940000: - hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b3a04f7); - if (frac_rate) - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00008168); + if (set_hpll_hclk_v1(0xf7, frac_rate ? 0x8168 : 0x10000)) + break; + else if (set_hpll_hclk_v2(0x7b, frac_rate ? 0x140b4 : 0x18000)) + break; + else if (set_hpll_hclk_v3(0xf7, frac_rate ? 0x8168 : 0x10000)) + break; else - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00010000); - hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); - hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x2a29dc00); - hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x65771290); - hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39272000); - hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); - hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); - WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); - pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + break; break; case 5405400: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004e1); @@ -130,6 +187,21 @@ void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk) WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); break; + case 4324320: + hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004b4); + if (frac_rate) + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00000000); + else + hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00005c29); + hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); + hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); + hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39270000); + hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); + hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); + WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); + pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); + break; case 3712500: hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b00049a); if (frac_rate) @@ -187,21 +259,6 @@ void set_g12a_hpll_clk_out(unsigned int frac_rate, unsigned int clk) WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); break; - case 4324320: - hd_write_reg(P_HHI_HDMI_PLL_CNTL0, 0x3b0004b4); - if (frac_rate) - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00000000); - else - hd_write_reg(P_HHI_HDMI_PLL_CNTL1, 0x00005c29); - hd_write_reg(P_HHI_HDMI_PLL_CNTL2, 0x00000000); - hd_write_reg(P_HHI_HDMI_PLL_CNTL3, 0x0a691c00); - hd_write_reg(P_HHI_HDMI_PLL_CNTL4, 0x33771290); - hd_write_reg(P_HHI_HDMI_PLL_CNTL5, 0x39270000); - hd_write_reg(P_HHI_HDMI_PLL_CNTL6, 0x50540000); - hd_set_reg_bits(P_HHI_HDMI_PLL_CNTL0, 0x0, 29, 1); - WAIT_FOR_PLL_LOCKED(P_HHI_HDMI_PLL_CNTL0); - pr_info("HPLL: 0x%x\n", hd_read_reg(P_HHI_HDMI_PLL_CNTL0)); - break; default: pr_info("error hpll clk: %d\n", clk); break; -- 2.7.4