linux/drivers/gpu/drm/rockchip
Douglas Anderson 287422a95f drm/rockchip: Round up _before_ giving to the clock framework
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 123643e5c4 ("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 527e4ca3b6 ("drm/rockchip: Base adjustments of the mode based
on prev adjustments") which shouldn't hurt in stable.

Fixes: b59b8de314 ("drm/rockchip: return a true clock rate to adjusted_mode")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191003114726.v2.1.Ib233b3e706cf6317858384264d5b0ed35657456e@changeid
2019-10-09 15:13:58 -04:00
..
analogix_dp-rockchip.c drm main pull for 5.4-rc1 2019-09-19 16:24:24 -07:00
cdn-dp-core.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
cdn-dp-core.h Linus 5.3-rc1 2019-07-22 21:24:10 +02:00
cdn-dp-reg.c Merge remote-tracking branch 'drm/drm-next' into drm-misc-next 2019-06-19 12:32:13 +02:00
cdn-dp-reg.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
dw_hdmi-rockchip.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
dw-mipi-dsi-rockchip.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
inno_hdmi.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
inno_hdmi.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
Kconfig treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
Makefile drm/rockchip: Use the helpers for PSR 2019-07-26 14:48:03 -04:00
rk3066_hdmi.c drm: rockchip: introduce rk3066 hdmi 2019-03-31 14:24:30 +02:00
rk3066_hdmi.h drm: rockchip: introduce rk3066 hdmi 2019-03-31 14:24:30 +02:00
rockchip_drm_drv.c drm main pull for 5.4-rc1 2019-09-19 16:24:24 -07:00
rockchip_drm_drv.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_drm_fb.c drm/rockchip: Use drm_atomic_helper_commit_tail_rpm 2019-07-26 14:48:03 -04:00
rockchip_drm_fb.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_drm_fbdev.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
rockchip_drm_fbdev.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_drm_gem.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
rockchip_drm_gem.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_drm_vop.c drm/rockchip: Round up _before_ giving to the clock framework 2019-10-09 15:13:58 -04:00
rockchip_drm_vop.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_lvds.c drm: Stop including drm_bridge.h from drm_crtc.h 2019-08-28 22:11:03 +02:00
rockchip_lvds.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00
rockchip_rgb.c drm/bridge: panel: Infer connector type from panel by default 2019-09-08 19:04:23 +02:00
rockchip_rgb.h drm/rockchip: rgb: update SPDX license identifier 2019-01-25 14:50:07 +01:00
rockchip_vop_reg.c drm/rockchip: drop use of drmP.h 2019-07-17 12:52:55 +02:00
rockchip_vop_reg.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 282 2019-06-05 17:36:37 +02:00