Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+28 -7
+28 -7
drivers/gpu/drm/tegra/sor.c
··· 225 225 writel(value, sor->regs + (offset << 2)); 226 226 } 227 227 228 + static 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 + 228 245 static int tegra_sor_dp_train_fast(struct tegra_sor *sor, 229 246 struct drm_dp_link *link) 230 247 { ··· 750 733 if ((value & SOR_PWR_TRIGGER) != 0) 751 734 return -ETIMEDOUT; 752 735 753 - err = clk_set_parent(sor->clk, sor->clk_safe); 736 + /* switch to safe parent clock */ 737 + err = tegra_sor_set_parent_clock(sor, sor->clk_safe); 754 738 if (err < 0) 755 739 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 756 740 ··· 1237 1219 return; 1238 1220 } 1239 1221 1240 - err = clk_set_parent(sor->clk, sor->clk_safe); 1222 + /* switch to safe parent clock */ 1223 + err = tegra_sor_set_parent_clock(sor, sor->clk_safe); 1241 1224 if (err < 0) 1242 1225 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1243 1226 ··· 1345 1326 value &= ~SOR_PLL2_PORT_POWERDOWN; 1346 1327 tegra_sor_writel(sor, value, SOR_PLL2); 1347 1328 1348 - /* switch to DP clock */ 1349 - err = clk_set_parent(sor->clk, sor->clk_dp); 1329 + /* switch to DP parent clock */ 1330 + err = tegra_sor_set_parent_clock(sor, sor->clk_dp); 1350 1331 if (err < 0) 1351 - dev_err(sor->dev, "failed to set DP parent clock: %d\n", err); 1332 + dev_err(sor->dev, "failed to set parent clock: %d\n", err); 1352 1333 1353 1334 /* power DP lanes */ 1354 1335 value = tegra_sor_readl(sor, SOR_DP_PADCTL0); ··· 1800 1781 1801 1782 reset_control_deassert(sor->rst); 1802 1783 1803 - err = clk_set_parent(sor->clk, sor->clk_safe); 1784 + /* switch to safe parent clock */ 1785 + err = tegra_sor_set_parent_clock(sor, sor->clk_safe); 1804 1786 if (err < 0) 1805 1787 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1806 1788 ··· 1912 1892 1913 1893 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL); 1914 1894 1915 - err = clk_set_parent(sor->clk, sor->clk_parent); 1895 + /* switch to parent clock */ 1896 + err = tegra_sor_set_parent_clock(sor, sor->clk_parent); 1916 1897 if (err < 0) 1917 1898 dev_err(sor->dev, "failed to set parent clock: %d\n", err); 1918 1899