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)
committerMaxime Ripard <maxime.ripard@bootlin.com>
Thu, 16 May 2019 08:44:52 +0000 (10:44 +0200)
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
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c

index 66ea3a9..afc6d4a 100644 (file)
@@ -672,22 +672,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);
@@ -708,18 +699,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: