From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> IVB introduced the CUR_FBC_CTL register which allows reducing the cursor height down to 8 lines from the otherwise square cursor dimensions. Implement support for it. Commandeer the otherwise unused intel_crtc->cursor_size to track the current value of CUR_FBC_CTL so that we can avoid duplicating the complicated device type checks in i9xx_update_cursor(). One caveat to note is that CUR_FBC_CTL can't be used with 180 degree rotation, so when cursor rotation gets introduced some extra checks are needed. Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_reg.h | 5 ++++- drivers/gpu/drm/i915/intel_display.c | 25 ++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 15c0eaa..572001b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4169,7 +4169,9 @@ enum punit_power_well { #define CURSOR_POS_SIGN 0x8000 #define CURSOR_X_SHIFT 0 #define CURSOR_Y_SHIFT 16 -#define CURSIZE 0x700a0 +#define CURSIZE 0x700a0 /* 845/865 */ +#define _CUR_FBC_CTL_A 0x700a0 /* ivb+ */ +#define CUR_FBC_CTL_EN (1 << 31) #define _CURBCNTR 0x700c0 #define _CURBBASE 0x700c4 #define _CURBPOS 0x700c8 @@ -4185,6 +4187,7 @@ enum punit_power_well { #define CURCNTR(pipe) _CURSOR2(pipe, _CURACNTR) #define CURBASE(pipe) _CURSOR2(pipe, _CURABASE) #define CURPOS(pipe) _CURSOR2(pipe, _CURAPOS) +#define CUR_FBC_CTL(pipe) _CURSOR2(pipe, _CUR_FBC_CTL_A) #define CURSOR_A_OFFSET 0x70080 #define CURSOR_B_OFFSET 0x700c0 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ca729e5..9c000fb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8197,6 +8197,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; uint32_t cntl; + uint32_t fbc_ctl = 0; cntl = 0; if (base) { @@ -8217,6 +8218,16 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) } cntl |= pipe << 28; /* Connect to correct pipe */ } + + if (intel_crtc->cursor_height != intel_crtc->cursor_width) + fbc_ctl = CUR_FBC_CTL_EN | (intel_crtc->cursor_height - 1); + + if (intel_crtc->cursor_size != fbc_ctl) { + I915_WRITE(CUR_FBC_CTL(pipe), fbc_ctl); + intel_crtc->cursor_size = fbc_ctl; + intel_crtc->cursor_cntl = 0; + } + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) cntl |= CURSOR_PIPE_CSC_ENABLE; @@ -8293,6 +8304,8 @@ static bool cursor_size_ok(struct drm_device *dev, * the width of their cursors, the height is arbitrary up to * the precision of the register. Everything else requires * square cursors, limited to a few power-of-two sizes. + * ivb+ have CUR_FBC_CTL which allows reducing the cursor + * height down to a minimum of 8 lines. */ if (IS_845G(dev) || IS_I865G(dev)) { if ((width & 63) != 0) @@ -8304,7 +8317,7 @@ static bool cursor_size_ok(struct drm_device *dev, if (height > 1023) return false; } else { - switch (width | height) { + switch (width) { case 256: case 128: if (IS_GEN2(dev)) @@ -8314,6 +8327,16 @@ static bool cursor_size_ok(struct drm_device *dev, default: return false; } + + if (IS_IVYBRIDGE(dev) || + IS_HASWELL(dev) || IS_BROADWELL(dev) || + INTEL_INFO(dev)->gen >= 9) { + if (height < 8 || height > width) + return false; + } else { + if (height != width) + return false; + } } return true; -- 1.8.5.5 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx