diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-22 14:56:54 +0100 |
---|---|---|
committer | Liviu Dudau <Liviu.Dudau@arm.com> | 2016-11-22 15:09:06 +0100 |
commit | 7a79279e7186c4ac8b753cbd335ecc4ba81b5970 (patch) | |
tree | 07246483935eb187767dd61ad24b254ca4c459c1 /drivers | |
parent | Linux 4.9-rc5 (diff) | |
download | linux-7a79279e7186c4ac8b753cbd335ecc4ba81b5970.tar.xz linux-7a79279e7186c4ac8b753cbd335ecc4ba81b5970.zip |
drm/arm: hdlcd: fix plane base address update
While testing HDMI with Xorg on the Juno board, I find that when Xorg
starts up or shuts down, the display is shifted significantly to the
right and wrapped in the active region. (No sync bars are visible.)
The timings are correct, it behaves as if the start address has been
shifted many pixels _into_ the framebuffer.
This occurs whenever the display mode size is changed - using xrandr
in Xorg shows that changing the resolution triggers the problem
almost every time, but changing the refresh rate does not.
Using devmem2 to disable and re-enable the HDLCD resolves the issue,
and repeated disable/enable cycles do not make the issue re-appear.
Further debugging shows that we try to update the controller
configuration while enabled.
Alwys ensure that the HDLCD is disabled prior to updating the
controller timings, and use drm_crtc_vblank_off()/drm_crtc_vblank_on()
so that DRM knows whether it can expect vblank interrupts.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 48019ae22ddb..28341b32067f 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -150,15 +150,14 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc) clk_prepare_enable(hdlcd->clk); hdlcd_crtc_mode_set_nofb(crtc); hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); + drm_crtc_vblank_on(crtc); } static void hdlcd_crtc_disable(struct drm_crtc *crtc) { struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); - if (!crtc->state->active) - return; - + drm_crtc_vblank_off(crtc); hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); clk_disable_unprepare(hdlcd->clk); } |