Commit eb26c6ab authored by Michael Tretter's avatar Michael Tretter Committed by Neil Armstrong

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: default avatarInki Dae <inki.dae@samsung.com>
Acked-by: default avatarInki 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: default avatarMarco Felsch <m.felsch@pengutronix.de>
Signed-off-by: default avatarMichael Tretter <m.tretter@pengutronix.de>
Tested-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20230818-samsung-dsim-v2-2-846603df0e0a@pengutronix.deSigned-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230818-samsung-dsim-v2-2-846603df0e0a@pengutronix.de
parent 3683182a
...@@ -614,7 +614,12 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, ...@@ -614,7 +614,12 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,
u16 m; u16 m;
u32 reg; u32 reg;
if (dsi->pll_clk)
fin = clk_get_rate(dsi->pll_clk);
else
fin = dsi->pll_clk_rate; fin = dsi->pll_clk_rate;
dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);
fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s); fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);
if (!fout) { if (!fout) {
dev_err(dsi->dev, dev_err(dsi->dev,
...@@ -1829,18 +1834,15 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi) ...@@ -1829,18 +1834,15 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)
u32 lane_polarities[5] = { 0 }; u32 lane_polarities[5] = { 0 };
struct device_node *endpoint; struct device_node *endpoint;
int i, nr_lanes, ret; int i, nr_lanes, ret;
struct clk *pll_clk;
ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency", ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",
&dsi->pll_clk_rate, 1); &dsi->pll_clk_rate, 1);
/* If it doesn't exist, read it from the clock instead of failing */ /* If it doesn't exist, read it from the clock instead of failing */
if (ret < 0) { if (ret < 0) {
dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n"); dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n");
pll_clk = devm_clk_get(dev, "sclk_mipi"); dsi->pll_clk = devm_clk_get(dev, "sclk_mipi");
if (!IS_ERR(pll_clk)) if (IS_ERR(dsi->pll_clk))
dsi->pll_clk_rate = clk_get_rate(pll_clk); return PTR_ERR(dsi->pll_clk);
else
return PTR_ERR(pll_clk);
} }
/* If it doesn't exist, use pixel clock instead of failing */ /* If it doesn't exist, use pixel clock instead of failing */
......
...@@ -88,6 +88,7 @@ struct samsung_dsim { ...@@ -88,6 +88,7 @@ struct samsung_dsim {
void __iomem *reg_base; void __iomem *reg_base;
struct phy *phy; struct phy *phy;
struct clk **clks; struct clk **clks;
struct clk *pll_clk;
struct regulator_bulk_data supplies[2]; struct regulator_bulk_data supplies[2];
int irq; int irq;
struct gpio_desc *te_gpio; struct gpio_desc *te_gpio;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment