aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-08-03 08:23:29 -0400
committerThierry Reding <treding@nvidia.com>2016-07-01 08:42:01 -0400
commit25bb2cec88401a512c01adc8b815f8a579da2558 (patch)
treef8d68ae61a35be1c4af1d2308a0e257c4573efbf
parent0751bb5c44fe1aa9494ce259d974c3d249b73a84 (diff)
drm/tegra: sor: Factor out tegra_sor_set_parent_clock()
Switching the SOR parent clock can glitch if done while the clock is enabled. Extract a common function that can be used to disable the module clock, switch the parent and reenable the module clock. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/sor.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 757c6e8603af..ed03a1f5b692 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -225,6 +225,23 @@ static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,
225 writel(value, sor->regs + (offset << 2)); 225 writel(value, sor->regs + (offset << 2));
226} 226}
227 227
228static int tegra_sor_set_parent_clock(struct tegra_sor *sor, struct clk *parent)
229{
230 int err;
231
232 clk_disable_unprepare(sor->clk);
233
234 err = clk_set_parent(sor->clk, parent);
235 if (err < 0)
236 return err;
237
238 err = clk_prepare_enable(sor->clk);
239 if (err < 0)
240 return err;
241
242 return 0;
243}
244
228static int tegra_sor_dp_train_fast(struct tegra_sor *sor, 245static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
229 struct drm_dp_link *link) 246 struct drm_dp_link *link)
230{ 247{
@@ -733,7 +750,8 @@ static int tegra_sor_power_down(struct tegra_sor *sor)
733 if ((value & SOR_PWR_TRIGGER) != 0) 750 if ((value & SOR_PWR_TRIGGER) != 0)
734 return -ETIMEDOUT; 751 return -ETIMEDOUT;
735 752
736 err = clk_set_parent(sor->clk, sor->clk_safe); 753 /* switch to safe parent clock */
754 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
737 if (err < 0) 755 if (err < 0)
738 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 756 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
739 757
@@ -1219,7 +1237,8 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1219 return; 1237 return;
1220 } 1238 }
1221 1239
1222 err = clk_set_parent(sor->clk, sor->clk_safe); 1240 /* switch to safe parent clock */
1241 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
1223 if (err < 0) 1242 if (err < 0)
1224 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1243 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
1225 1244
@@ -1326,10 +1345,10 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1326 value &= ~SOR_PLL2_PORT_POWERDOWN; 1345 value &= ~SOR_PLL2_PORT_POWERDOWN;
1327 tegra_sor_writel(sor, value, SOR_PLL2); 1346 tegra_sor_writel(sor, value, SOR_PLL2);
1328 1347
1329 /* switch to DP clock */ 1348 /* switch to DP parent clock */
1330 err = clk_set_parent(sor->clk, sor->clk_dp); 1349 err = tegra_sor_set_parent_clock(sor, sor->clk_dp);
1331 if (err < 0) 1350 if (err < 0)
1332 dev_err(sor->dev, "failed to set DP parent clock: %d\n", err); 1351 dev_err(sor->dev, "failed to set parent clock: %d\n", err);
1333 1352
1334 /* power DP lanes */ 1353 /* power DP lanes */
1335 value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 1354 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
@@ -1781,7 +1800,8 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
1781 1800
1782 reset_control_deassert(sor->rst); 1801 reset_control_deassert(sor->rst);
1783 1802
1784 err = clk_set_parent(sor->clk, sor->clk_safe); 1803 /* switch to safe parent clock */
1804 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
1785 if (err < 0) 1805 if (err < 0)
1786 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1806 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
1787 1807
@@ -1892,7 +1912,8 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
1892 1912
1893 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL); 1913 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
1894 1914
1895 err = clk_set_parent(sor->clk, sor->clk_parent); 1915 /* switch to parent clock */
1916 err = tegra_sor_set_parent_clock(sor, sor->clk_parent);
1896 if (err < 0) 1917 if (err < 0)
1897 dev_err(sor->dev, "failed to set parent clock: %d\n", err); 1918 dev_err(sor->dev, "failed to set parent clock: %d\n", err);
1898 1919