Use tc_pxl_pll_calc() to find out the exact clock frequency generated by the
Pixel PLL. Use the Pixel PLL frequency as adjusted_mode clock frequency and
pass it down the display pipeline to obtain exactly this frequency on input
into this bridge.

The precise input frequency that matches the Pixel PLL frequency is
important for this bridge, as if the frequencies do not match, the
bridge does suffer VFIFO overruns or underruns.

Reviewed-by: Alexander Stein <[email protected]>
Signed-off-by: Marek Vasut <[email protected]>
---
Cc: Andrzej Hajda <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Jernej Skrabec <[email protected]>
Cc: Jonas Karlman <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Lucas Stach <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: Maxime Ripard <[email protected]>
Cc: Neil Armstrong <[email protected]>
Cc: Robert Foss <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
V2: - Use mode clock as input into tc_pxl_pll_calc() to avoid
      accumulating rounding error
V3: No change
V4: - Add RB from Alexander
---
 drivers/gpu/drm/bridge/tc358767.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358767.c 
b/drivers/gpu/drm/bridge/tc358767.c
index b2f0175d95420..a77be11769791 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1624,6 +1624,18 @@ static int tc_dpi_atomic_check(struct drm_bridge *bridge,
                               struct drm_crtc_state *crtc_state,
                               struct drm_connector_state *conn_state)
 {
+       struct tc_data *tc = bridge_to_tc(bridge);
+       int adjusted_clock = 0;
+       int ret;
+
+       ret = tc_pxl_pll_calc(tc, clk_get_rate(tc->refclk),
+                             crtc_state->mode.clock * 1000,
+                             &adjusted_clock, NULL);
+       if (ret)
+               return ret;
+
+       crtc_state->adjusted_mode.clock = adjusted_clock / 1000;
+
        /* DSI->DPI interface clock limitation: upto 100 MHz */
        if (crtc_state->adjusted_mode.clock > 100000)
                return -EINVAL;
@@ -1636,6 +1648,18 @@ static int tc_edp_atomic_check(struct drm_bridge *bridge,
                               struct drm_crtc_state *crtc_state,
                               struct drm_connector_state *conn_state)
 {
+       struct tc_data *tc = bridge_to_tc(bridge);
+       int adjusted_clock = 0;
+       int ret;
+
+       ret = tc_pxl_pll_calc(tc, clk_get_rate(tc->refclk),
+                             crtc_state->mode.clock * 1000,
+                             &adjusted_clock, NULL);
+       if (ret)
+               return ret;
+
+       crtc_state->adjusted_mode.clock = adjusted_clock / 1000;
+
        /* DPI->(e)DP interface clock limitation: upto 154 MHz */
        if (crtc_state->adjusted_mode.clock > 154000)
                return -EINVAL;
-- 
2.43.0

Reply via email to