[Intel-gfx] [PATCH v4 4/4] drm/i915: Add support for variable cursor size on 845/865

2014-08-13 Thread ville . syrjala
From: Ville Syrjälä ville.syrj...@linux.intel.com

845/865 support different cursor sizes as well, albeit a bit differently
than later platforms. Add the necessary code to make them work.

Untested due to lack of hardware.

v2: Warn but accept invalid stride (Chris)
Rewrite the cursor size checks for other platforms (Chris)
v3: More polish and magic to the cursor size checks (Chris)
v4: Moar polish and a comment (Chris)

Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk
Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
---
 drivers/gpu/drm/i915/i915_reg.h  |   3 +-
 drivers/gpu/drm/i915/intel_display.c | 111 +++
 drivers/gpu/drm/i915/intel_drv.h |   1 +
 3 files changed, 91 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f79c20d..203062e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4128,7 +4128,8 @@ enum punit_power_well {
 /* Old style CUR*CNTR flags (desktop 8xx) */
 #define   CURSOR_ENABLE0x8000
 #define   CURSOR_GAMMA_ENABLE  0x4000
-#define   CURSOR_STRIDE_MASK   0x3000
+#define   CURSOR_STRIDE_SHIFT  28
+#define   CURSOR_STRIDE(x) ((ffs(x)-9)  CURSOR_STRIDE_SHIFT) /* 
256,512,1k,2k */
 #define   CURSOR_PIPE_CSC_ENABLE (124)
 #define   CURSOR_FORMAT_SHIFT  24
 #define   CURSOR_FORMAT_MASK   (0x07  CURSOR_FORMAT_SHIFT)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a1cf052..0cefd15 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8005,30 +8005,55 @@ static void i845_update_cursor(struct drm_crtc *crtc, 
u32 base)
struct drm_device *dev = crtc-dev;
struct drm_i915_private *dev_priv = dev-dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-   uint32_t cntl;
+   uint32_t cntl = 0, size = 0;
 
