drm/sun4i: Fix sun8i HDMI PHY clock initialization
authorJernej Skrabec <jernej.skrabec@siol.net>
Tue, 14 May 2019 20:43:36 +0000 (22:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Jun 2019 07:17:22 +0000 (09:17 +0200)
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

index a564b5d..be60518 100644 (file)
@@ -501,22 +501,13 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
                                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_hdmi *hdmi, struct device_node *node)
                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: