From: Zheng Yang Date: Tue, 13 Jun 2017 02:39:00 +0000 (+0800) Subject: drm/rockchip: hdmi: correct 3328 hdmi phy power up timing X-Git-Tag: release-20171130_firefly~4^2~400 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6d2995671209da44883fa8e8def28103cfd26143;p=firefly-linux-kernel-4.4.55.git drm/rockchip: hdmi: correct 3328 hdmi phy power up timing 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 --- diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 8c67659da743..943ed89fcfd4 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -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);