-   if (base != intel_crtc-cursor_base) {
-   /* On these chipsets we can only modify the base whilst
-* the cursor is disabled.
-*/
-   if (intel_crtc-cursor_cntl) {
-   I915_WRITE(_CURACNTR, 0);
-   POSTING_READ(_CURACNTR);
-   intel_crtc-cursor_cntl = 0;
+   if (base) {
+   unsigned int width = intel_crtc-cursor_width;
+   unsigned int height = intel_crtc-cursor_height;
+   unsigned int stride = roundup_pow_of_two(width) * 4;
+
+   switch (stride) {
+   default:
+   WARN_ONCE(1, Invalid cursor width/stride, width=%u, 
stride=%u\n,
+ width, stride);
+   stride = 256;
+   /* fallthrough */
+   case 256:
+   case 512:
+   case 1024:
+   case 2048:
+   break;
}
 
+   cntl |= CURSOR_ENABLE |
+   CURSOR_GAMMA_ENABLE |
+   CURSOR_FORMAT_ARGB |
+   CURSOR_STRIDE(stride);
+
+   size = (height  12) | width;
+   }
+
+   if (intel_crtc-cursor_cntl != 0 
+   (intel_crtc-cursor_base != base ||
+intel_crtc-cursor_size != size ||
+intel_crtc-cursor_cntl != cntl)) {
+   /* On these chipsets we can only modify the base/size/stride
+* whilst the cursor is disabled.
+*/
+   I915_WRITE(_CURACNTR, 0);
+   POSTING_READ(_CURACNTR);
+   intel_crtc-cursor_cntl = 0;
+   }
+
+   if (intel_crtc-cursor_base != base)
I915_WRITE(_CURABASE, base);
-   POSTING_READ(_CURABASE);
+
+   if (intel_crtc-cursor_size != size) {
+   I915_WRITE(CURSIZE, size);
+   intel_crtc-cursor_size = size;
}
 
-   /* XXX width must be 64, stride 256 = 0x00  28 */
-   cntl = 0;
-   if (base)
-   cntl = (CURSOR_ENABLE |
-   CURSOR_GAMMA_ENABLE |
-   CURSOR_FORMAT_ARGB);
if (intel_crtc-cursor_cntl != cntl) {
-   I915_WRITE(CURSIZE, (64  12) | 64);
I915_WRITE(_CURACNTR, cntl);
POSTING_READ(_CURACNTR);
intel_crtc-cursor_cntl = cntl;
@@ -8127,6 +8152,43 @@ static void intel_crtc_update_cursor(struct drm_crtc 
*crtc,
intel_crtc-cursor_base = base;
 }
 
+static bool cursor_size_ok(struct drm_device *dev,
+  uint32_t width, uint32_t height)
+{
+   if (width == 0 || height == 0)
+   return false;
+
+   /*
+* 845g/865g are special in that they are only limited by
+* the width of their cursors, the height is arbitrary up to
+* the precision of the register. Everything else requires
+* square cursors, limited 

Re: [Intel-gfx] [PATCH v4 4/4] drm/i915: Add support for variable cursor size on 845/865

2014-08-13 Thread Daniel Vetter
On Wed, Aug 13, 2014 at 11:57:05AM +0300, ville.syrj...@linux.intel.com wrote:
 From: Ville Syrjälä ville.syrj...@linux.intel.com
 
 845/865 support different cursor sizes as well, albeit a bit differently
 than later platforms. Add the necessary code to make them work.
 
 Untested due to lack of hardware.
 
 v2: Warn but accept invalid stride (Chris)
 Rewrite the cursor size checks for other platforms (Chris)
 v3: More polish and magic to the cursor size checks (Chris)
 v4: Moar polish and a comment (Chris)
 
 Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk
 Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com

All merged to dinq, thanks.
-Daniel

 ---
  drivers/gpu/drm/i915/i915_reg.h  |   3 +-
  drivers/gpu/drm/i915/intel_display.c | 111 
 +++
  drivers/gpu/drm/i915/intel_drv.h |   1 +
  3 files changed, 91 insertions(+), 24 deletions(-)
 
 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
 index f79c20d..203062e 100644
 --- a/drivers/gpu/drm/i915/i915_reg.h
 +++ b/drivers/gpu/drm/i915/i915_reg.h
 @@ -4128,7 +4128,8 @@ enum punit_power_well {
  /* Old style CUR*CNTR flags (desktop 8xx) */
  #define   CURSOR_ENABLE  0x8000
  #define   CURSOR_GAMMA_ENABLE0x4000
 -#define   CURSOR_STRIDE_MASK 0x3000
 +#define   CURSOR_STRIDE_SHIFT28
 +#define   CURSOR_STRIDE(x)   ((ffs(x)-9)  CURSOR_STRIDE_SHIFT) /* 
 256,512,1k,2k */
  #define   CURSOR_PIPE_CSC_ENABLE (124)
  #define   CURSOR_FORMAT_SHIFT24
  #define   CURSOR_FORMAT_MASK (0x07  CURSOR_FORMAT_SHIFT)
 diff --git a/drivers/gpu/drm/i915/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index a1cf052..0cefd15 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -8005,30 +8005,55 @@ static void i845_update_cursor(struct drm_crtc *crtc, 
 u32 base)
   struct drm_device *dev = crtc-dev;
   struct drm_i915_private *dev_priv = dev-dev_private;
   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 - uint32_t cntl;
 + uint32_t cntl = 0, size = 0;
  
 - if (base != intel_crtc-cursor_base) {
 - /* On these chipsets we can only modify the base whilst
 -  * the cursor is disabled.
 -  */
 - if (intel_crtc-cursor_cntl) {
 - I915_WRITE(_CURACNTR, 0);
 - POSTING_READ(_CURACNTR);
 - intel_crtc-cursor_cntl = 0;
 + if (base) {
 + unsigned int width = intel_crtc-cursor_width;
 + unsigned int height = intel_crtc-cursor_height;
 + unsigned int stride = roundup_pow_of_two(width) * 4;
 +
 + switch (stride) {
 + default:
 + WARN_ONCE(1, Invalid cursor width/stride, width=%u, 
 stride=%u\n,
 +   width, stride);
 + stride = 256;
 + /* fallthrough */
 + case 256:
 + case 512:
 + case 1024:
 + case 2048:
 + break;
   }
  
 + cntl |= CURSOR_ENABLE |
 + CURSOR_GAMMA_ENABLE |
 + CURSOR_FORMAT_ARGB |
 + CURSOR_STRIDE(stride);
 +
 + size = (height  12) | width;
 + }
 +
 + if (intel_crtc-cursor_cntl != 0 
 + (intel_crtc-cursor_base != base ||
 +  intel_crtc-cursor_size != size ||
 +  intel_crtc-cursor_cntl != cntl)) {
 + /* On these chipsets we can only modify the base/size/stride
 +  * whilst the cursor is disabled.
 +  */
 + I915_WRITE(_CURACNTR, 0);
 + POSTING_READ(_CURACNTR);
 + intel_crtc-cursor_cntl = 0;
 + }
 +
 + if (intel_crtc-cursor_base != base)
   I915_WRITE(_CURABASE, base);
 - POSTING_READ(_CURABASE);
 +
 + if (intel_crtc-cursor_size != size) {
 + I915_WRITE(CURSIZE, size);
 + intel_crtc-cursor_size = size;
   }
  
 - /* XXX width must be 64, stride 256 = 0x00  28 */
 - cntl = 0;
 - if (base)
 - cntl = (CURSOR_ENABLE |
 - CURSOR_GAMMA_ENABLE |
 - CURSOR_FORMAT_ARGB);
   if (intel_crtc-cursor_cntl != cntl) {
 - I915_WRITE(CURSIZE, (64  12) | 64);
   I915_WRITE(_CURACNTR, cntl);
   POSTING_READ(_CURACNTR);
   intel_crtc-cursor_cntl = cntl;
 @@ -8127,6 +8152,43 @@ static void intel_crtc_update_cursor(struct drm_crtc 
 *crtc,
   intel_crtc-cursor_base = base;
  }
  
 +static bool cursor_size_ok(struct drm_device *dev,
 +uint32_t width, uint32_t height)
 +{
 + if (width == 0 || height == 0)
 + return false;
 +
 + /*
 +  * 845g/865g are special in that they are only limited by
 +  * the width of their cursors, the height is