hdmitx: update phy/clk parameters
authorZongdong Jiao <zongdong.jiao@amlogic.com>
Mon, 12 Mar 2018 13:56:27 +0000 (21:56 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Thu, 15 Mar 2018 06:39:48 +0000 (22:39 -0800)
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 <zongdong.jiao@amlogic.com>
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_clk.c
drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hw_g12a.c

index 3154df3..1cae83c 100644 (file)
@@ -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;
index ddeeeaa..94c064c 100644 (file)
@@ -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},
index 48d9b55..4fb43bb 100644 (file)
 #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)
 
 #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;