[Intel-gfx] [PATCHv2 2/5] drm/i915/skl: Add blend_func to SKL/BXT sprite planes

2016-04-29 Thread Vandita Kulkarni
From: Damien Lespiau 

This patch adds the blend functions, and as per the
blend function, updates the plane control register values

V2: Add blend support for all RGB formats
Fix the reg writes on plane_ctl_alpha bits.

V3: Add support support for primary and cursor planes.
fix an issue where the previous value was not
retained, change the logic to do so.

Signed-off-by: Damien Lespiau 
Signed-off-by: vandita kulkarni 
---
 drivers/gpu/drm/i915/intel_display.c | 121 +--
 drivers/gpu/drm/i915/intel_drv.h |  14 +++-
 drivers/gpu/drm/i915/intel_sprite.c  |   6 +-
 3 files changed, 133 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c5b9687..037407f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2921,8 +2921,29 @@ static void skl_detach_scalers(struct intel_crtc 
*intel_crtc)
}
 }
 
-u32 skl_plane_ctl_format(uint32_t pixel_format)
+u32 skl_plane_ctl_format(uint32_t pixel_format,
+   enum per_pixel_alpha_state alpha)
 {
+   u32 plane_ctl_alpha = 0;
+
+   if (pixel_format == DRM_FORMAT_ABGR ||
+   pixel_format == DRM_FORMAT_ARGB) {
+
+   switch (alpha) {
+   case DROP_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_DISABLE;
+   break;
+   case PRE_MULTIPLIED_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   break;
+   case NON_PRE_MULTIPLIED_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_HW_PREMULTIPLY;
+   break;
+   default:
+   MISSING_CASE(alpha);
+   }
+   }
+
switch (pixel_format) {
case DRM_FORMAT_C8:
return PLANE_CTL_FORMAT_INDEXED;
@@ -2938,11 +2959,11 @@ u32 skl_plane_ctl_format(uint32_t pixel_format)
 * DRM_FORMAT) for user-space to configure that.
 */
case DRM_FORMAT_ABGR:
-   return PLANE_CTL_FORMAT_XRGB_ | PLANE_CTL_ORDER_RGBX |
-   PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   return ((PLANE_CTL_FORMAT_XRGB_ | (PLANE_CTL_ORDER_RGBX
+   & (~PLANE_CTL_ALPHA_MASK))) | plane_ctl_alpha);
case DRM_FORMAT_ARGB:
-   return PLANE_CTL_FORMAT_XRGB_ |
-   PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   return ((PLANE_CTL_FORMAT_XRGB_ & ~PLANE_CTL_ALPHA_MASK)
+   | plane_ctl_alpha);
case DRM_FORMAT_XRGB2101010:
return PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_XBGR2101010:
@@ -3031,7 +3052,8 @@ static void skylake_update_primary_plane(struct drm_plane 
*plane,
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE;
 
-   plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+   plane_ctl |= skl_plane_ctl_format(fb->pixel_format,
+   plane_state->per_pixel_alpha);
plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
plane_ctl |= skl_plane_ctl_rotation(rotation);
@@ -3087,6 +3109,69 @@ static void skylake_update_primary_plane(struct 
drm_plane *plane,
POSTING_READ(PLANE_SURF(pipe, 0));
 }
 
+static int intel_plane_state_check_blend(struct drm_plane_state *plane_state)
+{
+   struct drm_device *dev = plane_state->state->dev;
+   struct intel_plane_state *state = to_intel_plane_state(plane_state);
+   const struct drm_framebuffer *fb = plane_state->fb;
+   const struct drm_blend_mode *mode = >base.blend_mode;
+   bool has_per_pixel_blending;
+
+   /*
+* We don't install the properties pre-SKL, so this is SKL+ specific
+* code for now.
+*/
+   if (INTEL_INFO(dev)->gen < 9)
+   return 0;
+
+   if (!fb)
+   return 0;
+
+   has_per_pixel_blending = fb->pixel_format == DRM_FORMAT_ABGR ||
+   fb->pixel_format == DRM_FORMAT_RGBA ||
+   fb->pixel_format == DRM_FORMAT_ARGB ||
+   fb->pixel_format == DRM_FORMAT_BGRA;
+
+   /* drop alpha for all fbs without an alpha channel */
+   if (!has_per_pixel_blending)
+   state->per_pixel_alpha = DROP_ALPHA;
+
+   switch (mode->func) {
+   /*
+* The 'AUTO' behaviour is the default and keeps compatibility with
+* kernels before the introduction of the blend_func property:
+*   - pre-multiplied alpha if the fb has an alpha channel
+*   - usual DRM_BLEND_FUNC(ONE, ZERO) otherwise
+*/
+   case 

[Intel-gfx] [PATCHv2 2/5] drm/i915/skl: Add blend_func to SKL/BXT sprite planes

2016-04-26 Thread Vandita Kulkarni
From: Damien Lespiau 

This patch adds the blend functions, and as per the
blend function, updates the plane control register values

V2: Add blend support for all RGB formats
Fix the reg writes on plane_ctl_alpha bits.

V3: Add support support for primary and cursor planes.
fix an issue where the previous value was not
retained, change the logic to do so.

Signed-off-by: Damien Lespiau 
Signed-off-by: vandita kulkarni 
---
 drivers/gpu/drm/i915/intel_display.c | 121 +--
 drivers/gpu/drm/i915/intel_drv.h |  14 +++-
 drivers/gpu/drm/i915/intel_sprite.c  |   6 +-
 3 files changed, 133 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c5b9687..037407f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2921,8 +2921,29 @@ static void skl_detach_scalers(struct intel_crtc 
*intel_crtc)
}
 }
 
-u32 skl_plane_ctl_format(uint32_t pixel_format)
+u32 skl_plane_ctl_format(uint32_t pixel_format,
+   enum per_pixel_alpha_state alpha)
 {
+   u32 plane_ctl_alpha = 0;
+
+   if (pixel_format == DRM_FORMAT_ABGR ||
+   pixel_format == DRM_FORMAT_ARGB) {
+
+   switch (alpha) {
+   case DROP_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_DISABLE;
+   break;
+   case PRE_MULTIPLIED_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   break;
+   case NON_PRE_MULTIPLIED_ALPHA:
+   plane_ctl_alpha = PLANE_CTL_ALPHA_HW_PREMULTIPLY;
+   break;
+   default:
+   MISSING_CASE(alpha);
+   }
+   }
+
switch (pixel_format) {
case DRM_FORMAT_C8:
return PLANE_CTL_FORMAT_INDEXED;
@@ -2938,11 +2959,11 @@ u32 skl_plane_ctl_format(uint32_t pixel_format)
 * DRM_FORMAT) for user-space to configure that.
 */
case DRM_FORMAT_ABGR:
-   return PLANE_CTL_FORMAT_XRGB_ | PLANE_CTL_ORDER_RGBX |
-   PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   return ((PLANE_CTL_FORMAT_XRGB_ | (PLANE_CTL_ORDER_RGBX
+   & (~PLANE_CTL_ALPHA_MASK))) | plane_ctl_alpha);
case DRM_FORMAT_ARGB:
-   return PLANE_CTL_FORMAT_XRGB_ |
-   PLANE_CTL_ALPHA_SW_PREMULTIPLY;
+   return ((PLANE_CTL_FORMAT_XRGB_ & ~PLANE_CTL_ALPHA_MASK)
+   | plane_ctl_alpha);
case DRM_FORMAT_XRGB2101010:
return PLANE_CTL_FORMAT_XRGB_2101010;
case DRM_FORMAT_XBGR2101010:
@@ -3031,7 +3052,8 @@ static void skylake_update_primary_plane(struct drm_plane 
*plane,
PLANE_CTL_PIPE_GAMMA_ENABLE |
PLANE_CTL_PIPE_CSC_ENABLE;
 
-   plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
+   plane_ctl |= skl_plane_ctl_format(fb->pixel_format,
+   plane_state->per_pixel_alpha);
plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
plane_ctl |= skl_plane_ctl_rotation(rotation);
@@ -3087,6 +3109,69 @@ static void skylake_update_primary_plane(struct 
drm_plane *plane,
POSTING_READ(PLANE_SURF(pipe, 0));
 }
 
+static int intel_plane_state_check_blend(struct drm_plane_state *plane_state)
+{
+   struct drm_device *dev = plane_state->state->dev;
+   struct intel_plane_state *state = to_intel_plane_state(plane_state);
+   const struct drm_framebuffer *fb = plane_state->fb;
+   const struct drm_blend_mode *mode = >base.blend_mode;
+   bool has_per_pixel_blending;
+
+   /*
+* We don't install the properties pre-SKL, so this is SKL+ specific
+* code for now.
+*/
+   if (INTEL_INFO(dev)->gen < 9)
+   return 0;
+
+   if (!fb)
+   return 0;
+
+   has_per_pixel_blending = fb->pixel_format == DRM_FORMAT_ABGR ||
+   fb->pixel_format == DRM_FORMAT_RGBA ||
+   fb->pixel_format == DRM_FORMAT_ARGB ||
+   fb->pixel_format == DRM_FORMAT_BGRA;
+
+   /* drop alpha for all fbs without an alpha channel */
+   if (!has_per_pixel_blending)
+   state->per_pixel_alpha = DROP_ALPHA;
+
+   switch (mode->func) {
+   /*
+* The 'AUTO' behaviour is the default and keeps compatibility with
+* kernels before the introduction of the blend_func property:
+*   - pre-multiplied alpha if the fb has an alpha channel
+*   - usual DRM_BLEND_FUNC(ONE, ZERO) otherwise
+*/
+   case