Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

DRM/i915: On G45 enable cursor plane briefly after enabling the display plane.

On G45 some low res modes (800x600 and 1024x768) produce a blank
screen when the display plane is enabled with with cursor plane
off.
Experiments showed that this issue occurred when the following
conditions were met:
a. a previous mode had the cursor plane enabled (Xserver).
b. this mode or the previous one was using self refresh. (Thus
the problem was only seen with low res modes).
The screens lit up as soon as the cursor plane got enabled.
Therefore the blank screen occurred only in console mode, not
when running an Xserver.
It also seemed to be necessary to disable self refresh while briefly
enabling the cursor plane.

Signed-off-by: Egbert Eich <eich@suse.com>
Bugzilla: https://bugs.freedesktop.org/attachment.cgi?bugid=61457
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
[danvet: drop spurious whitespace change.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Egbert Eich and committed by
Daniel Vetter
61bc95c1 86c268ed

+26
+26
drivers/gpu/drm/i915/intel_display.c
··· 3604 3604 */ 3605 3605 } 3606 3606 3607 + /** 3608 + * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware 3609 + * cursor plane briefly if not already running after enabling the display 3610 + * plane. 3611 + * This workaround avoids occasional blank screens when self refresh is 3612 + * enabled. 3613 + */ 3614 + static void 3615 + g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) 3616 + { 3617 + u32 cntl = I915_READ(CURCNTR(pipe)); 3618 + 3619 + if ((cntl & CURSOR_MODE) == 0) { 3620 + u32 fw_bcl_self = I915_READ(FW_BLC_SELF); 3621 + 3622 + I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN); 3623 + I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); 3624 + intel_wait_for_vblank(dev_priv->dev, pipe); 3625 + I915_WRITE(CURCNTR(pipe), cntl); 3626 + I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); 3627 + I915_WRITE(FW_BLC_SELF, fw_bcl_self); 3628 + } 3629 + } 3630 + 3607 3631 static void i9xx_crtc_enable(struct drm_crtc *crtc) 3608 3632 { 3609 3633 struct drm_device *dev = crtc->dev; ··· 3653 3629 3654 3630 intel_enable_pipe(dev_priv, pipe, false); 3655 3631 intel_enable_plane(dev_priv, plane, pipe); 3632 + if (IS_G4X(dev)) 3633 + g4x_fixup_plane(dev_priv, pipe); 3656 3634 3657 3635 intel_crtc_load_lut(crtc); 3658 3636 intel_update_fbc(dev);