| From 8a943c6021ba8b95a36c842327e468df1fddd4a7 Mon Sep 17 00:00:00 2001 |
| From: Jernej Skrabec <jernej.skrabec@siol.net> |
| Date: Tue, 14 May 2019 22:43:36 +0200 |
| Subject: drm/sun4i: Fix sun8i HDMI PHY clock initialization |
| |
| From: Jernej Skrabec <jernej.skrabec@siol.net> |
| |
| commit 8a943c6021ba8b95a36c842327e468df1fddd4a7 upstream. |
| |
| Current code initializes HDMI PHY clock driver before reset line is |
| deasserted and clocks enabled. Because of that, initial readout of |
| clock divider is incorrect (0 instead of 2). This causes any clock |
| rate with divider 1 (register value 0) to be set incorrectly. |
| |
| Fix this by moving initialization of HDMI PHY clock driver after reset |
| line is deasserted and clocks enabled. |
| |
| Cc: stable@vger.kernel.org # 4.17+ |
| Fixes: 4f86e81748fe ("drm/sun4i: Add support for H3 HDMI PHY variant") |
| Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> |
| Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20190514204337.11068-2-jernej.skrabec@siol.net |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 26 ++++++++++++++------------ |
| 1 file changed, 14 insertions(+), 12 deletions(-) |
| |
| --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |
| +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c |
| @@ -501,22 +501,13 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw |
| goto err_put_clk_pll0; |
| } |
| } |
| - |
| - ret = sun8i_phy_clk_create(phy, dev, |
| - phy->variant->has_second_pll); |
| - if (ret) { |
| - dev_err(dev, "Couldn't create the PHY clock\n"); |
| - goto err_put_clk_pll1; |
| - } |
| - |
| - clk_prepare_enable(phy->clk_phy); |
| } |
| |
| phy->rst_phy = of_reset_control_get_shared(node, "phy"); |
| if (IS_ERR(phy->rst_phy)) { |
| dev_err(dev, "Could not get phy reset control\n"); |
| ret = PTR_ERR(phy->rst_phy); |
| - goto err_disable_clk_phy; |
| + goto err_put_clk_pll1; |
| } |
| |
| ret = reset_control_deassert(phy->rst_phy); |
| @@ -537,18 +528,29 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw |
| goto err_disable_clk_bus; |
| } |
| |
| + if (phy->variant->has_phy_clk) { |
| + ret = sun8i_phy_clk_create(phy, dev, |
| + phy->variant->has_second_pll); |
| + if (ret) { |
| + dev_err(dev, "Couldn't create the PHY clock\n"); |
| + goto err_disable_clk_mod; |
| + } |
| + |
| + clk_prepare_enable(phy->clk_phy); |
| + } |
| + |
| hdmi->phy = phy; |
| |
| return 0; |
| |
| +err_disable_clk_mod: |
| + clk_disable_unprepare(phy->clk_mod); |
| err_disable_clk_bus: |
| clk_disable_unprepare(phy->clk_bus); |
| err_deassert_rst_phy: |
| reset_control_assert(phy->rst_phy); |
| err_put_rst_phy: |
| reset_control_put(phy->rst_phy); |
| -err_disable_clk_phy: |
| - clk_disable_unprepare(phy->clk_phy); |
| err_put_clk_pll1: |
| clk_put(phy->clk_pll1); |
| err_put_clk_pll0: |