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

drm/bridge: samsung-dsim: reread ref clock before configuring PLL

The PLL reference clock may change at runtime when its parent clock
changes. For example, this may happen on the i.MX8M Nano if the
reference clock is a child of the Video PLL. If the pixel clock changes,
this may propagate to the Video PLL and as a side effect change the
reference clock. Thus, reading the clock rate during probe is not
sufficient to correctly configure the PLL for the expected hs clock.

Read the actual rate of the reference clock before calculating the PLL
configuration parameters.

Note that the "samsung,pll-clock-frequency" is always preferred and PLL
reference clock is only read from the clock tree if that device tree
property is not set.

Reviewed-by: Inki Dae <inki.dae@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de> # Kontron BL i.MX8MM + Waveshare 10.1inch HDMI LCD (E)
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20230818-samsung-dsim-v2-2-846603df0e0a@pengutronix.de
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230818-samsung-dsim-v2-2-846603df0e0a@pengutronix.de

authored by

Michael Tretter and committed by
Neil Armstrong
eb26c6ab 3683182a

+10 -7
+9 -7
drivers/gpu/drm/bridge/samsung-dsim.c
··· 614 614 u16 m; 615 615 u32 reg; 616 616 617 - fin = dsi->pll_clk_rate; 617 + if (dsi->pll_clk) 618 + fin = clk_get_rate(dsi->pll_clk); 619 + else 620 + fin = dsi->pll_clk_rate; 621 + dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin); 622 + 618 623 fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s); 619 624 if (!fout) { 620 625 dev_err(dsi->dev, ··· 1834 1829 u32 lane_polarities[5] = { 0 }; 1835 1830 struct device_node *endpoint; 1836 1831 int i, nr_lanes, ret; 1837 - struct clk *pll_clk; 1838 1832 1839 1833 ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency", 1840 1834 &dsi->pll_clk_rate, 1); 1841 1835 /* If it doesn't exist, read it from the clock instead of failing */ 1842 1836 if (ret < 0) { 1843 1837 dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n"); 1844 - pll_clk = devm_clk_get(dev, "sclk_mipi"); 1845 - if (!IS_ERR(pll_clk)) 1846 - dsi->pll_clk_rate = clk_get_rate(pll_clk); 1847 - else 1848 - return PTR_ERR(pll_clk); 1838 + dsi->pll_clk = devm_clk_get(dev, "sclk_mipi"); 1839 + if (IS_ERR(dsi->pll_clk)) 1840 + return PTR_ERR(dsi->pll_clk); 1849 1841 } 1850 1842 1851 1843 /* If it doesn't exist, use pixel clock instead of failing */
+1
include/drm/bridge/samsung-dsim.h
··· 88 88 void __iomem *reg_base; 89 89 struct phy *phy; 90 90 struct clk **clks; 91 + struct clk *pll_clk; 91 92 struct regulator_bulk_data supplies[2]; 92 93 int irq; 93 94 struct gpio_desc *te_gpio;