From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Marek Vasut <marex@denx.de>
Cc: dri-devel@lists.freedesktop.org,
Andrzej Hajda <andrzej.hajda@intel.com>,
David Airlie <airlied@gmail.com>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Jonas Karlman <jonas@kwiboo.se>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>, Simona Vetter <simona@ffwll.ch>,
Thomas Zimmermann <tzimmermann@suse.de>
Subject: Re: [PATCH v2 2/2] drm/bridge: tc358767: Improve DPI output pixel clock accuracy
Date: Tue, 12 Nov 2024 07:29:11 +0200 [thread overview]
Message-ID: <20241112052911.GA5877@pendragon.ideasonboard.com> (raw)
In-Reply-To: <20241112020737.335297-2-marex@denx.de>
Hi Marek,
Thank you for the patch.
On Tue, Nov 12, 2024 at 03:05:37AM +0100, 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
> from either mode clock or display_timing .pixelclock.max , whichever is
> higher.
Maybe this is a leftover from v1 in the commit message, but I don't
think the code computes two pixel PLL.
> Since the Pixel PLL output clock frequency calculation always
> returns lower frequency than the requested clock frequency, passing in
> the higher clock frequency should result in output clock frequency which
> is closer to the expected pixel clock.
Is that guaranteed ?
> 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.
I'm a bit concerned that this patch is quite a bit of a hack, but fixing
the problem correctly would be too much yak shaving :-S
>
> Keep the change isolated to DPI output.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> Cc: Andrzej Hajda <andrzej.hajda@intel.com>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Robert Foss <rfoss@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: dri-devel@lists.freedesktop.org
> ---
> V2: - Isolate the change to DPI only, split tc_bridge_mode_set()
> - Look up display_timings and use .pixelclock.max as input
> into the PLL calculation if available. That should yield
> more accurate results for DPI panels.
> ---
> drivers/gpu/drm/bridge/tc358767.c | 47 +++++++++++++++++++++++++------
> 1 file changed, 39 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
> index 0d523322fdd8e..fe9ab06d82d91 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -39,6 +39,8 @@
> #include <drm/drm_print.h>
> #include <drm/drm_probe_helper.h>
>
> +#include <video/display_timing.h>
> +
> /* Registers */
>
> /* DSI D-PHY Layer registers */
> @@ -1681,13 +1683,33 @@ static int tc_dpi_atomic_check(struct drm_bridge *bridge,
> struct drm_crtc_state *crtc_state,
> struct drm_connector_state *conn_state)
> {
> + u32 mode_clock = crtc_state->mode.clock * 1000;
> struct tc_data *tc = bridge_to_tc(bridge);
> - int adjusted_clock = 0;
> + struct drm_bridge *nb = bridge;
> + struct display_timing timings;
> + struct drm_panel *panel;
> + int adjusted_clock;
> int ret;
>
> + do {
> + if (!drm_bridge_is_panel(nb))
drm_bridge_get_panel() already checks if the bridge is related to a
panel, so I think you can drop this check.
> + continue;
> +
> + panel = drm_bridge_get_panel(nb);
> + if (!panel || !panel->funcs || !panel->funcs->get_timings)
> + continue;
> +
> + ret = panel->funcs->get_timings(panel, 1, &timings);
> + if (ret <= 0)
> + break;
> +
> + if (timings.pixelclock.max > mode_clock)
> + mode_clock = timings.pixelclock.max;
> + break;
> + } while ((nb = drm_bridge_get_next_bridge(nb)));
Can the panel be anything that the last bridge in the chain ?
> +
> ret = tc_pxl_pll_calc(tc, clk_get_rate(tc->refclk),
> - crtc_state->mode.clock * 1000,
> - &adjusted_clock, NULL);
> + mode_clock, &adjusted_clock, NULL);
> if (ret)
> return ret;
>
> @@ -1758,9 +1780,18 @@ tc_edp_mode_valid(struct drm_bridge *bridge,
> return MODE_OK;
> }
>
> -static void tc_bridge_mode_set(struct drm_bridge *bridge,
> - const struct drm_display_mode *mode,
> - const struct drm_display_mode *adj)
> +static void tc_dpi_bridge_mode_set(struct drm_bridge *bridge,
> + const struct drm_display_mode *mode,
> + const struct drm_display_mode *adj)
> +{
> + struct tc_data *tc = bridge_to_tc(bridge);
> +
> + drm_mode_copy(&tc->mode, adj);
> +}
> +
> +static void tc_edp_bridge_mode_set(struct drm_bridge *bridge,
> + const struct drm_display_mode *mode,
> + const struct drm_display_mode *adj)
> {
> struct tc_data *tc = bridge_to_tc(bridge);
>
> @@ -1977,7 +2008,7 @@ tc_edp_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
> static const struct drm_bridge_funcs tc_dpi_bridge_funcs = {
> .attach = tc_dpi_bridge_attach,
> .mode_valid = tc_dpi_mode_valid,
> - .mode_set = tc_bridge_mode_set,
> + .mode_set = tc_dpi_bridge_mode_set,
> .atomic_check = tc_dpi_atomic_check,
> .atomic_enable = tc_dpi_bridge_atomic_enable,
> .atomic_disable = tc_dpi_bridge_atomic_disable,
> @@ -1991,7 +2022,7 @@ static const struct drm_bridge_funcs tc_edp_bridge_funcs = {
> .attach = tc_edp_bridge_attach,
> .detach = tc_edp_bridge_detach,
> .mode_valid = tc_edp_mode_valid,
> - .mode_set = tc_bridge_mode_set,
> + .mode_set = tc_edp_bridge_mode_set,
> .atomic_check = tc_edp_atomic_check,
> .atomic_enable = tc_edp_bridge_atomic_enable,
> .atomic_disable = tc_edp_bridge_atomic_disable,
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2024-11-12 5:29 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-12 2:05 [PATCH v2 1/2] drm/bridge/panel: Add drm_bridge_get_panel to extract panel from last bridge Marek Vasut
2024-11-12 2:05 ` [PATCH v2 2/2] drm/bridge: tc358767: Improve DPI output pixel clock accuracy Marek Vasut
2024-11-12 5:29 ` Laurent Pinchart [this message]
2024-11-22 13:32 ` Dmitry Baryshkov
2024-11-25 13:17 ` Maxime Ripard
2024-11-25 22:07 ` Dmitry Baryshkov
2024-11-26 15:59 ` Maxime Ripard
2024-11-26 18:06 ` Dmitry Baryshkov
2024-11-25 23:50 ` Marek Vasut
2024-11-25 23:48 ` Marek Vasut
2024-11-26 15:56 ` Maxime Ripard
2024-11-26 16:30 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241112052911.GA5877@pendragon.ideasonboard.com \
--to=laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=maarten.lankhorst@linux.intel.com \
--cc=marex@denx.de \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=rfoss@kernel.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.