drm/rockchip: hdmi: correct 3328 hdmi phy power up timing
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 13 Jun 2017 02:39:00 +0000 (10:39 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 15 Jun 2017 08:13:52 +0000 (16:13 +0800)
According to spec, TMDS driver should power up between PLL
power up and PLL lock.

There is an mistake of pdata en register, the real register
is reg2 bit0, not reg1 bit0.

Change-Id: I9d2b707cbcfd70b63f4a1a277a85f21b62643d2e
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c

index 8c67659da74389f50070e7b2af2cedc91c75d05c..943ed89fcfd422de1c2830060d09782cd5ea0ba9 100644 (file)
@@ -254,7 +254,7 @@ inno_dw_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data,
                return -EINVAL;
 
        /* set pdata_en to 0 */
-       inno_phy_modeb(hdmi, 0, 1, 0x01);
+       inno_phy_modeb(hdmi, 0, 1, 0x02);
        /* Power off post PLL */
        inno_phy_modeb(hdmi, 1, 1, 0xaa);
 
@@ -273,14 +273,6 @@ inno_dw_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data,
                inno_phy_writel(hdmi, 0xab, val);
                inno_phy_writel(hdmi, 0xaa, 0x0e);
        }
-       /* Power up post PLL */
-       inno_phy_modeb(hdmi, 0, 1, 0xaa);
-       /* Wait for post PLL lock */
-       for (i = 0; i < 5; ++i) {
-               if (inno_phy_readl(hdmi, 0xaf) & 1)
-                       break;
-               usleep_range(1000, 2000);
-       }
 
        for (i = 0; i < 14; i++)
                inno_phy_writel(hdmi, 0xb5 + i, inno_phy_config->regs[i]);
@@ -317,13 +309,26 @@ inno_dw_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data,
                inno_phy_writel(hdmi, 0xc5, 0x81);
        }
 
-       if (inno_phy_config->tmdsclock > 340000000)
-               msleep(100);
-
+       /* Power up post PLL */
+       inno_phy_modeb(hdmi, 0, 1, 0xaa);
+       /* Power up tmds driver */
        inno_phy_modeb(hdmi, 4, 4, 0xb0);
        inno_phy_writel(hdmi, 0xb2, 0x0f);
+
+       /* Wait for post PLL lock */
+       for (i = 0; i < 5; ++i) {
+               if (inno_phy_readl(hdmi, 0xaf) & 1)
+                       break;
+               usleep_range(1000, 2000);
+       }
+       if (!(inno_phy_readl(hdmi, 0xaf) & 1)) {
+               dev_err(hdmi->dev, "HDMI PHY Post PLL unlock\n");
+               return -ETIMEDOUT;
+       }
+       if (inno_phy_config->tmdsclock > 340000000)
+               msleep(100);
        /* set pdata_en to 1 */
-       inno_phy_modeb(hdmi, 1, 1, 0x01);
+       inno_phy_modeb(hdmi, 1, 1, 0x02);
        return 0;
 }
 
@@ -386,7 +391,7 @@ static int inno_dw_hdmi_phy_is_prepared(struct clk_hw *hw)
 
 static unsigned long
 inno_dw_hdmi_phy_pll_recalc_rate(struct clk_hw *hw,
-                                 unsigned long parent_rate)
+                                unsigned long parent_rate)
 {
        struct rockchip_hdmi *hdmi =
                container_of(hw, struct rockchip_hdmi, hdmiphy_clkhw);