public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Sean Paul <sean@poorly.run>
To: Douglas Anderson <dianders@chromium.org>
Cc: heiko@sntech.de, David Airlie <airlied@linux.ie>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	tfiga@chromium.org, linux-rockchip@lists.infradead.org,
	mka@chromium.org, seanpaul@chromium.org, ryandcase@chromium.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2] drm/rockchip: Round up _before_ giving to the clock framework
Date: Wed, 9 Oct 2019 15:45:02 -0400	[thread overview]
Message-ID: <20191009194502.GH85762@art_vandelay> (raw)
In-Reply-To: <20191003114726.v2.1.Ib233b3e706cf6317858384264d5b0ed35657456e@changeid>

On Thu, Oct 03, 2019 at 11:47:30AM -0700, Douglas Anderson wrote:
> I'm embarassed to say that even though I've touched
> vop_crtc_mode_fixup() twice and I swear I tested it, there's still a
> stupid glaring bug in it.  Specifically, on veyron_minnie (with all
> the latest display timings) we want to be setting our pixel clock to
> 66,666,666.67 Hz and we tell userspace that's what we set, but we're
> actually choosing 66,000,000 Hz.  This is confirmed by looking at the
> clock tree.
> 
> The problem is that in drm_display_mode_from_videomode() we convert
> from Hz to kHz with:
> 
>   dmode->clock = vm->pixelclock / 1000;
> 
> ...and drm_display_mode_from_videomode() is called from panel-simple
> when we have an "override_mode" like we do on veyron_minnie.  See
> commit 123643e5c40a ("ARM: dts: rockchip: Specify
> rk3288-veyron-minnie's display timings").
> 
> ...so when the device tree specifies a clock of 66666667 for the panel
> then DRM translates that to 66666000.  The clock framework will always
> pick a clock that is _lower_ than the one requested, so it will refuse
> to pick 66666667 and we'll end up at 66000000.
> 
> While we could try to fix drm_display_mode_from_videomode() to round
> to the nearest kHz and it would fix our problem, it wouldn't help if
> the clock we actually needed was 60,000,001 Hz.  We could
> alternatively have DRM always round up, but maybe this would break
> someone else who already baked in the assumption that DRM rounds down.
> Specifically note that clock drivers are not consistent about whether
> they round up or round down when you call clk_set_rate().  We know how
> Rockchip's clock driver works, but (for instance) you can see that on
> most Qualcomm clocks the default is clk_rcg2_ops which rounds up.
> 
> Let's solve this by just adding 999 Hz before calling
> clk_round_rate().  This should be safe and work everywhere.  As
> discussed in more detail in comments in the commit, Rockchip's PLLs
> are configured in a way that there shouldn't be another PLL setting
> that is only a few kHz off so we won't get mixed up.
> 
> NOTE: if this is picked to stable, it's probably easiest to first pick
> commit 527e4ca3b6d1 ("drm/rockchip: Base adjustments of the mode based
> on prev adjustments") which shouldn't hurt in stable.
> 
> Fixes: b59b8de31497 ("drm/rockchip: return a true clock rate to adjusted_mode")
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Pushed to drm-misc-next, thanks for your patch (and revision)!

Sean

> Reviewed-by: Sean Paul <seanpaul@chromium.org>
> ---
> 
> Changes in v2:
> - Beefed up the commit message (Sean).
> 
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 37 +++++++++++++++++++--
>  1 file changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 613404f86668..84e3decb17b1 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -1040,10 +1040,41 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
>  				struct drm_display_mode *adjusted_mode)
>  {
>  	struct vop *vop = to_vop(crtc);
> +	unsigned long rate;
>  
> -	adjusted_mode->clock =
> -		DIV_ROUND_UP(clk_round_rate(vop->dclk,
> -					    adjusted_mode->clock * 1000), 1000);
> +	/*
> +	 * Clock craziness.
> +	 *
> +	 * Key points:
> +	 *
> +	 * - DRM works in in kHz.
> +	 * - Clock framework works in Hz.
> +	 * - Rockchip's clock driver picks the clock rate that is the
> +	 *   same _OR LOWER_ than the one requested.
> +	 *
> +	 * Action plan:
> +	 *
> +	 * 1. When DRM gives us a mode, we should add 999 Hz to it.  That way
> +	 *    if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to
> +	 *    make 60000 kHz then the clock framework will actually give us
> +	 *    the right clock.
> +	 *
> +	 *    NOTE: if the PLL (maybe through a divider) could actually make
> +	 *    a clock rate 999 Hz higher instead of the one we want then this
> +	 *    could be a problem.  Unfortunately there's not much we can do
> +	 *    since it's baked into DRM to use kHz.  It shouldn't matter in
> +	 *    practice since Rockchip PLLs are controlled by tables and
> +	 *    even if there is a divider in the middle I wouldn't expect PLL
> +	 *    rates in the table that are just a few kHz different.
> +	 *
> +	 * 2. Get the clock framework to round the rate for us to tell us
> +	 *    what it will actually make.
> +	 *
> +	 * 3. Store the rounded up rate so that we don't need to worry about
> +	 *    this in the actual clk_set_rate().
> +	 */
> +	rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
> +	adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
>  
>  	return true;
>  }
> -- 
> 2.23.0.444.g18eeb5a265-goog
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

      reply	other threads:[~2019-10-09 19:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-03 18:47 [PATCH v2] drm/rockchip: Round up _before_ giving to the clock framework Douglas Anderson
2019-10-09 19:45 ` Sean Paul [this message]

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=20191009194502.GH85762@art_vandelay \
    --to=sean@poorly.run \
    --cc=airlied@linux.ie \
    --cc=dianders@chromium.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mka@chromium.org \
    --cc=ryandcase@chromium.org \
    --cc=seanpaul@chromium.org \
    --cc=tfiga@chromium.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox