All of lore.kernel.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,
	linux-rockchip@lists.infradead.org, mka@chromium.org,
	seanpaul@chromium.org, ryandcase@chromium.org,
	tfiga@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

WARNING: multiple messages have this Message-ID (diff)
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: 5+ 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-03 18:47 ` Douglas Anderson
2019-10-03 18:47 ` Douglas Anderson
2019-10-09 19:45 ` Sean Paul [this message]
2019-10-09 19:45   ` Sean Paul

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 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.