[PATCH] drm/bridge: tc358767: Improve DPI output pixel clock accuracy
Neil Armstrong
neil.armstrong at linaro.org
Mon Oct 28 09:45:10 UTC 2024
On 26/10/2024 06:11, Marek Vasut wrote:
> The Pixel PLL is not very capable and may come up with wildly inaccurate
> clock. Since DPI panels are often tolerant to slightly higher pixel clock
> without being operated outside of specification, calculate two Pixel PLL
> settings for DPI output, one for desired output pixel clock and one for
> output pixel clock with 1% increase, and then pick the result which is
> closer to the desired pixel clock and use it as the Pixel PLL settings.
>
> For the Chefree CH101 panel with 13 MHz Xtal input clock, the frequency
> without this patch is 65 MHz which is out of the panel specification of
> 68.9..73.4 MHz, while with this patch it is 71.5 MHz which is well within
> the specification and far more accurate.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> ---
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: David Airlie <airlied at gmail.com>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Neil Armstrong <neil.armstrong at linaro.org>
> Cc: Robert Foss <rfoss at kernel.org>
> Cc: Simona Vetter <simona at ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: dri-devel at lists.freedesktop.org
> ---
> drivers/gpu/drm/bridge/tc358767.c | 28 ++++++++++++++++++++++++++--
> 1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
> index 0d523322fdd8e..7e1a7322cec70 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -1682,15 +1682,39 @@ static int tc_dpi_atomic_check(struct drm_bridge *bridge,
> struct drm_connector_state *conn_state)
> {
> struct tc_data *tc = bridge_to_tc(bridge);
> - int adjusted_clock = 0;
> + int adjusted_clock_0p = 0;
> + int adjusted_clock_1p = 0;
> + int adjusted_clock;
> int ret;
>
> + /*
> + * Calculate adjusted clock pixel and find out what the PLL can
> + * produce. The PLL is limited, so the clock might be inaccurate.
> + */
> ret = tc_pxl_pll_calc(tc, clk_get_rate(tc->refclk),
> crtc_state->mode.clock * 1000,
> - &adjusted_clock, NULL);
> + &adjusted_clock_0p, NULL);
> + if (ret)
> + return ret;
> +
> + /*
> + * Calculate adjusted pixel clock with 1% faster requested pixel
> + * clock and find out what the PLL can produce. This may in fact
> + * be closer to the expected pixel clock of the output.
> + */
> + ret = tc_pxl_pll_calc(tc, clk_get_rate(tc->refclk),
> + crtc_state->mode.clock * 1010,
> + &adjusted_clock_1p, NULL);
> if (ret)
> return ret;
>
> + /* Pick the more accurate of the two calculated results. */
> + if (crtc_state->mode.clock * 1010 - adjusted_clock_1p <
> + crtc_state->mode.clock * 1000 - adjusted_clock_0p)
> + adjusted_clock = adjusted_clock_1p;
> + else
> + adjusted_clock = adjusted_clock_0p;
> +
> crtc_state->adjusted_mode.clock = adjusted_clock / 1000;
>
> /* DSI->DPI interface clock limitation: upto 100 MHz */
It looks like you want to go around a not very well written tc_pxl_pll_calc()
Seems the functions would either need a rewrite or perhaps use CCF instead by
declaring all the pre-div/PLL/post-div.
Neil
More information about the dri-devel
mailing list