[RFC PATCH] drm: Add per-plane pixel blend mode property

2018-05-09 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Add a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Signed-off-by: Lowry Li <lowry...@arm.com>
---
 drivers/gpu/drm/drm_atomic.c|  4 ++
 drivers/gpu/drm/drm_atomic_helper.c |  1 +
 drivers/gpu/drm/drm_blend.c | 95 +
 include/drm/drm_blend.h |  6 +++
 include/drm/drm_plane.h |  7 +++
 5 files changed, 113 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a567310..0bb6de1 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -764,6 +764,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
state->src_w = val;
} else if (property == config->prop_src_h) {
state->src_h = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_ROTATE_MASK))
return -EINVAL;
@@ -826,6 +828,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
*val = state->src_w;
} else if (property == config->prop_src_h) {
*val = state->src_h;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 01d936b..e4377fd 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3133,6 +3133,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
if (plane->state) {
plane->state->plane = plane;
plane->state->rotation = DRM_ROTATE_0;
+   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
}
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 665aafc..bb938de 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -98,6 +98,12 @@
  *   planes. Without this property the primary plane is always below the cursor
  *   plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
  * Note that all the property extensions described here apply either to the
  * plane or the CRTC (e.g. for the background color, which currently is not
  * exposed and assumed to be black).
@@ -405,3 +411,92 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
return 0;
 }
 EXPORT_SYMBOL(drm_atomic_normalize_zpos);
+
+/**
+ * drm_plane_create_blend_mode_property - create a new blend mode property
+ * @plane: drm plane
+ * @supported_modes: bitmask of supported modes, must include
+ *  BIT(DRM_MODE_BLEND_PREMULTI)
+ *
+ * This creates a new property describing the blend mode.
+ *
+ * The property exposed to userspace is an enumeration property (see
+ * drm_property_create_enum()) called "pixel blend mode" and has the
+ * following enumeration values:
+ *
+ * DRM_MODE_BLEND_PIXEL_NONE: Blend formula that ignores the pixel alpha.
+ * "None"
+ * out.rgb = plane.alpha * pixel.rgb + (1 - plane.alpha) * bg.rgb
+ *
+ * DRM_MODE_BLEND_PREMULTI: Blend formula that assumes the pixel color values
+ * have been already pre-multiplied with the alpha
+ * channel values.
+ * "Pre-multiplied"
+ * out.rgb = plane.alpha * pixel.rgb +
+ *   (1 - (plane.alpha * pixel.alpha)) * bg.rgb
+ *
+ * DRM_MODE_BLEND_COVERAGE: Blend formula that assumes the pixel color values
+ * have not been pre-multiplied and will do so when
+ * blending them to the background color values.
+ * "Coverage"
+ * out.rgb = plane.alpha * pixel.alpha * pixel.rgb +
+ *   (1 - (plane.alpha * pixel.alpha)) * bg.rgb
+ *
+ * This property has no effect on formats with no pixel alpha, as pixel.alpha
+ * is assumed to be 1.0. If the plane does not expose the "alpha" property, 
then
+ * plane.alpha is assumed to be 1.0, otherwise, it is the value of the "alpha"

Re: [RFC PATCH] drm: Add per-plane pixel blend mode property

2018-05-22 Thread Lowry Li
On Wed, May 09, 2018 at 10:08:16AM +0200, Daniel Vetter wrote:
> On Tue, May 08, 2018 at 06:34:36PM +0800, Lowry Li wrote:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Signed-off-by: Lowry Li <lowry...@arm.com>
>
> Some suggestions for the kerneldoc below. lgtm otherwise (but needs the
> driver implementation + userspace support before we can merge).
> -Daniel
Thanks for the review comments.
OK. Driver implementation and userspace support will be committed in
other patchsets.
> > ---
> >  drivers/gpu/drm/drm_atomic.c|  4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |  1 +
> >  drivers/gpu/drm/drm_blend.c | 95 
> > +
> >  include/drm/drm_blend.h |  6 +++
> >  include/drm/drm_plane.h |  7 +++
> >  5 files changed, 113 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index a567310..0bb6de1 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -764,6 +764,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > state->src_w = val;
> > } else if (property == config->prop_src_h) {
> > state->src_h = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_ROTATE_MASK))
> > return -EINVAL;
> > @@ -826,6 +828,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > *val = state->src_w;
> > } else if (property == config->prop_src_h) {
> > *val = state->src_h;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 01d936b..e4377fd 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3133,6 +3133,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane)
> > if (plane->state) {
> > plane->state->plane = plane;
> > plane->state->rotation = DRM_ROTATE_0;
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index 665aafc..bb938de 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -98,6 +98,12 @@
> >   *   planes. Without this property the primary plane is always below the 
> > cursor
> >   *   plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
>
> I think a link here to drm_plane_create_blend_mode_property() for the
> blending equations would be really good.
About the details of blending equations, as your comments below, we
will move them here. And drm_plane_create_blend_mode_property()
already has a link which can take the reader to the function easily.
> > + *
> >   * Note that all the property extensions described here apply either to the
> >   * plane or the CRTC (e.g. for the background color, which currently is not
> >   * exposed and assumed to be black).
> > @@ -405,3 +411,92 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> > return 0;
> >  }
> >  EXPORT_SYMBOL(drm_atomic_normalize_zpos);
> > +
> > +/**
> > + * drm_plane_create_blend_mode_property - create a new blend mode property
> > + * @plane: drm plane
> > + * @supported_modes: bitmask of supported modes, must include
> &g

Re: [RFC PATCH] drm: Add per-plane pixel blend mode property

2018-05-22 Thread Lowry Li
On Wed, May 09, 2018 at 01:48:06PM +0300, Ville Syrjälä wrote:
> On Tue, May 08, 2018 at 06:34:36PM +0800, Lowry Li wrote:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> > 
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> > 
> > Defines three blend modes in drm_blend.h.
> > 
> > Signed-off-by: Lowry Li <lowry...@arm.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c|  4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |  1 +
> >  drivers/gpu/drm/drm_blend.c | 95 
> > +
> >  include/drm/drm_blend.h |  6 +++
> >  include/drm/drm_plane.h |  7 +++
> >  5 files changed, 113 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index a567310..0bb6de1 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -764,6 +764,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > state->src_w = val;
> > } else if (property == config->prop_src_h) {
> > state->src_h = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_ROTATE_MASK))
> > return -EINVAL;
> > @@ -826,6 +828,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > *val = state->src_w;
> > } else if (property == config->prop_src_h) {
> > *val = state->src_h;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 01d936b..e4377fd 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3133,6 +3133,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane)
> > if (plane->state) {
> > plane->state->plane = plane;
> > plane->state->rotation = DRM_ROTATE_0;
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index 665aafc..bb938de 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -98,6 +98,12 @@
> >   *   planes. Without this property the primary plane is always below the 
> > cursor
> >   *   plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
> > + *
> >   * Note that all the property extensions described here apply either to the
> >   * plane or the CRTC (e.g. for the background color, which currently is not
> >   * exposed and assumed to be black).
> > @@ -405,3 +411,92 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> > return 0;
> >  }
> >  EXPORT_SYMBOL(drm_atomic_normalize_zpos);
> > +
> > +/**
> > + * drm_plane_create_blend_mode_property - create a new blend mode property
> > + * @plane: drm plane
> > + * @supported_modes: bitmask of supported modes, must include
> > + *  BIT(DRM_MODE_BLEND_PREMULTI)
> > + *
> > + * This creates a new property describing the blend mode.
> > + *
> > + * The property exposed to userspace is an enumeration property (see
> > + * drm_property_create_enum()) called "pixel blend mode" and has the
> > + * following enumeration values:
> > + *
> > + * DRM_MODE_BLEND_PIXEL_NONE: Blend formula that ignores the pixel alpha.
> > + * "None"
> > + * out.rgb = plane.alpha * pixel.rgb + (1 - plane.alpha) * bg.rgb
> > + *
> > + * DRM_MODE_BL

Re: [RFC PATCH] drm: Add per-plane pixel blend mode property

2018-05-22 Thread Lowry Li
On Thu, May 17, 2018 at 10:05:35AM +0200, Maarten Lankhorst wrote:
> Op 08-05-18 om 12:34 schreef Lowry Li:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Signed-off-by: Lowry Li <lowry...@arm.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c|  4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |  1 +
> >  drivers/gpu/drm/drm_blend.c | 95 
> > +
> >  include/drm/drm_blend.h |  6 +++
> >  include/drm/drm_plane.h |  7 +++
> >  5 files changed, 113 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index a567310..0bb6de1 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -764,6 +764,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > state->src_w = val;
> > } else if (property == config->prop_src_h) {
> > state->src_h = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_ROTATE_MASK))
> > return -EINVAL;
> > @@ -826,6 +828,8 @@ int drm_atomic_plane_set_property(struct drm_plane 
> > *plane,
> > *val = state->src_w;
> > } else if (property == config->prop_src_h) {
> > *val = state->src_h;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 01d936b..e4377fd 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3133,6 +3133,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane)
> > if (plane->state) {
> > plane->state->plane = plane;
> > plane->state->rotation = DRM_ROTATE_0;
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index 665aafc..bb938de 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -98,6 +98,12 @@
> >   *   planes. Without this property the primary plane is always below the 
> > cursor
> >   *   plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
> > + *
> >   * Note that all the property extensions described here apply either to the
> >   * plane or the CRTC (e.g. for the background color, which currently is not
> >   * exposed and assumed to be black).
> > @@ -405,3 +411,92 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> > return 0;
> >  }
> >  EXPORT_SYMBOL(drm_atomic_normalize_zpos);
> > +
> > +/**
> > + * drm_plane_create_blend_mode_property - create a new blend mode property
> > + * @plane: drm plane
> > + * @supported_modes: bitmask of supported modes, must include
> > + *  BIT(DRM_MODE_BLEND_PREMULTI)
> > + *
> > + * This creates a new property describing the blend mode.
> > + *
> > + * The property exposed to userspace is an enumeration property (see
> > + * drm_property_create_enum()) called "pixel blend mode" and has the
> > + * following enumeration values:
> > + *
> > + * DRM_MODE_BLEND_PIXEL_NONE: Blend formula that ignores the pixel alpha.
> > + * "None"
> > + * out.rgb = plane.alpha * pixel.rgb + (1 - plane.alpha) * bg.rgb
> > + *
> > + * DRM_MODE_BLEND_PREMULT

Re: [PATCH v2 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-05-31 Thread Lowry Li
On Wed, May 30, 2018 at 02:34:33PM +0100, Brian Starkey wrote:
> Hi Lowry,
> 
> On Wed, May 30, 2018 at 07:23:54PM +0800, Lowry Li wrote:
> >Check the pixel blending mode and plane alpha value when
> >do the plane_check. Mali DP supports blending the current plane
> >with the background either based on the pixel alpha blending
> >mode or by using the layer's alpha value, but not both at the
> >same time. If both case, plane_check will return failed.
> >
> >Set the HW when doing plane_update accordingly. If plane alpha
> >is the 0x, set the PREM bit accordingly. If not we'd set
> >ALPHA bit as zero and layer alpha value.
> 
> The code looks correct - but the description of the PREM bit seems
> wrong here. Did you mean "set the pixel blending bits accordingly"?
> 
> With that fixed:
> 
> Reviewed-by: Brian Starkey 
> 
Hi Brian,

PREM bit is PREMULTI bit to be set premulti or coverage bit
accordingly. But yes, I think I'd change to use "set pixel blending
bits accordingly" to make it entirety :)
Thanks for the review.

> >
> >Signed-off-by: Lowry Li 
> >---
> >drivers/gpu/drm/arm/malidp_planes.c | 76 
> >+
> >1 file changed, 44 insertions(+), 32 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
> >b/drivers/gpu/drm/arm/malidp_planes.c
> >index 7a44897..daa3f4f 100644
> >--- a/drivers/gpu/drm/arm/malidp_planes.c

> >+++ b/drivers/gpu/drm/arm/malidp_planes.c
> >@@ -35,6 +35,7 @@
> >#define   LAYER_COMP_MASK(0x3 << 12)
> >#define   LAYER_COMP_PIXEL   (0x3 << 12)
> >#define   LAYER_COMP_PLANE   (0x2 << 12)
> >+#define   LAYER_PMUL_ENABLE (0x1 << 14)
> >#define   LAYER_ALPHA_OFFSET (16)
> >#define   LAYER_ALPHA_MASK   (0xff)
> >#define   LAYER_ALPHA(x) (((x) & LAYER_ALPHA_MASK) << 
> >LAYER_ALPHA_OFFSET)
> >@@ -182,6 +183,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
> > struct malidp_plane_state *ms = to_malidp_plane_state(state);
> > bool rotated = state->rotation & MALIDP_ROTATED_MASK;
> > struct drm_framebuffer *fb;
> >+u16 pixel_alpha = state->pixel_blend_mode;
> > int i, ret;
> >
> > if (!state->crtc || !state->fb)
> >@@ -244,6 +246,11 @@ static int malidp_de_plane_check(struct drm_plane 
> >*plane,
> > ms->rotmem_size = val;
> > }
> >
> >+/* HW can't support plane + pixel blending */
> >+if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
> >+(pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
> >+return -EINVAL;
> >+
> > return 0;
> >}
> >
> >@@ -325,31 +332,33 @@ static void malidp_de_plane_update(struct drm_plane 
> >*plane,
> >{
> > struct malidp_plane *mp;
> > struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
> >+struct drm_plane_state *state = plane->state;
> >+u16 pixel_alpha = state->pixel_blend_mode;
> >+u8 plane_alpha = state->alpha >> 8;
> > u32 src_w, src_h, dest_w, dest_h, val;
> > int i;
> >-bool format_has_alpha = plane->state->fb->format->has_alpha;
> >
> > mp = to_malidp_plane(plane);
> >
> > /* convert src values from Q16 fixed point to integer */
> >-src_w = plane->state->src_w >> 16;
> >-src_h = plane->state->src_h >> 16;
> >-dest_w = plane->state->crtc_w;
> >-dest_h = plane->state->crtc_h;
> >+src_w = state->src_w >> 16;
> >+src_h = state->src_h >> 16;
> >+dest_w = state->crtc_w;
> >+dest_h = state->crtc_h;
> >
> > malidp_hw_write(mp->hwdev, ms->format, mp->layer->base);
> >
> > for (i = 0; i < ms->n_planes; i++) {
> > /* calculate the offset for the layer's plane registers */
> > u16 ptr = mp->layer->ptr + (i << 4);
> >-dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
> >- plane->state, i);
> >+dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
> >+ state, i);
> >
> > malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
> > malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
> > }
> > mal

Re: [PATCH v2 0/2] drm/blend: Add per-plane pixel blend mode property

2018-05-31 Thread Lowry Li
On Wed, May 30, 2018 at 10:40:40AM -0400, Sean Paul wrote:
> On Wed, May 30, 2018 at 07:23:52PM +0800, Lowry Li wrote:
> > Hi,
> > 
> > This serie aims at adding the support for pixel blend modes represent the
> > alpha blending equation selection in the driver. It also introduces to use
> > it in the malidp driver.
> > 
> > Let me know what you think,
> 
> Hi Lowry,
> Thank you for doing this work. I know this is something that is missing for
> proper Android support, so it's most welcome.
> 
> Do you have userspace patches using this property?
> 
> Sean
> 
> 
Hi Sean,
Thanks a lot for the reply. Yes, we have userspace patches, which is
on the way. Will let you know once it's ready.

Thanks,
Lowry
> > Lowry
> > 
> > Changes for v2:
> >  - Moves the blending equation into the DOC comment
> >  - Refines the comments of drm_plane_create_blend_mode_property to not
> >enumerate the #defines, but instead the string values
> >  - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
> >  - Introduces to use it in the malidp driver, which depends on the plane
> >alpha patch
> > 
> > Changes from v1:
> >  - v1 is just the core changes to request for commments
> >  - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
> >drm_plane, and related support functions
> >  - Defines three blend modes in drm_blend.h
> >  - Rebased on current drm-next
> > 
> > Lowry Li (2):
> >   drm/blend: Add per-plane pixel blend mode property
> >   drm/mali-dp: Implement plane alpha and pixel blend on malidp
> > 
> >  drivers/gpu/drm/arm/malidp_planes.c |  76 ++---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 110 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   6 ++
> >  6 files changed, 171 insertions(+), 32 deletions(-)
> > 
> > -- 
> > 1.9.1
> > 
> 
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/2] drm/blend: Add per-plane pixel blend mode property

2018-05-31 Thread Lowry Li
On Thu, May 31, 2018 at 11:36:47AM +0200, Maarten Lankhorst wrote:
> Hey,
> 
> Op 30-05-18 om 13:23 schreef Lowry Li:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Signed-off-by: Lowry Li 
> > ---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 110 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   6 ++
> >  5 files changed, 127 insertions(+)
> Can you rebase this on top of a kernel with alpha property support? Getting 
> some nasty conflicts otherwise..
> 
> ~Maarten
Dear Maarten,

Yes, I will rebase this on top of drm-misc-next branch with alpha
property support.
-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


drm/blend: Add per-plane pixel blend mode property

2018-05-30 Thread Lowry Li
daniel.vet...@intel.com,jani.nik...@linux.intel.com,seanp...@chromium.org,airl...@linux.ie,dri-devel@lists.freedesktop.org,linux-ker...@vger.kernel.org,brian.star...@arm.com,n...@arm.com
Bcc: lowry...@arm.com
Subject: drm/blend: Add per-plane pixel blend mode property
Reply-To: 


-- 
Regards,
Lowry
>From 7b3b4cae2b0283076b47775efdf5dbbf75a8d859 Mon Sep 17 00:00:00 2001
From: Lowry Li 
Date: Wed, 30 May 2018 15:04:53 +0800
Subject: [PATCH v2 0/2] drm/blend: Add per-plane pixel blend mode property

Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
   drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  65 ++---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 110 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   7 +++
 6 files changed, 174 insertions(+), 19 deletions(-)

-- 
1.9.1

>From 86d2123481c749233afb51d4f651c2b84f8bf225 Mon Sep 17 00:00:00 2001
From: Lowry Li 
Date: Fri, 25 May 2018 19:18:37 +0800
Subject: [PATCH v2 1/2] drm: Add per-plane pixel blend mode property

Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Add a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 110 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   7 +++
 5 files changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a567310..0bb6de1 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -764,6 +764,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
 		state->src_w = val;
 	} else if (property == config->prop_src_h) {
 		state->src_h = val;
+	} else if (property == plane->blend_mode_property) {
+		state->pixel_blend_mode = val;
 	} else if (property == plane->rotation_property) {
 		if (!is_power_of_2(val & DRM_ROTATE_MASK))
 			return -EINVAL;
@@ -826,6 +828,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
 		*val = state->src_w;
 	} else if (property == config->prop_src_h) {
 		*val = state->src_h;
+	} else if (property == plane->blend_mode_property) {
+		*val = state->pixel_blend_mode;
 	} else if (property == plane->rotation_property) {
 		*val = state->rotation;
 	} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 01d936b..e4377fd 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3133,6 +3133,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
 	if (plane->state) {
 		plane->state->plane = plane;
 		plane->state->rotation = DRM_ROTATE_0;
+		plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 	}
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 665aafc..abeb995 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -98,6 +98,41 @@
  *   planes. Without this property the primary plane is always below the cursor
  *   plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ *	Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ *	It adds a blend mode for alpha blending equation selection, describing
+ *	how the pixels from the current plane are composited with the
+ *	background.
+ *
+ *	Three alpha blending equations(note that the fg.rgb or bg.rgb notation
+ *	means each of the R, G or B channels for the foreground and background
+ *	colors, respectively):
+ *
+ *	"None": Blend formula that ignor

[PATCH v2 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-05-30 Thread Lowry Li
Check the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Set the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the PREM bit accordingly. If not we'd set
ALPHA bit as zero and layer alpha value.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/malidp_planes.c | 76 +
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 7a44897..daa3f4f 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -35,6 +35,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -182,6 +183,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -244,6 +246,11 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
+   return -EINVAL;
+
return 0;
 }
 
@@ -325,31 +332,33 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
malidp_hw_write(mp->hwdev, ms->format, mp->layer->base);
 
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +371,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VAL(plane->state->crtc_y),
+   malidp_hw_write(mp->hwdev, LAYER_H_VAL(state->crtc_x) |
+   LAYER_V_VAL(state->crtc_y),
mp->layer->base + MALIDP_LAYER_OFFSET);
 
if (mp->layer->id == DE_SMART)
@@ -376,38 +385,35 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
val &= ~LAYER_ROT_MASK;
 
/* setup the rotation and axis flip bits */
-   if (plane->state->rotation & DRM_MODE_ROTATE_MASK)
+   if (state->rotation &

[PATCH v2 1/2] drm/blend: Add per-plane pixel blend mode property

2018-05-30 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Add a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 110 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   6 ++
 5 files changed, 127 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 7d25c42..467f8de 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -783,6 +783,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_w = val;
} else if (property == config->prop_src_h) {
state->src_h = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
return -EINVAL;
@@ -848,6 +850,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
*val = state->src_w;
} else if (property == config->prop_src_h) {
*val = state->src_h;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index c356545..ddbd0d2 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3484,6 +3484,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
if (plane->state) {
plane->state->plane = plane;
plane->state->rotation = DRM_MODE_ROTATE_0;
+   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
}
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 5a81e1b..4ac45da 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -100,6 +100,41 @@
  * planes. Without this property the primary plane is always below the 
cursor
  * plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
+ * Three alpha blending equations(note that the fg.rgb or bg.rgb notation
+ * means each of the R, G or B channels for the foreground and background
+ * colors, respectively):
+ *
+ * "None": Blend formula that ignores the pixel alpha.
+ * out.rgb = plane_alpha * fg.rgb + (1 - plane_alpha) * bg.rgb
+ *
+ * "Pre-multiplied": Blend formula that assumes the pixel color values
+ * have been already pre-multiplied with the alpha
+ * channel values.
+ * out.rgb = plane_alpha * fg.rgb + (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ * "Coverage": Blend formula that assumes the pixel color values have not
+ * been pre-multiplied and will do so when blending them to the background
+ * color values.
+ * out.rgb = plane_alpha * fg.alpha * fg.rgb +
+ *   (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ * fg.rgb: Each of the RGB component values from the plane's pixel
+ * fg.alpha: Alpha component value from the plane's pixel
+ * bg.rgb: Each of the RGB component values from the background
+ * plane_alpha: Plane alpha value set by the plane alpha property (if
+ *  applicable).
+ *
+ * This property has no effect on formats with no pixel alpha, as fg.alpha
+ * is assumed to be 1.0. If the plane does not expose the "alpha" property,
+ * then plane_alpha is assumed to be 1.0, otherwise, it is the value of the
+ * "alpha" property.
+ *
  * Note that all the property extensions described here apply either to the
  * plane or the CRTC (e.g. for the background color, which currently is not
  * exposed and assumed to be black).
@@ -409,3 +444,78 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
return 0;
 }
 EXPORT_SYMBOL(drm_atomic_normalize_zpos);
+
+/**
+ * drm_plane_create_blend_mode_property - create a new blend mode property
+ * @plane: drm plane
+ * @supported_modes: bitmask of supported

[PATCH v2 0/2] drm/blend: Add per-plane pixel blend mode property

2018-05-30 Thread Lowry Li
Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver, which depends on the plane
   alpha patch

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
   drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm/blend: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  76 ++---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 110 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   6 ++
 6 files changed, 171 insertions(+), 32 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 0/2] drm/blend: Add per-plane pixel blend mode property

2018-06-04 Thread Lowry Li
On Thu, May 31, 2018 at 06:22:26PM +0800, Lowry Li wrote:
> On Wed, May 30, 2018 at 10:40:40AM -0400, Sean Paul wrote:
> > On Wed, May 30, 2018 at 07:23:52PM +0800, Lowry Li wrote:
> > > Hi,
> > > 
> > > This serie aims at adding the support for pixel blend modes represent the
> > > alpha blending equation selection in the driver. It also introduces to use
> > > it in the malidp driver.
> > > 
> > > Let me know what you think,
> > 
> > Hi Lowry,
> > Thank you for doing this work. I know this is something that is missing for
> > proper Android support, so it's most welcome.
> > 
> > Do you have userspace patches using this property?
> > 
> > Sean
> > 
> > 
> Hi Sean,
> Thanks a lot for the reply. Yes, we have userspace patches, which is
> on the way. Will let you know once it's ready.
> 
> Thanks,
> Lowry
Hi Sean,
We've created a merge request on userspace patches. Please kindly check the
following link address at your time. Thanks:)
https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/merge_requests/16

Regards
Lowry
> > > Lowry
> > > 
> > > Changes for v2:
> > >  - Moves the blending equation into the DOC comment
> > >  - Refines the comments of drm_plane_create_blend_mode_property to not
> > >enumerate the #defines, but instead the string values
> > >  - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
> > >  - Introduces to use it in the malidp driver, which depends on the plane
> > >alpha patch
> > > 
> > > Changes from v1:
> > >  - v1 is just the core changes to request for commments
> > >  - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
> > >drm_plane, and related support functions
> > >  - Defines three blend modes in drm_blend.h
> > >  - Rebased on current drm-next
> > > 
> > > Lowry Li (2):
> > >   drm/blend: Add per-plane pixel blend mode property
> > >   drm/mali-dp: Implement plane alpha and pixel blend on malidp
> > > 
> > >  drivers/gpu/drm/arm/malidp_planes.c |  76 ++---
> > >  drivers/gpu/drm/drm_atomic.c|   4 ++
> > >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> > >  drivers/gpu/drm/drm_blend.c | 110 
> > > 
> > >  include/drm/drm_blend.h |   6 ++
> > >  include/drm/drm_plane.h |   6 ++
> > >  6 files changed, 171 insertions(+), 32 deletions(-)
> > > 
> > > -- 
> > > 1.9.1
> > > 
> > 
> > -- 
> > Sean Paul, Software Engineer, Google / Chromium OS
> 
> -- 
> Regards,
> Lowry

-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/2] drm/blend: Add per-plane pixel blend mode property

2018-06-01 Thread Lowry Li
On Thu, May 31, 2018 at 03:51:37PM +0100, Emil Velikov wrote:
> Hi Lowry,
> 
> Small drive-by suggestion. Haven't checked if others have pointed it
> out previously :-\
> 
> On 30 May 2018 at 12:23, Lowry Li  wrote:
> 
> > +/**
> > + * drm_plane_create_blend_mode_property - create a new blend mode property
> > + * @plane: drm plane
> > + * @supported_modes: bitmask of supported modes, must include
> > + *  BIT(DRM_MODE_BLEND_PREMULTI)
> > + *
> There are two possible blend modes (ignoring 'none'), yet premult must
> be supported.
> What if the hardware can do only "coverage"?
> 
> One-liner explaining why things are as-is would be a great move.
> 
> HTH
> Emil
Hi Emil,

Thanks for your comments. Yes, we'd add explaining on the comments of
the function.
About why and regarding supporting more than pre-mult, because the
current DRM assumption is that alpha is premultiplied, and old
userspace can break if the property defaults to coverage.
Please also refer to the discuss record as below on IRC.
https://people.freedesktop.org/~cbrill/dri-log/?channel=dri-devel_names==2018-04-25_html=true
Please read from around 12:45 to 12:49. :)

-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-06-01 Thread Lowry Li
1. Check the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

2. Set the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/malidp_planes.c | 76 +
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 7a44897..daa3f4f 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -35,6 +35,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -182,6 +183,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -244,6 +246,11 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
+   return -EINVAL;
+
return 0;
 }
 
@@ -325,31 +332,33 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
malidp_hw_write(mp->hwdev, ms->format, mp->layer->base);
 
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +371,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VAL(plane->state->crtc_y),
+   malidp_hw_write(mp->hwdev, LAYER_H_VAL(state->crtc_x) |
+   LAYER_V_VAL(state->crtc_y),
mp->layer->base + MALIDP_LAYER_OFFSET);
 
if (mp->layer->id == DE_SMART)
@@ -376,38 +385,35 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
val &= ~LAYER_ROT_MASK;
 
/* setup the rotation and axis flip bits */
-   if (plane->state->rotation & DRM_MODE_ROTATE_MASK)
+   if (state

[PATCH v3 1/2] drm: Add per-plane pixel blend mode property

2018-06-01 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Add a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   5 ++
 5 files changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 07fef42..1d18389 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -785,6 +785,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_h = val;
} else if (property == plane->alpha_property) {
state->alpha = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
return -EINVAL;
@@ -852,6 +854,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
*val = state->src_h;
} else if (property == plane->alpha_property) {
*val = state->alpha;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 130da51..7f5d463 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3515,6 +3515,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
*plane)
/* Reset the alpha value to fully opaque if it matters */
if (plane->alpha_property)
plane->state->alpha = plane->alpha_property->values[1];
+   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
}
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index a16a74d..ac6f19c 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -107,6 +107,52 @@
  * planes. Without this property the primary plane is always below the 
cursor
  * plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
+ *  Three alpha blending equations are defined:
+ *
+ *  "None":
+ *  Blend formula that ignores the pixel alpha::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - plane_alpha) * bg.rgb
+ *
+ *  "Pre-multiplied":
+ *  Blend formula that assumes the pixel color values
+ *  have been already pre-multiplied with the alpha
+ *  channel values::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  "Coverage":
+ *  Blend formula that assumes the pixel color values have not
+ *  been pre-multiplied and will do so when blending them to the
+ *  background color values::
+ *
+ *  out.rgb = plane_alpha * fg.alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  Using the following symbols:
+ *
+ *  ``fg.rgb``:
+ *  Each of the RGB component values from the plane's pixel
+ *  ``fg.alpha``:
+ *  Alpha component value from the plane's pixel. If the plane's
+ *  pixel format has no alpha component, then this is assumed to be
+ *  1.0. In these cases, this property has no effect, as all three
+ *  equations become equivalent.
+ *  ``bg.rgb``:
+ *  Each of the RGB component values from the background
+ *  ``plane_alpha``:
+ *  Plane alpha value set by the plane "alpha" property. If the
+ *  plane does not expose the "alpha" property, then this is
+ *  assumed to be 1.0
+ *
  * Note that all the property extensions described here apply either to the
  * plane or the CRTC (e.g. for the background color, which currently i

[PATCH v3 0/2] drm/blend: Add per-plane pixel blend mode property

2018-06-01 Thread Lowry Li
Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v3:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
 - Refines the comments of drm/mali-dp patchset
 - Rebased on drm-misc-next and fixed the confilcts with plane alpha patch

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver, which depends on the plane
   alpha patch

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
   drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  76 +-
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   5 ++
 6 files changed, 186 insertions(+), 32 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/2] drm/blend: Add per-plane pixel blend mode property

2018-06-01 Thread Lowry Li
On Wed, May 30, 2018 at 02:27:55PM +0100, Brian Starkey wrote:
> Hi Lowry,
> 
> On Wed, May 30, 2018 at 07:23:53PM +0800, Lowry Li wrote:
> >Pixel blend modes represent the alpha blending equation
> >selection, describing how the pixels from the current
> >plane are composited with the background.
> >
> >Add a pixel_blend_mode to drm_plane_state and a
> >blend_mode_property to drm_plane, and related support
> >functions.
> >
> >Defines three blend modes in drm_blend.h.
> >
> >Signed-off-by: Lowry Li 
> 
> With or without the kerneldoc tweaks I've suggested below, this patch
> is:
> 
> Reviewed-by: Brian Starkey 
> 
Hi Brian,

Thanks for the patch and comments. Will update a new patchset with this.

Regards,
Lowry
> >---
> >drivers/gpu/drm/drm_atomic.c|   4 ++
> >drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >drivers/gpu/drm/drm_blend.c | 110 
> >
> >include/drm/drm_blend.h |   6 ++
> >include/drm/drm_plane.h |   6 ++
> >5 files changed, 127 insertions(+)
> >
> >diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >index 7d25c42..467f8de 100644
> >--- a/drivers/gpu/drm/drm_atomic.c
> >+++ b/drivers/gpu/drm/drm_atomic.c
> >@@ -783,6 +783,8 @@ static int drm_atomic_plane_set_property(struct 
> >drm_plane *plane,
> > state->src_w = val;
> > } else if (property == config->prop_src_h) {
> > state->src_h = val;
> >+} else if (property == plane->blend_mode_property) {
> >+state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> > return -EINVAL;
> >@@ -848,6 +850,8 @@ static int drm_atomic_plane_set_property(struct 
> >drm_plane *plane,
> > *val = state->src_w;
> > } else if (property == config->prop_src_h) {
> > *val = state->src_h;
> >+} else if (property == plane->blend_mode_property) {
> >+*val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> >diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> >b/drivers/gpu/drm/drm_atomic_helper.c
> >index c356545..ddbd0d2 100644
> >--- a/drivers/gpu/drm/drm_atomic_helper.c
> >+++ b/drivers/gpu/drm/drm_atomic_helper.c
> >@@ -3484,6 +3484,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> >*plane)
> > if (plane->state) {
> > plane->state->plane = plane;
> > plane->state->rotation = DRM_MODE_ROTATE_0;
> >+plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >}
> >EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> >diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> >index 5a81e1b..4ac45da 100644
> >--- a/drivers/gpu/drm/drm_blend.c
> >+++ b/drivers/gpu/drm/drm_blend.c
> >@@ -100,6 +100,41 @@
> > *   planes. Without this property the primary plane is always below the 
> > cursor
> > *   plane, and ordering between all other planes is undefined.
> > *
> >+ * pixel blend mode:
> >+ *  Pixel blend mode is set up with drm_plane_create_blend_mode_property().
> >+ *  It adds a blend mode for alpha blending equation selection, describing
> >+ *  how the pixels from the current plane are composited with the
> >+ *  background.
> >+ *
> >+ *  Three alpha blending equations(note that the fg.rgb or bg.rgb notation
> >+ *  means each of the R, G or B channels for the foreground and background
> >+ *  colors, respectively):
> >+ *
> >+ *  "None": Blend formula that ignores the pixel alpha.
> >+ *  out.rgb = plane_alpha * fg.rgb + (1 - plane_alpha) * bg.rgb
> >+ *
> >+ *  "Pre-multiplied": Blend formula that assumes the pixel color values
> >+ *  have been already pre-multiplied with the alpha
> >+ *  channel values.
> >+ *  out.rgb = plane_alpha * fg.rgb + (1 - (plane_alpha * fg.alpha)) * bg.rgb
> >+ *
> >+ *  "Coverage": Blend formula that assumes the pixel color values have not
> >+ *  been pre-multiplied and will do so when blending them to the background
> >+ *  color values.
> >+ *  out.rgb = plane_alpha * fg.alpha * fg.rgb +
> >+ *(1 - (plane_alpha * fg.alpha)) * bg.rgb
> >+ *
> >+ *  fg.rgb: E

Re: [PATCH v3 1/2] drm: Add per-plane pixel blend mode property

2018-06-05 Thread Lowry Li
On Mon, Jun 04, 2018 at 02:49:26PM +0100, Emil Velikov wrote:
> On 1 June 2018 at 13:41, Lowry Li  wrote:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Signed-off-by: Lowry Li 
> > ---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 126 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   5 ++
> >  5 files changed, 142 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 07fef42..1d18389 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -785,6 +785,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > state->src_h = val;
> > } else if (property == plane->alpha_property) {
> > state->alpha = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> > return -EINVAL;
> > @@ -852,6 +854,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > *val = state->src_h;
> > } else if (property == plane->alpha_property) {
> > *val = state->alpha;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 130da51..7f5d463 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3515,6 +3515,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane)
> > /* Reset the alpha value to fully opaque if it matters */
> > if (plane->alpha_property)
> > plane->state->alpha = 
> > plane->alpha_property->values[1];
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index a16a74d..ac6f19c 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -107,6 +107,52 @@
> >   * planes. Without this property the primary plane is always below the 
> > cursor
> >   * plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with 
> > drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, 
> > describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
> > + *
> > + *  Three alpha blending equations are defined:
> > + *
> > + *  "None":
> > + *  Blend formula that ignores the pixel alpha::
> > + *
> > + *  out.rgb = plane_alpha * fg.rgb +
> > + *  (1 - plane_alpha) * bg.rgb
> > + *
> > + *  "Pre-multiplied":
> > + *  Blend formula that assumes the pixel color values
> > + *  have been already pre-multiplied with the alpha
> > + *  channel values::
> > + *
> > + *  out.rgb = plane_alpha * fg.rgb +
> > + *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
> > + *
> > + *  "Coverage":
> > + *  Blend formula that assumes the pixel color values have not
> > + *  been pre-multiplied and will do so when blending them to 
> > the
> > + *  bac

Re: [PATCH v3 1/2] drm: Add per-plane pixel blend mode property

2018-08-13 Thread Lowry Li
On Mon, Aug 13, 2018 at 12:49:13PM +0200, Maarten Lankhorst wrote:
> Op 05-06-18 om 11:07 schreef Lowry Li:
> > On Mon, Jun 04, 2018 at 02:49:26PM +0100, Emil Velikov wrote:
> >> On 1 June 2018 at 13:41, Lowry Li  wrote:
> >>> Pixel blend modes represent the alpha blending equation
> >>> selection, describing how the pixels from the current
> >>> plane are composited with the background.
> >>>
> >>> Add a pixel_blend_mode to drm_plane_state and a
> >>> blend_mode_property to drm_plane, and related support
> >>> functions.
> >>>
> >>> Defines three blend modes in drm_blend.h.
> >>>
> >>> Signed-off-by: Lowry Li 
> >>> ---
> >>>  drivers/gpu/drm/drm_atomic.c|   4 ++
> >>>  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >>>  drivers/gpu/drm/drm_blend.c | 126 
> >>> 
> >>>  include/drm/drm_blend.h |   6 ++
> >>>  include/drm/drm_plane.h |   5 ++
> >>>  5 files changed, 142 insertions(+)
> >>>
> >>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>> index 07fef42..1d18389 100644
> >>> --- a/drivers/gpu/drm/drm_atomic.c
> >>> +++ b/drivers/gpu/drm/drm_atomic.c
> >>> @@ -785,6 +785,8 @@ static int drm_atomic_plane_set_property(struct 
> >>> drm_plane *plane,
> >>> state->src_h = val;
> >>> } else if (property == plane->alpha_property) {
> >>> state->alpha = val;
> >>> +   } else if (property == plane->blend_mode_property) {
> >>> +   state->pixel_blend_mode = val;
> >>> } else if (property == plane->rotation_property) {
> >>> if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> >>> return -EINVAL;
> >>> @@ -852,6 +854,8 @@ static int drm_atomic_plane_set_property(struct 
> >>> drm_plane *plane,
> >>> *val = state->src_h;
> >>> } else if (property == plane->alpha_property) {
> >>> *val = state->alpha;
> >>> +   } else if (property == plane->blend_mode_property) {
> >>> +   *val = state->pixel_blend_mode;
> >>> } else if (property == plane->rotation_property) {
> >>> *val = state->rotation;
> >>> } else if (property == plane->zpos_property) {
> >>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> >>> b/drivers/gpu/drm/drm_atomic_helper.c
> >>> index 130da51..7f5d463 100644
> >>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>> @@ -3515,6 +3515,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> >>> *plane)
> >>> /* Reset the alpha value to fully opaque if it matters */
> >>> if (plane->alpha_property)
> >>> plane->state->alpha = 
> >>> plane->alpha_property->values[1];
> >>> +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> >>> }
> >>>  }
> >>>  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> >>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> >>> index a16a74d..ac6f19c 100644
> >>> --- a/drivers/gpu/drm/drm_blend.c
> >>> +++ b/drivers/gpu/drm/drm_blend.c
> >>> @@ -107,6 +107,52 @@
> >>>   * planes. Without this property the primary plane is always below 
> >>> the cursor
> >>>   * plane, and ordering between all other planes is undefined.
> >>>   *
> >>> + * pixel blend mode:
> >>> + * Pixel blend mode is set up with 
> >>> drm_plane_create_blend_mode_property().
> >>> + * It adds a blend mode for alpha blending equation selection, 
> >>> describing
> >>> + * how the pixels from the current plane are composited with the
> >>> + * background.
> >>> + *
> >>> + *  Three alpha blending equations are defined:
> >>> + *
> >>> + *  "None":
> >>> + *  Blend formula that ignores the pixel alpha::
> >>> + *
> >>> + *  out.rgb = plane_alpha * f

Re: [PATCH v3 1/2] drm: Add per-plane pixel blend mode property

2018-08-14 Thread Lowry Li
On Tue, Aug 14, 2018 at 11:15:43AM +0200, Maarten Lankhorst wrote:
> Op 14-08-18 om 05:11 schreef Lowry Li:
> > On Mon, Aug 13, 2018 at 12:49:13PM +0200, Maarten Lankhorst wrote:
> >> Op 05-06-18 om 11:07 schreef Lowry Li:
> >>> On Mon, Jun 04, 2018 at 02:49:26PM +0100, Emil Velikov wrote:
> >>>> On 1 June 2018 at 13:41, Lowry Li  wrote:
> >>>>> Pixel blend modes represent the alpha blending equation
> >>>>> selection, describing how the pixels from the current
> >>>>> plane are composited with the background.
> >>>>>
> >>>>> Add a pixel_blend_mode to drm_plane_state and a
> >>>>> blend_mode_property to drm_plane, and related support
> >>>>> functions.
> >>>>>
> >>>>> Defines three blend modes in drm_blend.h.
> >>>>>
> >>>>> Signed-off-by: Lowry Li 
> >>>>> ---
> >>>>>  drivers/gpu/drm/drm_atomic.c|   4 ++
> >>>>>  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >>>>>  drivers/gpu/drm/drm_blend.c | 126 
> >>>>> 
> >>>>>  include/drm/drm_blend.h |   6 ++
> >>>>>  include/drm/drm_plane.h |   5 ++
> >>>>>  5 files changed, 142 insertions(+)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>>>> index 07fef42..1d18389 100644
> >>>>> --- a/drivers/gpu/drm/drm_atomic.c
> >>>>> +++ b/drivers/gpu/drm/drm_atomic.c
> >>>>> @@ -785,6 +785,8 @@ static int drm_atomic_plane_set_property(struct 
> >>>>> drm_plane *plane,
> >>>>> state->src_h = val;
> >>>>> } else if (property == plane->alpha_property) {
> >>>>> state->alpha = val;
> >>>>> +   } else if (property == plane->blend_mode_property) {
> >>>>> +   state->pixel_blend_mode = val;
> >>>>> } else if (property == plane->rotation_property) {
> >>>>> if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> >>>>> return -EINVAL;
> >>>>> @@ -852,6 +854,8 @@ static int drm_atomic_plane_set_property(struct 
> >>>>> drm_plane *plane,
> >>>>> *val = state->src_h;
> >>>>> } else if (property == plane->alpha_property) {
> >>>>> *val = state->alpha;
> >>>>> +   } else if (property == plane->blend_mode_property) {
> >>>>> +   *val = state->pixel_blend_mode;
> >>>>> } else if (property == plane->rotation_property) {
> >>>>> *val = state->rotation;
> >>>>> } else if (property == plane->zpos_property) {
> >>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> >>>>> b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>> index 130da51..7f5d463 100644
> >>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>> @@ -3515,6 +3515,7 @@ void drm_atomic_helper_plane_reset(struct 
> >>>>> drm_plane *plane)
> >>>>> /* Reset the alpha value to fully opaque if it matters 
> >>>>> */
> >>>>> if (plane->alpha_property)
> >>>>> plane->state->alpha = 
> >>>>> plane->alpha_property->values[1];
> >>>>> +   plane->state->pixel_blend_mode = 
> >>>>> DRM_MODE_BLEND_PREMULTI;
> >>>>> }
> >>>>>  }
> >>>>>  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> >>>>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> >>>>> index a16a74d..ac6f19c 100644
> >>>>> --- a/drivers/gpu/drm/drm_blend.c
> >>>>> +++ b/drivers/gpu/drm/drm_blend.c
> >>>>> @@ -107,6 +107,52 @@
> >>>>>   * planes. Without this property the primary plane is always below 
> >>>>> the cursor
> >>>>>   * plane, and ordering between all other planes 

Re: [PATCH v4 1/2] drm: Add per-plane pixel blend mode property

2018-08-15 Thread Lowry Li
On Tue, Aug 14, 2018 at 02:23:10PM +0200, Maarten Lankhorst wrote:
> Op 14-08-18 om 13:32 schreef Lowry Li:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Adds a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> Hey,
> 
> The changelog's missing?
> 
> ~Maarten

Hi Maarten,

Will add the changelog. Thanks a lot.
-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 1/2] drm: Add per-plane pixel blend mode property

2018-08-15 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Adds a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Changes since v1:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
Changes since v2:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
Changes since v3:
 - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
   can calculate the index itself just fine, so no point in having the
   caller pass it in.
 - Since the current DRM assumption is that alpha is premultiplied
   as default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
 - Refines some comments.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   2 +
 5 files changed, 139 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3eb061e..d0478ab 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -895,6 +895,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_h = val;
} else if (property == plane->alpha_property) {
state->alpha = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 
0x%llx\n",
@@ -968,6 +970,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
*val = state->src_h;
} else if (property == plane->alpha_property) {
*val = state->alpha;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 6dd5036..563af09 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3569,6 +3569,7 @@ void __drm_atomic_helper_plane_reset(struct drm_plane 
*plane,
/* Reset the alpha value to fully opaque if it matters */
if (plane->alpha_property)
state->alpha = plane->alpha_property->values[1];
+   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 
plane->state = state;
 }
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index a16a74d..24016c9 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -107,6 +107,52 @@
  * planes. Without this property the primary plane is always below the 
cursor
  * plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
+ *  Three alpha blending equations are defined:
+ *
+ *  "None":
+ *  Blend formula that ignores the pixel alpha::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - plane_alpha) * bg.rgb
+ *
+ *  "Pre-multiplied":
+ *  Blend formula that assumes the pixel color values
+ *  have been already pre-multiplied with the alpha
+ *  channel values::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  "Coverage":
+ *  Blend formula that assumes the pixel color values have not
+ *  been pre-multiplied and will do so when blending them to the
+ *  background color values::
+ *
+ *  out.rgb = plane_alpha * fg.alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  Using the following symbols:
+ *
+ *  "fg.rgb":
+ *   

[PATCH v4 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-08-15 Thread Lowry Li
Checks the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Sets the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Changes since v1:
 - Introduces to use it in the malidp driver, which depends on
   the plane alpha patch
Changes since v2:
 - Refines the comments of drm/mali-dp patchset
Changes since v3:
 - Updates on drm/malidp, hardware limitation check only when
   the format has alpha pixel.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/malidp_planes.c | 74 +
 1 file changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6..17be123 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -36,6 +36,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -180,6 +181,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -242,6 +244,11 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
+   return -EINVAL;
+
return 0;
 }
 
@@ -323,17 +330,19 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
val = malidp_hw_read(mp->hwdev, mp->layer->base);
val = (val & ~LAYER_FORMAT_MASK) | ms->format;
@@ -342,14 +351,14 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +371,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VAL(plane->state->crtc_y),
+   malidp_hw_write(mp->hwdev, LAYER_H_VAL(state->crtc_x) |
+ 

[PATCH v4 0/2] drm/blend: Add per-plane pixel blend mode property

2018-08-15 Thread Lowry Li
Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v4:
 - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
   can calculate the index itself just fine, so no point in having the
   caller pass it in.
 - Since the current DRM assumption is that alpha is premultiplied as default,
   define DRM_MODE_BLEND_PREMULTI as 0 will be better.
 - Refines some comments.
 - Updates on drm/malidp, hardware limitation check only when the format has
   alpha pixel.
 - Rebases on drm-misc-next and fixed the confilcts

Changes for v3:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
 - Refines the comments of drm/mali-dp patchset
 - Rebased on drm-misc-next and fixed the confilcts with plane alpha patch

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver, which depends on the plane
   alpha patch

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
   drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  74 -
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   2 +
 6 files changed, 182 insertions(+), 31 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-08-14 Thread Lowry Li
Checks the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Sets the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/malidp_planes.c | 74 +
 1 file changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6..17be123 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -36,6 +36,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -180,6 +181,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -242,6 +244,11 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
+   return -EINVAL;
+
return 0;
 }
 
@@ -323,17 +330,19 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
val = malidp_hw_read(mp->hwdev, mp->layer->base);
val = (val & ~LAYER_FORMAT_MASK) | ms->format;
@@ -342,14 +351,14 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +371,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VAL(plane->state->crtc_y),
+   malidp_hw_write(mp->hwdev, LAYER_H_VAL(state->crtc_x) |
+   LAYER_V_VAL(state->crtc_y),
mp->layer->base + MALIDP_LAYER_OFFSET);
 
if (mp->layer->id == DE_SMART)
@@ -376,38 +385,35 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
val &= ~LAYER_ROT_MASK;
 
/

[PATCH v4 0/2] drm/blend: Add per-plane pixel blend mode property

2018-08-14 Thread Lowry Li
Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v4:
 - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
   can calculate the index itself just fine, so no point in having the
   caller pass it in.
 - Since the current DRM assumption is that alpha is premultiplied as
   default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
 - Refines some comments.
 - Updates on drm/malidp, hardware limitation check only when the format
   has alpha pixel.
 - Rebases on drm-misc-next and fixed the confilcts

Changes for v3:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
 - Refines the comments of drm/mali-dp patchset
 - Rebased on drm-misc-next and fixed the confilcts with plane alpha patch

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver, which depends on the plane
   alpha patch

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property to
   drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  74 -
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   2 +
 6 files changed, 182 insertions(+), 31 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 1/2] drm: Add per-plane pixel blend mode property

2018-08-14 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Adds a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 126 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   2 +
 5 files changed, 139 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3eb061e..d0478ab 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -895,6 +895,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_h = val;
} else if (property == plane->alpha_property) {
state->alpha = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 
0x%llx\n",
@@ -968,6 +970,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
*val = state->src_h;
} else if (property == plane->alpha_property) {
*val = state->alpha;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 6dd5036..563af09 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3569,6 +3569,7 @@ void __drm_atomic_helper_plane_reset(struct drm_plane 
*plane,
/* Reset the alpha value to fully opaque if it matters */
if (plane->alpha_property)
state->alpha = plane->alpha_property->values[1];
+   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 
plane->state = state;
 }
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index a16a74d..24016c9 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -107,6 +107,52 @@
  * planes. Without this property the primary plane is always below the 
cursor
  * plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
+ *  Three alpha blending equations are defined:
+ *
+ *  "None":
+ *  Blend formula that ignores the pixel alpha::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - plane_alpha) * bg.rgb
+ *
+ *  "Pre-multiplied":
+ *  Blend formula that assumes the pixel color values
+ *  have been already pre-multiplied with the alpha
+ *  channel values::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  "Coverage":
+ *  Blend formula that assumes the pixel color values have not
+ *  been pre-multiplied and will do so when blending them to the
+ *  background color values::
+ *
+ *  out.rgb = plane_alpha * fg.alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  Using the following symbols:
+ *
+ *  "fg.rgb":
+ *  Each of the RGB component values from the plane's pixel
+ *  "fg.alpha":
+ *  Alpha component value from the plane's pixel. If the plane's
+ *  pixel format has no alpha component, then this is assumed to be
+ *  1.0. In these cases, this property has no effect, as all three
+ *  equations become equivalent.
+ *  "bg.rgb":
+ *  Each of the RGB component values from the background
+ *  "plane_alpha":
+ *  Plane alpha value set by the plane "alpha" property. If the
+ *  plane does not expose the "alpha" property, then this is
+ *  assumed to be 1.0
+ *
  * Note that all the property extensions described here apply either to the
  * plane or the CRTC (e.g. for the bac

Re: [PATCH v3 1/2] drm: Add per-plane pixel blend mode property

2018-08-14 Thread Lowry Li
On Mon, Jun 04, 2018 at 02:49:26PM +0100, Emil Velikov wrote:
> On 1 June 2018 at 13:41, Lowry Li  wrote:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Add a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Signed-off-by: Lowry Li 
> > ---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 126 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   5 ++
> >  5 files changed, 142 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 07fef42..1d18389 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -785,6 +785,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > state->src_h = val;
> > } else if (property == plane->alpha_property) {
> > state->alpha = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> > return -EINVAL;
> > @@ -852,6 +854,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > *val = state->src_h;
> > } else if (property == plane->alpha_property) {
> > *val = state->alpha;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 130da51..7f5d463 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3515,6 +3515,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane)
> > /* Reset the alpha value to fully opaque if it matters */
> > if (plane->alpha_property)
> > plane->state->alpha = 
> > plane->alpha_property->values[1];
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > }
> >  }
> >  EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index a16a74d..ac6f19c 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -107,6 +107,52 @@
> >   * planes. Without this property the primary plane is always below the 
> > cursor
> >   * plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with 
> > drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, 
> > describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
> > + *
> > + *  Three alpha blending equations are defined:
> > + *
> > + *  "None":
> > + *  Blend formula that ignores the pixel alpha::
> > + *
> > + *  out.rgb = plane_alpha * fg.rgb +
> > + *  (1 - plane_alpha) * bg.rgb
> > + *
> > + *  "Pre-multiplied":
> > + *  Blend formula that assumes the pixel color values
> > + *  have been already pre-multiplied with the alpha
> > + *  channel values::
> > + *
> > + *  out.rgb = plane_alpha * fg.rgb +
> > + *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
> > + *
> > + *  "Coverage":
> > + *  Blend formula that assumes the pixel color values have not
> > + *  been pre-multiplied and will do so when blending them to 
> > the
> > + *  bac

Re: [PATCH v4 1/2] drm: Add per-plane pixel blend mode property

2018-08-23 Thread Lowry Li
On Wed, Aug 22, 2018 at 03:27:44PM +0200, Maarten Lankhorst wrote:
> Op 15-08-18 om 08:35 schreef Lowry Li:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> >
> > Adds a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> >
> > Defines three blend modes in drm_blend.h.
> >
> > Changes since v1:
> >  - Moves the blending equation into the DOC comment
> >  - Refines the comments of drm_plane_create_blend_mode_property to not
> >enumerate the #defines, but instead the string values
> >  - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
> > Changes since v2:
> >  - Refines the comments of drm_plane_create_blend_mode_property:
> >   1) Puts the descriptions (after the ":") on a new line
> >   2) Adds explaining why @supported_modes need PREMUL as default
> > Changes since v3:
> >  - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
> >can calculate the index itself just fine, so no point in having the
> >caller pass it in.
> >  - Since the current DRM assumption is that alpha is premultiplied
> >as default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
> >  - Refines some comments.
> >
> > Signed-off-by: Lowry Li 
> > ---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 126 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   2 +
> >  5 files changed, 139 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 3eb061e..d0478ab 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -895,6 +895,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > state->src_h = val;
> > } else if (property == plane->alpha_property) {
> > state->alpha = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
> > DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 
> > 0x%llx\n",
> > @@ -968,6 +970,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > *val = state->src_h;
> > } else if (property == plane->alpha_property) {
> > *val = state->alpha;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 6dd5036..563af09 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3569,6 +3569,7 @@ void __drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane,
> > /* Reset the alpha value to fully opaque if it matters */
> > if (plane->alpha_property)
> > state->alpha = plane->alpha_property->values[1];
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> >  
> > plane->state = state;
> >  }
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index a16a74d..24016c9 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -107,6 +107,52 @@
> >   * planes. Without this property the primary plane is always below the 
> > cursor
> >   * plane, and ordering between all other planes is undefined.
> >   *
> > + * pixel blend mode:
> > + * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
> > + * It adds a blend mode for alpha blending equation selection, describing
> > + * how the pixels from the current plane are composited with the
> > + * background.
> > + *
> > + *  Three alpha blending equations are defined:
> > + *
> > + *  "None":
> > + *  Blend formula th

Re: [PATCH v4 1/2] drm: Add per-plane pixel blend mode property

2018-08-23 Thread Lowry Li
On Wed, Aug 22, 2018 at 08:39:49AM -0400, Sean Paul wrote:
> On Wed, Aug 15, 2018 at 02:35:32PM +0800, Lowry Li wrote:
> > Pixel blend modes represent the alpha blending equation
> > selection, describing how the pixels from the current
> > plane are composited with the background.
> > 
> > Adds a pixel_blend_mode to drm_plane_state and a
> > blend_mode_property to drm_plane, and related support
> > functions.
> > 
> > Defines three blend modes in drm_blend.h.
> > 
> > Changes since v1:
> >  - Moves the blending equation into the DOC comment
> >  - Refines the comments of drm_plane_create_blend_mode_property to not
> >enumerate the #defines, but instead the string values
> >  - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
> > Changes since v2:
> >  - Refines the comments of drm_plane_create_blend_mode_property:
> >   1) Puts the descriptions (after the ":") on a new line
> >   2) Adds explaining why @supported_modes need PREMUL as default
> > Changes since v3:
> >  - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
> >can calculate the index itself just fine, so no point in having the
> >caller pass it in.
> >  - Since the current DRM assumption is that alpha is premultiplied
> >as default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
> >  - Refines some comments.
> > 
> > Signed-off-by: Lowry Li 
> > ---
> >  drivers/gpu/drm/drm_atomic.c|   4 ++
> >  drivers/gpu/drm/drm_atomic_helper.c |   1 +
> >  drivers/gpu/drm/drm_blend.c | 126 
> > 
> >  include/drm/drm_blend.h |   6 ++
> >  include/drm/drm_plane.h |   2 +
> >  5 files changed, 139 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 3eb061e..d0478ab 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -895,6 +895,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > state->src_h = val;
> > } else if (property == plane->alpha_property) {
> > state->alpha = val;
> > +   } else if (property == plane->blend_mode_property) {
> > +   state->pixel_blend_mode = val;
> > } else if (property == plane->rotation_property) {
> > if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
> > DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 
> > 0x%llx\n",
> > @@ -968,6 +970,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > *val = state->src_h;
> > } else if (property == plane->alpha_property) {
> > *val = state->alpha;
> > +   } else if (property == plane->blend_mode_property) {
> > +   *val = state->pixel_blend_mode;
> > } else if (property == plane->rotation_property) {
> > *val = state->rotation;
> > } else if (property == plane->zpos_property) {
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 6dd5036..563af09 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -3569,6 +3569,7 @@ void __drm_atomic_helper_plane_reset(struct drm_plane 
> > *plane,
> > /* Reset the alpha value to fully opaque if it matters */
> > if (plane->alpha_property)
> > state->alpha = plane->alpha_property->values[1];
> > +   plane->state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> 
> Shouldn't this be state->pixel_blend_mode instead of
> plane->state->pixel_blend_mode?
Hi Sean,
Yeah, will refine this. Thanks for your comments:) 
> >  
> > plane->state = state;
> >  }
> 
> /snip
> 
> -- 
> Sean Paul, Software Engineer, Google / Chromium OS

-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 0/2] drm/blend: Add per-plane pixel blend mode property

2018-08-23 Thread Lowry Li
Hi,

This serie aims at adding the support for pixel blend modes represent the
alpha blending equation selection in the driver. It also introduces to use
it in the malidp driver.

Let me know what you think,
Lowry

Changes for v5:
 - Adds comments in drm_blend.h.
 - Removes setting default value in drm_plane_create_blend_mode_property()
   as it is already in __drm_atomic_helper_plane_reset().
 - Fixes to use state->pixel_blend_mode instead of using
   plane->state->pixel_blend_mode in reset function.
 - Rebases on drm-misc-next.

Changes for v4:
 - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
   can calculate the index itself just fine, so no point in having the
   caller pass it in.
 - Since the current DRM assumption is that alpha is premultiplied as
   default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
 - Refines some comments.
 - Updates on drm/malidp, hardware limitation check only when the format
   has alpha pixel.
 - Rebases on drm-misc-next and fixed the confilcts

Changes for v3:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
 - Refines the comments of drm/mali-dp patchset
 - Rebased on drm-misc-next and fixed the confilcts with plane alpha patch

Changes for v2:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
 - Introduces to use it in the malidp driver, which depends on the plane
   alpha patch

Changes from v1:
 - v1 is just the core changes to request for commments
 - Adds a pixel_blend_mode to drm_plane_state and a blend_mode_property
   to drm_plane, and related support functions
 - Defines three blend modes in drm_blend.h
 - Rebased on current drm-next

Lowry Li (2):
  drm: Add per-plane pixel blend mode property
  drm/mali-dp: Implement plane alpha and pixel blend on malidp

 drivers/gpu/drm/arm/malidp_planes.c |  74 +-
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 123 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   9 +++
 6 files changed, 186 insertions(+), 31 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-08-23 Thread Lowry Li
Checks the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Sets the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Changes since v1:
 - Introduces to use it in the malidp driver, which depends on
   the plane alpha patch
Changes since v2:
 - Refines the comments of drm/mali-dp patchset
Changes since v3:
 - Updates on drm/malidp, hardware limitation check only when
   the format has alpha pixel.
Changes since v4:
 - Rebases on drm-misc-next.

Signed-off-by: Lowry Li 
Acked-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/malidp_planes.c | 74 +
 1 file changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6..17be123 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -36,6 +36,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -180,6 +181,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -242,6 +244,11 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE))
+   return -EINVAL;
+
return 0;
 }
 
@@ -323,17 +330,19 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
val = malidp_hw_read(mp->hwdev, mp->layer->base);
val = (val & ~LAYER_FORMAT_MASK) | ms->format;
@@ -342,14 +351,14 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +371,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VAL(plane->state->crtc_y),
+   malidp_hw_

[PATCH v5 1/2] drm: Add per-plane pixel blend mode property

2018-08-23 Thread Lowry Li
Pixel blend modes represent the alpha blending equation
selection, describing how the pixels from the current
plane are composited with the background.

Adds a pixel_blend_mode to drm_plane_state and a
blend_mode_property to drm_plane, and related support
functions.

Defines three blend modes in drm_blend.h.

Changes since v1:
 - Moves the blending equation into the DOC comment
 - Refines the comments of drm_plane_create_blend_mode_property to not
   enumerate the #defines, but instead the string values
 - Uses fg.* instead of pixel.* and plane_alpha instead of plane.alpha
Changes since v2:
 - Refines the comments of drm_plane_create_blend_mode_property:
  1) Puts the descriptions (after the ":") on a new line
  2) Adds explaining why @supported_modes need PREMUL as default
Changes since v3:
 - Refines drm_plane_create_blend_mode_property(). drm_property_add_enum()
   can calculate the index itself just fine, so no point in having the
   caller pass it in.
 - Since the current DRM assumption is that alpha is premultiplied
   as default, define DRM_MODE_BLEND_PREMULTI as 0 will be better.
 - Refines some comments.
Changes since v4:
 - Adds comments in drm_blend.h.
 - Removes setting default value in drm_plane_create_blend_mode_property()
   as it is already in __drm_atomic_helper_plane_reset().
 - Fixes to use state->pixel_blend_mode instead of using
   plane->state->pixel_blend_mode in reset function.
 - Rebases on drm-misc-next.

Reviewed-by: Liviu Dudau 
Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/drm_atomic.c|   4 ++
 drivers/gpu/drm/drm_atomic_helper.c |   1 +
 drivers/gpu/drm/drm_blend.c | 123 
 include/drm/drm_blend.h |   6 ++
 include/drm/drm_plane.h |   9 +++
 5 files changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3eb061e..d0478ab 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -895,6 +895,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
state->src_h = val;
} else if (property == plane->alpha_property) {
state->alpha = val;
+   } else if (property == plane->blend_mode_property) {
+   state->pixel_blend_mode = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] bad rotation bitmask: 
0x%llx\n",
@@ -968,6 +970,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
*val = state->src_h;
} else if (property == plane->alpha_property) {
*val = state->alpha;
+   } else if (property == plane->blend_mode_property) {
+   *val = state->pixel_blend_mode;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 6dd5036..284a5d2 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3569,6 +3569,7 @@ void __drm_atomic_helper_plane_reset(struct drm_plane 
*plane,
/* Reset the alpha value to fully opaque if it matters */
if (plane->alpha_property)
state->alpha = plane->alpha_property->values[1];
+   state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 
plane->state = state;
 }
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index a16a74d..402b62d 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -107,6 +107,52 @@
  * planes. Without this property the primary plane is always below the 
cursor
  * plane, and ordering between all other planes is undefined.
  *
+ * pixel blend mode:
+ * Pixel blend mode is set up with drm_plane_create_blend_mode_property().
+ * It adds a blend mode for alpha blending equation selection, describing
+ * how the pixels from the current plane are composited with the
+ * background.
+ *
+ *  Three alpha blending equations are defined:
+ *
+ *  "None":
+ *  Blend formula that ignores the pixel alpha::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - plane_alpha) * bg.rgb
+ *
+ *  "Pre-multiplied":
+ *  Blend formula that assumes the pixel color values
+ *  have been already pre-multiplied with the alpha
+ *  channel values::
+ *
+ *  out.rgb = plane_alpha * fg.rgb +
+ *  (1 - (plane_alpha * fg.alpha)) * bg.rgb
+ *
+ *  "Coverage":
+ *  Blend formula that assumes the pixel color values have

[PATCH v5 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-08-31 Thread Lowry Li
Checks the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Sets the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Changes since v1:
 - Introduces to use it in the malidp driver, which depends on
   the plane alpha patch
Changes since v2:
 - Refines the comments of drm/mali-dp patchset
Changes since v3:
 - Adds hardware limitation check
Changes since v4:
 - Updates on drm/malidp, hardware limitation check only when
   the format has alpha pixel.
 - Rebases on drm-misc-next.

Signed-off-by: Lowry Li 
Acked-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/malidp_planes.c | 75 ++---
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6..96ee429 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -36,6 +36,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -180,6 +181,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -242,6 +244,12 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE) &&
+   fb->format->has_alpha)
+   return -EINVAL;
+
return 0;
 }
 
@@ -323,17 +331,19 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
val = malidp_hw_read(mp->hwdev, mp->layer->base);
val = (val & ~LAYER_FORMAT_MASK) | ms->format;
@@ -342,14 +352,14 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +372,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->cr

[PATCH v5 2/2] drm/mali-dp: Implement plane alpha and pixel blend on malidp

2018-08-30 Thread Lowry Li
Checks the pixel blending mode and plane alpha value when
do the plane_check. Mali DP supports blending the current plane
with the background either based on the pixel alpha blending
mode or by using the layer's alpha value, but not both at the
same time. If both case, plane_check will return failed.

Sets the HW when doing plane_update accordingly. If plane alpha
is the 0x, set the pixel blending bits accordingly. If not
we'd set ALPHA bit as zero and layer alpha value.

Changes since v1:
 - Introduces to use it in the malidp driver, which depends on
   the plane alpha patch
Changes since v2:
 - Refines the comments of drm/mali-dp patchset
Changes since v3:
 - Updates on drm/malidp, hardware limitation check only when
   the format has alpha pixel.
Changes since v4:
 - Rebases on drm-misc-next.

Signed-off-by: Lowry Li 
Acked-by: Liviu Dudau 
---
 drivers/gpu/drm/arm/malidp_planes.c | 75 ++---
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index 49c37f6..96ee429 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -36,6 +36,7 @@
 #define   LAYER_COMP_MASK  (0x3 << 12)
 #define   LAYER_COMP_PIXEL (0x3 << 12)
 #define   LAYER_COMP_PLANE (0x2 << 12)
+#define   LAYER_PMUL_ENABLE(0x1 << 14)
 #define   LAYER_ALPHA_OFFSET   (16)
 #define   LAYER_ALPHA_MASK (0xff)
 #define   LAYER_ALPHA(x)   (((x) & LAYER_ALPHA_MASK) << 
LAYER_ALPHA_OFFSET)
@@ -180,6 +181,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
struct malidp_plane_state *ms = to_malidp_plane_state(state);
bool rotated = state->rotation & MALIDP_ROTATED_MASK;
struct drm_framebuffer *fb;
+   u16 pixel_alpha = state->pixel_blend_mode;
int i, ret;
 
if (!state->crtc || !state->fb)
@@ -242,6 +244,12 @@ static int malidp_de_plane_check(struct drm_plane *plane,
ms->rotmem_size = val;
}
 
+   /* HW can't support plane + pixel blending */
+   if ((state->alpha != DRM_BLEND_ALPHA_OPAQUE) &&
+   (pixel_alpha != DRM_MODE_BLEND_PIXEL_NONE) &&
+   fb->format->has_alpha)
+   return -EINVAL;
+
return 0;
 }
 
@@ -323,17 +331,19 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
 {
struct malidp_plane *mp;
struct malidp_plane_state *ms = to_malidp_plane_state(plane->state);
+   struct drm_plane_state *state = plane->state;
+   u16 pixel_alpha = state->pixel_blend_mode;
+   u8 plane_alpha = state->alpha >> 8;
u32 src_w, src_h, dest_w, dest_h, val;
int i;
-   bool format_has_alpha = plane->state->fb->format->has_alpha;
 
mp = to_malidp_plane(plane);
 
/* convert src values from Q16 fixed point to integer */
-   src_w = plane->state->src_w >> 16;
-   src_h = plane->state->src_h >> 16;
-   dest_w = plane->state->crtc_w;
-   dest_h = plane->state->crtc_h;
+   src_w = state->src_w >> 16;
+   src_h = state->src_h >> 16;
+   dest_w = state->crtc_w;
+   dest_h = state->crtc_h;
 
val = malidp_hw_read(mp->hwdev, mp->layer->base);
val = (val & ~LAYER_FORMAT_MASK) | ms->format;
@@ -342,14 +352,14 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
for (i = 0; i < ms->n_planes; i++) {
/* calculate the offset for the layer's plane registers */
u16 ptr = mp->layer->ptr + (i << 4);
-   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb,
-plane->state, i);
+   dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(state->fb,
+state, i);
 
malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr);
malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4);
}
malidp_de_set_plane_pitches(mp, ms->n_planes,
-   plane->state->fb->pitches);
+   state->fb->pitches);
 
if ((plane->state->color_encoding != old_state->color_encoding) ||
(plane->state->color_range != old_state->color_range))
@@ -362,8 +372,8 @@ static void malidp_de_plane_update(struct drm_plane *plane,
malidp_hw_write(mp->hwdev, LAYER_H_VAL(dest_w) | LAYER_V_VAL(dest_h),
mp->layer->base + MALIDP_LAYER_COMP_SIZE);
 
-   malidp_hw_write(mp->hwdev, LAYER_H_VAL(plane->state->crtc_x) |
-   LAYER_V_VA

[RFC PATCH v2] drm/komeda: fixing of DMA mapping sg segment warning

2019-04-04 Thread Lowry Li (Arm Technology China)
Fixing the DMA mapping sg segment warning, which shows "DMA-API: mapping
sg segment longer than device claims to support [len=921600] [max=65536]".
Fixed by setting the max segment size at Komeda driver.

This patch depends on:
- https://patchwork.freedesktop.org/series/54448/
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58976/

Changes since v1:
- Adds member description
- Adds patch denpendency in the comment

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 4 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 7f25e6a..b4902ae 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_DEBUG_FS
 #include 
 #include 
@@ -245,6 +246,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
goto err_cleanup;
}
 
+   dev->dma_parms = >dma_parms;
+   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 29e03c4..83ace71 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -149,6 +149,8 @@ struct komeda_dev {
struct device *dev;
/** @reg_base: the base address of komeda io space */
u32 __iomem   *reg_base;
+   /** @dma_parms: the dma parameters of komeda */
+   struct device_dma_parameters dma_parms;
 
/** @chip: the basic chip information */
struct komeda_chip_info chip;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[RFC PATCH v2] drm/komeda: Creates plane alpha and blend mode properties

2019-04-04 Thread Lowry Li (Arm Technology China)
Creates plane alpha and blend mode properties attached to plane.

This patch depends on:
- https://patchwork.freedesktop.org/series/54448/
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/

Changes since v1:
- Adds patch denpendency in the comment

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 68cd2c9e..aae5e80 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -220,6 +220,17 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_alpha_property(plane);
+   if (err)
+   goto cleanup;
+
+   err = drm_plane_create_blend_mode_property(plane,
+   BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+   BIT(DRM_MODE_BLEND_PREMULTI)   |
+   BIT(DRM_MODE_BLEND_COVERAGE));
+   if (err)
+   goto cleanup;
+
return 0;
 cleanup:
komeda_plane_destroy(plane);
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[RFC PATCH] drm/komeda: fixing of DMA mapping sg segment warning

2019-03-28 Thread Lowry Li (Arm Technology China)
Fixing the DMA mapping sg segment warning, which shows "DMA-API: mapping
sg segment longer than device claims to support [len=921600] [max=65536]".
Fixed by setting the max segment size at Komeda driver.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 4 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 7f25e6a..b4902ae 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_DEBUG_FS
 #include 
 #include 
@@ -245,6 +246,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
goto err_cleanup;
}
 
+   dev->dma_parms = >dma_parms;
+   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 0c3e32b..d8cfa92 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -146,6 +146,7 @@ enum {
  */
 struct komeda_dev {
struct device *dev;
+   struct device_dma_parameters dma_parms;
u32 __iomem   *reg_base;
 
struct komeda_chip_info chip;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[RFC PATCH] drm/komeda: Creates plane alpha and blend mode properties

2019-03-29 Thread Lowry Li (Arm Technology China)
Creates plane alpha and blend mode properties attached to plane.

Signed-off-by: Lowry Li 
---
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index af51f0c..0ebec39 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -212,6 +212,17 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_alpha_property(plane);
+   if (err)
+   goto cleanup;
+
+   err = drm_plane_create_blend_mode_property(plane,
+   BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+   BIT(DRM_MODE_BLEND_PREMULTI)   |
+   BIT(DRM_MODE_BLEND_COVERAGE));
+   if (err)
+   goto cleanup;
+
return 0;
 cleanup:
komeda_plane_destroy(plane);
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2] drm/komeda: fixing of DMA mapping sg segment warning

2019-04-11 Thread Lowry Li (Arm Technology China)
Fixing the DMA mapping sg segment warning, which shows "DMA-API: mapping
sg segment longer than device claims to support [len=921600] [max=65536]".
Fixed by setting the max segment size at Komeda driver.

This patch depends on:
- https://patchwork.freedesktop.org/series/54448/
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58976/

Changes since v1:
- Adds member description
- Adds patch denpendency in the comment

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 4 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 7f25e6a..b4902ae 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_DEBUG_FS
 #include 
 #include 
@@ -245,6 +246,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
goto err_cleanup;
}
 
+   dev->dma_parms = >dma_parms;
+   dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 29e03c4..83ace71 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -149,6 +149,8 @@ struct komeda_dev {
struct device *dev;
/** @reg_base: the base address of komeda io space */
u32 __iomem   *reg_base;
+   /** @dma_parms: the dma parameters of komeda */
+   struct device_dma_parameters dma_parms;
 
/** @chip: the basic chip information */
struct komeda_chip_info chip;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2] drm/komeda: Creates plane alpha and blend mode properties

2019-04-11 Thread Lowry Li (Arm Technology China)
Creates plane alpha and blend mode properties attached to plane.

This patch depends on:
- https://patchwork.freedesktop.org/series/54448/
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/

Changes since v1:
- Adds patch denpendency in the comment

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 68cd2c9e..aae5e80 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -220,6 +220,17 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_alpha_property(plane);
+   if (err)
+   goto cleanup;
+
+   err = drm_plane_create_blend_mode_property(plane,
+   BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+   BIT(DRM_MODE_BLEND_PREMULTI)   |
+   BIT(DRM_MODE_BLEND_COVERAGE));
+   if (err)
+   goto cleanup;
+
return 0;
 cleanup:
komeda_plane_destroy(plane);
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 1/2] drm/komeda: Update HW up-sampling on D71

2019-05-16 Thread Lowry Li (Arm Technology China)
Updates HW up-sampling method according to the format type.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c | 29 ++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index f8846c6..dfc70f5 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -212,6 +212,35 @@ static void d71_layer_update(struct komeda_component *c,
malidp_write32(reg, BLK_P1_PTR_HIGH, upper_32_bits(addr));
}
 
+   if (fb->format->is_yuv) {
+   u32 upsampling = 0;
+
+   switch (kfb->format_caps->fourcc) {
+   case DRM_FORMAT_YUYV:
+   upsampling = fb->modifier ? LR_CHI422_BILINEAR :
+LR_CHI422_REPLICATION;
+   break;
+   case DRM_FORMAT_UYVY:
+   upsampling = LR_CHI422_REPLICATION;
+   break;
+   case DRM_FORMAT_NV12:
+   case DRM_FORMAT_YUV420_8BIT:
+   case DRM_FORMAT_YUV420_10BIT:
+   case DRM_FORMAT_YUV420:
+   case DRM_FORMAT_P010:
+   /* these fmt support MPGE/JPEG both, here perfer JPEG*/
+   upsampling = LR_CHI420_JPEG;
+   break;
+   case DRM_FORMAT_X0L2:
+   upsampling = LR_CHI420_JPEG;
+   break;
+   default:
+   break;
+   }
+
+   malidp_write32(reg, LAYER_R_CONTROL, upsampling);
+   }
+
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 2/2] drm/komeda: Enable color-encoding (YUV format) support

2019-05-16 Thread Lowry Li (Arm Technology China)
Adds color-encoding properties if layer can support YUV format.
Updates HW YUV-RGB matrix state according to the color-encoding
properties.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/Makefile|  1 +
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  6 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 67 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h | 17 ++
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 13 +
 5 files changed, 104 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h

diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile 
b/drivers/gpu/drm/arm/display/komeda/Makefile
index d7e29fc..73b8e8b 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -8,6 +8,7 @@ komeda-y := \
komeda_drv.o \
komeda_dev.o \
komeda_format_caps.o \
+   komeda_color_mgmt.o \
komeda_pipeline.o \
komeda_pipeline_state.o \
komeda_framebuffer.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index dfc70f5..b85514b 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -10,6 +10,7 @@
 #include "komeda_kms.h"
 #include "malidp_io.h"
 #include "komeda_framebuffer.h"
+#include "komeda_color_mgmt.h"
 
 static void get_resources_id(u32 hw_id, u32 *pipe_id, u32 *comp_id)
 {
@@ -239,6 +240,11 @@ static void d71_layer_update(struct komeda_component *c,
}
 
malidp_write32(reg, LAYER_R_CONTROL, upsampling);
+   malidp_write_group(reg, LAYER_YUV_RGB_COEFF0,
+  KOMEDA_N_YUV2RGB_COEFFS,
+  komeda_select_yuv2rgb_coeffs(
+   plane_st->color_encoding,
+   plane_st->color_range));
}
 
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
new file mode 100644
index 000..9d14a92
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang 
+ *
+ */
+
+#include "komeda_color_mgmt.h"
+
+/* 10bit precision YUV2RGB matrix */
+static const s32 yuv2rgb_bt601_narrow[KOMEDA_N_YUV2RGB_COEFFS] = {
+   1192,0, 1634,
+   1192, -401, -832,
+   1192, 2066,0,
+ 64,  512,  512
+};
+
+static const s32 yuv2rgb_bt601_wide[KOMEDA_N_YUV2RGB_COEFFS] = {
+   1024,0, 1436,
+   1024, -352, -731,
+   1024, 1815,0,
+  0,  512,  512
+};
+
+static const s32 yuv2rgb_bt709_narrow[KOMEDA_N_YUV2RGB_COEFFS] = {
+   1192,0, 1836,
+   1192, -218, -546,
+   1192, 2163,0,
+ 64,  512,  512
+};
+
+static const s32 yuv2rgb_bt709_wide[KOMEDA_N_YUV2RGB_COEFFS] = {
+   1024,0, 1613,
+   1024, -192, -479,
+   1024, 1900,0,
+  0,  512,  512
+};
+
+static const s32 yuv2rgb_bt2020[KOMEDA_N_YUV2RGB_COEFFS] = {
+   1024,0, 1476,
+   1024, -165, -572,
+   1024, 1884,0,
+  0,  512,  512
+};
+
+const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range)
+{
+   bool narrow = color_range == DRM_COLOR_YCBCR_LIMITED_RANGE;
+   const s32 *coeffs;
+
+   switch (color_encoding) {
+   case DRM_COLOR_YCBCR_BT709:
+   coeffs = narrow ? yuv2rgb_bt709_narrow : yuv2rgb_bt709_wide;
+   break;
+   case DRM_COLOR_YCBCR_BT601:
+   coeffs = narrow ? yuv2rgb_bt601_narrow : yuv2rgb_bt601_wide;
+   break;
+   case DRM_COLOR_YCBCR_BT2020:
+   coeffs = yuv2rgb_bt2020;
+   break;
+   default:
+   coeffs = NULL;
+   break;
+   }
+
+   return coeffs;
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
new file mode 100644
index 000..a2df218
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang 
+ *
+ */
+
+#ifndef _KOMEDA_COLOR_MGMT_H_
+#define _KOMEDA_COLOR_MGMT_H_
+
+#include 
+
+#define KOMEDA_N_YUV2RGB_COEFFS12
+
+const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
+
+#endif
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plan

[PATCH v1 0/2] drm/komeda: Enable color-encoding (YUV format) support

2019-05-16 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at:
- Updating HW up-sampling method according to the format type.
- Adding color-encoding properties if layer can support YUV format,
and updating HW YUV-RGB matrix state according to the color-encoding
properties.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/

Lowry Li (Arm Technology China) (2):
  drm/komeda: Update HW up-sampling on D71
  drm/komeda: Enable color-encoding (YUV format) support

 drivers/gpu/drm/arm/display/komeda/Makefile|  1 +
 .../gpu/drm/arm/display/komeda/d71/d71_component.c | 35 +++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 67 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h | 17 ++
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 13 +
 5 files changed, 133 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 2/2] drm/komeda: Adds limitation check for AFBC wide block not support Rot90

2019-05-27 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Komeda series hardware doesn't support Rot90 for AFBC wide block. So
add limitation check to reject it if such configuration has been posted.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c|  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h|  8 +++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c| 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h|  5 +++--
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c |  8 +++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  |  2 +-
 7 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 1c914f8..4563c2a 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -494,11 +494,26 @@ static int d71_enum_resources(struct komeda_dev *mdev)
{__HW_ID(6, 7), 0/*DRM_FORMAT_YUV420_10BIT*/, 1,RICH,   
Rot_ALL_H_V,LYT_NM, AFB_TH},
 };
 
+static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot)
+{
+   uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
+
+   if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
+   drm_rotation_90_or_270(rot)) {
+   DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
+   return false;
+   }
+
+   return true;
+}
+
 static void d71_init_fmt_tbl(struct komeda_dev *mdev)
 {
struct komeda_format_caps_table *table = >fmt_tbl;
 
table->format_caps = d71_format_caps_table;
+   table->format_mod_supported = d71_format_mod_supported;
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
index b219514..cd4d9f5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
@@ -74,7 +74,8 @@
 };
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier)
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot)
 {
const struct komeda_format_caps *caps;
 
@@ -85,6 +86,10 @@ bool komeda_format_mod_supported(struct 
komeda_format_caps_table *table,
if (!(caps->supported_layer_types & layer_type))
return false;
 
+   if (table->format_mod_supported)
+   return table->format_mod_supported(caps, layer_type, modifier,
+  rot);
+
return true;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index 96de22e..381e873 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -71,10 +71,15 @@ struct komeda_format_caps {
  *
  * @n_formats: the size of format_caps list.
  * @format_caps: format_caps list.
+ * @format_mod_supported: Optional. Some HW may have special requirements or
+ * limitations which can not be described by format_caps, this func supply HW
+ * the ability to do the further HW specific check.
  */
 struct komeda_format_caps_table {
u32 n_formats;
const struct komeda_format_caps *format_caps;
+   bool (*format_mod_supported)(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot);
 };
 
 extern u64 komeda_supported_modifiers[];
@@ -100,6 +105,7 @@ u32 *komeda_get_layer_fourcc_list(struct 
komeda_format_caps_table *table,
 void komeda_put_fourcc_list(u32 *fourcc_list);
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier);
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot);
 
 #endif
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index d0e713a..5f63dec 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -240,20 +240,20 @@ struct drm_framebuffer *
 }
 
 /* if the fb can be supported by a specific layer */
-bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type)
+bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type,
+  

[PATCH v3 1/2] drm/komeda: Add rotation support on Komeda driver

2019-05-27 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

- Adds rotation property to plane.
- Komeda display rotation support diverges from the specific formats,
so need to check the user required rotation type with the format caps
and reject the commit if it can not be supported.
- In the layer validate flow, sets the rotation value to the layer
state. If r90 or r270, swap the width and height of the data flow
for next stage.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h  | 11 +++
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c   |  7 +++
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c| 16 
 3 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index bc3b2df36..96de22e 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -79,6 +79,17 @@ struct komeda_format_caps_table {
 
 extern u64 komeda_supported_modifiers[];
 
+static inline const char *komeda_get_format_name(u32 fourcc, u64 modifier)
+{
+   struct drm_format_name_buf buf;
+   static char name[64];
+
+   snprintf(name, sizeof(name), "%s with modifier: 0x%llx.",
+drm_get_format_name(fourcc, ), modifier);
+
+   return name;
+}
+
 const struct komeda_format_caps *
 komeda_get_format_caps(struct komeda_format_caps_table *table,
   u32 fourcc, u64 modifier);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index db34ea2..34737c0 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -339,6 +339,13 @@ struct komeda_pipeline_state *
/* update the data flow for the next stage */
komeda_component_set_output(>input, >base, 0);
 
+   /*
+* The rotation has been handled by layer, so adjusted the data flow for
+* the next stage.
+*/
+   if (drm_rotation_90_or_270(st->rot))
+   swap(dflow->in_h, dflow->in_w);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 9b87c25..c9f37ff 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -10,6 +10,7 @@
 #include 
 #include "komeda_dev.h"
 #include "komeda_kms.h"
+#include "komeda_framebuffer.h"
 
 static int
 komeda_plane_init_data_flow(struct drm_plane_state *st,
@@ -17,6 +18,7 @@
 {
struct komeda_plane_state *kplane_st = to_kplane_st(st);
struct drm_framebuffer *fb = st->fb;
+   const struct komeda_format_caps *caps = to_kfb(fb)->format_caps;
 
memset(dflow, 0, sizeof(*dflow));
 
@@ -37,6 +39,15 @@
dflow->in_w = st->src_w >> 16;
dflow->in_h = st->src_h >> 16;
 
+   dflow->rot = drm_rotation_simplify(st->rotation, caps->supported_rots);
+   if (!has_bits(dflow->rot, caps->supported_rots)) {
+   DRM_DEBUG_ATOMIC("rotation(0x%x) isn't supported by %s.\n",
+dflow->rot,
+komeda_get_format_name(caps->fourcc,
+   fb->modifier));
+   return -EINVAL;
+   }
+
dflow->en_img_enhancement = kplane_st->img_enhancement;
 
komeda_complete_data_flow_cfg(dflow);
@@ -303,6 +314,11 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
+layer->supported_rots);
+   if (err)
+   goto cleanup;
+
err = drm_plane_create_alpha_property(plane);
if (err)
goto cleanup;
-- 
1.9.1



[PATCH v3 0/2] drm/komeda: Add rotation support on Komeda driver

2019-05-27 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for rotation on Komeda driver.
For rotation, D71 doesn't support Rot90 for AFBC wide block. So this patch
set also includes the limitation check.

This patch series depends on:
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/58665/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59471/
- https://patchwork.freedesktop.org/series/58710/

Changes since v1:
- Modify patch denpendency in the comment

Changes since v2:
- Rebase the code

Regards,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add rotation support on Komeda driver
  drm/komeda: Adds limitation check for AFBC wide block not support
Rot90

 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c  | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c   |  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h   | 19 ++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c   | 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h   |  5 +++--
 .../drm/arm/display/komeda/komeda_pipeline_state.c| 15 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 18 +-
 7 files changed, 82 insertions(+), 15 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 0/2] Adds slave pipeline support

2019-06-03 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for slave pipeline on Komeda
driver. Also adds drop_master to shutdown the device and make sure
all the komeda resources shared between crtcs have been released.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59747/
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/60698/
- https://patchwork.freedesktop.org/series/60856/
- https://patchwork.freedesktop.org/series/60893/
- https://patchwork.freedesktop.org/series/61370/

Regards,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add slave pipeline support
  drm/komeda: Adds komeda_kms_drop_master

 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 41 --
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c| 23 
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h|  9 +
 .../gpu/drm/arm/display/komeda/komeda_pipeline.c   | 22 
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline_state.c | 15 
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 32 -
 7 files changed, 141 insertions(+), 3 deletions(-)

-- 
1.9.1



[PATCH v1 2/2] drm/komeda: Adds komeda_kms_drop_master

2019-06-03 Thread Lowry Li (Arm Technology China)
The komeda internal resources (pipelines) are shared between crtcs,
and resources release by disable_crtc. This commit is working for once
user forgot disabling crtc like app quit abnomally, and then the
resources can not be used by another crtc. Adds drop_master to
shutdown the device and make sure all the komeda resources have been
released and can be used for the next usage.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 8543860..647bce5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -54,11 +54,24 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void 
*data)
return status;
 }
 
+/* Komeda internal resources (pipelines) are shared between crtcs, and 
resources
+ * are released by disable_crtc. But if user forget disabling crtc like app 
quit
+ * abnormally, the resources can not be used by another crtc.
+ * Use drop_master to shutdown the device and make sure all the komeda 
resources
+ * have been released, and can be used for the next usage.
+ */
+static void komeda_kms_drop_master(struct drm_device *dev,
+  struct drm_file *file_priv)
+{
+   drm_atomic_helper_shutdown(dev);
+}
+
 static struct drm_driver komeda_kms_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
   DRIVER_PRIME | DRIVER_HAVE_IRQ,
.lastclose  = drm_fb_helper_lastclose,
.irq_handler= komeda_kms_irq_handler,
+   .master_drop= komeda_kms_drop_master,
.gem_free_object_unlocked   = drm_gem_cma_free_object,
.gem_vm_ops = _gem_cma_vm_ops,
.dumb_create= komeda_gem_cma_dumb_create,
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 1/2] drm/komeda: Add slave pipeline support

2019-06-03 Thread Lowry Li (Arm Technology China)
One crtc can use two komeda_pipeline, and one works as master and as
slave. the slave pipeline doesn't have its own output and timing
ctrlr, but pre-composite the input layer data flow and then feed the
result to master. the pipeline configuration like:

slave-layer-0 \
...slave->CU
slave-layer-4 / \
\
master-layer-0 > master->CU -> ...
 ...  /
master-layer-4 -->

Since komeda Compiz doesn't output alpha, so the slave->CU result
only can be used as bottom input when blend it with master input data
flows.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 41 --
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c| 10 ++
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h|  9 +
 .../gpu/drm/arm/display/komeda/komeda_pipeline.c   | 22 
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline_state.c | 15 
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 32 -
 7 files changed, 128 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 18c23f8..b5190a1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -64,6 +64,10 @@ static void komeda_crtc_update_clock_ratio(struct 
komeda_crtc_state *kcrtc_st)
}
 
/* release unclaimed pipeline resources */
+   err = komeda_release_unclaimed_resources(kcrtc->slave, kcrtc_st);
+   if (err)
+   return err;
+
err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st);
if (err)
return err;
@@ -230,6 +234,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state);
struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave = kcrtc->slave;
struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
struct drm_connector_state *conn_st;
 
@@ -241,6 +246,9 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
if (has_bit(master->id, kcrtc_st->affected_pipes))
komeda_pipeline_update(master, old->state);
 
+   if (slave && has_bit(slave->id, kcrtc_st->affected_pipes))
+   komeda_pipeline_update(slave, old->state);
+
conn_st = wb_conn ? wb_conn->base.base.state : NULL;
if (conn_st && conn_st->writeback_job)
drm_writeback_queue_job(_conn->base, conn_st);
@@ -266,6 +274,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
struct komeda_crtc_state *old_st = to_kcrtc_st(old);
struct komeda_dev *mdev = crtc->dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave  = kcrtc->slave;
struct completion *disable_done = >state->commit->flip_done;
struct completion temp;
int timeout;
@@ -274,6 +283,9 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 drm_crtc_index(crtc),
 old_st->active_pipes, old_st->affected_pipes);
 
+   if (slave && has_bit(slave->id, old_st->active_pipes))
+   komeda_pipeline_disable(slave, old->state);
+
if (has_bit(master->id, old_st->active_pipes))
komeda_pipeline_disable(master, old->state);
 
@@ -425,6 +437,7 @@ static void komeda_crtc_reset(struct drm_crtc *crtc)
 
new->affected_pipes = old->active_pipes;
new->clock_ratio = old->clock_ratio;
+   new->max_slave_zorder = old->max_slave_zorder;
 
return >base;
 }
@@ -499,7 +512,7 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
master = mdev->pipelines[i];
 
crtc->master = master;
-   crtc->slave  = NULL;
+   crtc->slave  = komeda_pipeline_get_slave(master);
 
if (crtc->slave)
sprintf(str, "pipe-%d", crtc->slave->id);
@@ -533,6 +546,26 @@ static int komeda_crtc_create_clock_ratio_property(struct 
komeda_crtc *kcrtc)
return 0;
 }
 
+static int komeda_crtc_create_slave_planes_property(struct komeda_crtc *kcrtc)
+{
+   struct drm_crtc *crtc = >base;
+   struct drm_property *prop;
+
+   if (kcrtc->slave_planes == 0)
+   return 0;
+
+   prop = drm_property_create_range(crtc->dev, DRM_MODE_PROP_IMMUTABLE,
+"slave_planes", 0, U32_MAX);
+   if (!prop)
+   re

Re: [PATCH v1 1/2] drm/komeda: Add rotation support on Komeda driver

2019-06-05 Thread Lowry Li (Arm Technology China)
On Wed, Jun 05, 2019 at 05:22:22PM +0800, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Mon, Apr 22, 2019 at 04:16:26AM +0100, Lowry Li (Arm Technology China) 
> wrote:
> > - Adds rotation property to plane.
> > - Komeda display rotation support diverges from the specific formats,
> > so need to check the user required rotation type with the format caps
> > and reject the commit if it can not be supported.
> > - In the layer validate flow, sets the rotation value to the layer
> > state. If r90 or r270, swap the width and height of the data flow
> > for next stage.
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h  | 11 +++
> >  .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c   |  7 +++
> >  drivers/gpu/drm/arm/display/komeda/komeda_plane.c| 16 
> > 
> >  3 files changed, 34 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > index bc3b2df36..96de22e 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > @@ -79,6 +79,17 @@ struct komeda_format_caps_table {
> >  
> >  extern u64 komeda_supported_modifiers[];
> >  
> > +static inline const char *komeda_get_format_name(u32 fourcc, u64 modifier)
> > +{
> > +   struct drm_format_name_buf buf;
> > +   static char name[64];
> > +
> > +   snprintf(name, sizeof(name), "%s with modifier: 0x%llx.",
> > +drm_get_format_name(fourcc, ), modifier);
> > +
> > +   return name;
> > +}
> 
> Can you roll the content of this function inside the if () {.} part? We
> only have one use for it, I don't see the need to split it into a separate
> function.
> 
> With that: Reviewed-by: Liviu Dudau 
> 
> Best regards,
> Liviu
> 
Hi Liviu,

Thanks a lot for your comments. This function is generic one which
will be called from many places further, like print the format string
log and etc. So we split it out in komeda_format_caps header file
here :)

Best regards,
Lowry

> > +
> >  const struct komeda_format_caps *
> >  komeda_get_format_caps(struct komeda_format_caps_table *table,
> >u32 fourcc, u64 modifier);
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
> > index 9b29e9a..8c133e4 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
> > @@ -317,6 +317,13 @@ struct komeda_pipeline_state *
> > /* update the data flow for the next stage */
> > komeda_component_set_output(>input, >base, 0);
> >  
> > +   /*
> > +* The rotation has been handled by layer, so adjusted the data flow for
> > +* the next stage.
> > +*/
> > +   if (drm_rotation_90_or_270(st->rot))
> > +   swap(dflow->in_h, dflow->in_w);
> > +
> > return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > index 14d6861..5e5bfdb 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > @@ -9,12 +9,14 @@
> >  #include 
> >  #include "komeda_dev.h"
> >  #include "komeda_kms.h"
> > +#include "komeda_framebuffer.h"
> >  
> >  static int
> >  komeda_plane_init_data_flow(struct drm_plane_state *st,
> > struct komeda_data_flow_cfg *dflow)
> >  {
> > struct drm_framebuffer *fb = st->fb;
> > +   const struct komeda_format_caps *caps = to_kfb(fb)->format_caps;
> >  
> > memset(dflow, 0, sizeof(*dflow));
> >  
> > @@ -35,6 +37,15 @@
> > dflow->in_w = st->src_w >> 16;
> > dflow->in_h = st->src_h >> 16;
> >  
> > +   dflow->rot = drm_rotation_simplify(st->rotation, caps->supported_rots);
> > +   if (!has_bits(dflow->rot, caps->supported_rots)) {
> > +   DRM_DEBUG_ATOMIC("rotation(0x%x) isn't supported by %s.\n",
> > +dflow->rot,
> > +komeda_get_format_name(caps->fourcc,
> > +   fb->modifier));
&g

[PATCH] drm/komeda: Adds gamma and color-transform support for DOU-IPS

2019-05-30 Thread Lowry Li (Arm Technology China)
Adds gamma and color-transform support for DOU-IPS.
Adds two caps members fgamma_coeffs and ctm_coeffs to komeda_improc_state.
If color management changed, set gamma and color-transform accordingly.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59747/
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/60698/
- https://patchwork.freedesktop.org/series/60856/
- https://patchwork.freedesktop.org/series/60893/

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c | 24 ++
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   |  2 ++
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  3 +++
 .../drm/arm/display/komeda/komeda_pipeline_state.c |  6 ++
 4 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 9668063..240f82c 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -882,15 +882,39 @@ static int d71_downscaling_clk_check(struct 
komeda_pipeline *pipe,
 static void d71_improc_update(struct komeda_component *c,
  struct komeda_component_state *state)
 {
+   struct drm_crtc_state *crtc_st = state->crtc->state;
struct komeda_improc_state *st = to_improc_st(state);
+   struct d71_pipeline *pipe = to_d71_pipeline(c->pipeline);
u32 __iomem *reg = c->reg;
u32 index;
+   u32 mask = 0, ctrl = 0;
 
for_each_changed_input(state, index)
malidp_write32(reg, BLK_INPUT_ID0 + index * 4,
   to_d71_input_id(state, index));
 
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
+
+   if (crtc_st->color_mgmt_changed) {
+   mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
+
+   if (crtc_st->gamma_lut) {
+   malidp_write_group(pipe->dou_ft_coeff_addr, FT_COEFF0,
+  KOMEDA_N_GAMMA_COEFFS,
+  st->fgamma_coeffs);
+   ctrl |= IPS_CTRL_FT; /* enable gamma */
+   }
+
+   if (crtc_st->ctm) {
+   malidp_write_group(reg, IPS_RGB_RGB_COEFF0,
+  KOMEDA_N_CTM_COEFFS,
+  st->ctm_coeffs);
+   ctrl |= IPS_CTRL_RGB; /* enable gamut */
+   }
+   }
+
+   if (mask)
+   malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
 }
 
 static void d71_improc_dump(struct komeda_component *c, struct seq_file *sf)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 24a9613..18c23f8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -573,6 +573,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
if (err)
return err;
 
+   drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 49bb058..989408b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include "malidp_utils.h"
+#include "komeda_color_mgmt.h"
 
 #define KOMEDA_MAX_PIPELINES   2
 #define KOMEDA_PIPELINE_MAX_LAYERS 4
@@ -313,6 +314,8 @@ struct komeda_improc {
 struct komeda_improc_state {
struct komeda_component_state base;
u16 hsize, vsize;
+   u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];
+   u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];
 };
 
 /* display timing controller */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index afb2301..82ea6cf 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -700,6 +700,12 @@ void pipeline_composition_size(struct komeda_crtc_state 
*kcrtc_st,
st->hsize = dflow->in_w;
st->vsize = dflow->in_h;
 
+   if (kcrtc_st->base.color_mgmt_changed) {
+   drm_lut_to_fgamma_coeffs(kcrtc_st->base.gamma_lut,
+st->fgamma_coeffs);
+   drm_ctm_to_coeffs(kcrtc_st->base.ctm, st->ctm_coeffs);
+   }
+
komeda_compo

Re: [PATCH v1 1/2] drm/komeda: Adds SMMU support

2019-06-06 Thread Lowry Li (Arm Technology China)
Hi Liviu,

Please ignore last email and please find the latest feedback inline as
below.

On Wed, Jun 05, 2019 at 07:19:37PM +0800, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Tue, Apr 30, 2019 at 07:19:29AM +0100, Lowry Li (Arm Technology China) 
> wrote:
> > Adds iommu_connect and disconnect for SMMU support, and configures
> > TBU translation once SMMU has been attached to the display device.
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
> >  drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 
> > ++
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 17 
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
> >  .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
> >  .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
> >  6 files changed, 82 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > index 33ca171..9065040 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > @@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= L_TBU_EN;
> > malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
> >  }
> >  
> > @@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component 
> > *c,
> >fb->pitches[i] & 0x);
> > }
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= LW_TBU_EN;
> > +
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> > malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > index 9603de9..45c98a7 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > @@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
> > table->n_formats = ARRAY_SIZE(d71_format_caps_table);
> >  }
> >  
> > +static int d71_connect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int i, ret;
> > +
> > +   if (!d71->integrates_tbu)
> > +   return -1;
> > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
> > +   100, 1000, 1000);
> > +   if (ret <= 0) {
> > +   DRM_ERROR("connect to TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
> > +   return -ETIMEDOUT;
> > +   }
> > +
> > +   for (i = 0; i < d71->num_pipelines; i++)
> > +   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
> > +   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
> > +   return 0;
> > +}
> > +
> > +static int d71_disconnect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int ret;
> > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
> > +   100, 1000, 1000);
> > +   if (ret <= 0) {
> > +   DRM_ERROR("disconnect from TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
> > +   }
> > +
> > +   return ret > 0 ? 0 : -1;
> 
> For consistency with d71_connect_iommu() you should return -ETIMEDOUT as well.
> I'm sending a patch to convert dp

[PATCH v2 1/2] drm/komeda: Adds SMMU support

2019-06-06 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds iommu_connect and disconnect for SMMU support, and configures
TBU translation once SMMU has been attached to the display device.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 6 files changed, 83 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 4e26a80..4a48dd6 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
+   if (kfb->is_va)
+   ctrl |= L_TBU_EN;
malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
 }
 
@@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component *c,
   fb->pitches[i] & 0x);
}
 
+   if (kfb->is_va)
+   ctrl |= LW_TBU_EN;
+
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 8e682c7..1b9e734 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
+static int d71_connect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int i, ret;
+
+   if (!d71->integrates_tbu)
+   return -1;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
+
+   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
+   100, 1000, 1000);
+   if (ret <= 0) {
+   DRM_ERROR("connect to TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   return -ETIMEDOUT;
+   }
+
+   for (i = 0; i < d71->num_pipelines; i++)
+   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
+   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
+   return 0;
+}
+
+static int d71_disconnect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int ret;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
+
+   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
+   100, 1000, 1000);
+   if (ret < 0) {
+   DRM_ERROR("disconnect from TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   }
+
+   return ret;
+}
+
 static struct komeda_dev_funcs d71_chip_funcs = {
.init_format_table = d71_init_fmt_tbl,
.enum_resources = d71_enum_resources,
@@ -527,6 +574,8 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
.on_off_vblank  = d71_on_off_vblank,
.change_opmode  = d71_change_opmode,
.flush  = d71_flush,
+   .connect_iommu  = d71_connect_iommu,
+   .disconnect_iommu = d71_disconnect_iommu,
 };
 
 struct komeda_dev_funcs *
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index c92e161..e80e673 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -253,6 +253,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
dev->dma_parms = >dma_parms;
dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
+   mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
+   if (!mdev->iommu)
+   DRM_INFO("continue without IOMMU support!\n");
+
+   if (mdev->iommu &&a

[PATCH v2 2/2] dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

2019-06-06 Thread Lowry Li (Arm Technology China)
Updates the device-tree doc about how to enable SMMU by devicetree.

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Liviu Dudau 
Reviewed-by: James Qian Wang (Arm Technology China) 

---
 Documentation/devicetree/bindings/display/arm,komeda.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/arm,komeda.txt 
b/Documentation/devicetree/bindings/display/arm,komeda.txt
index 02b2265..b12c045 100644
--- a/Documentation/devicetree/bindings/display/arm,komeda.txt
+++ b/Documentation/devicetree/bindings/display/arm,komeda.txt
@@ -11,6 +11,10 @@ Required properties:
   - "pclk": for the APB interface clock
 - #address-cells: Must be 1
 - #size-cells: Must be 0
+- iommus: configure the stream id to IOMMU, Must be configured if want to
+enable iommu in display. for how to configure this node please reference
+devicetree/bindings/iommu/arm,smmu-v3.txt,
+devicetree/bindings/iommu/iommu.txt
 
 Required properties for sub-node: pipeline@nq
 Each device contains one or two pipeline sub-nodes (at least one), each
@@ -44,6 +48,9 @@ Example:
interrupts = <0 168 4>;
clocks = <_mclk>, <_aclk>;
clock-names = "mclk", "pclk";
+   iommus = < 0>, < 1>, < 2>, < 3>,
+   < 4>, < 5>, < 6>, < 7>,
+   < 8>, < 9>;
 
dp0_pipe0: pipeline@0 {
clocks = <>, <_aclk>;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 0/2] drm/komeda: Add SMMU support on Komeda driver

2019-06-06 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for SMMU on Komeda driver.
Also updates the device-tree doc about how to enable SMMU by devicetree.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/61650/

Changes since v1:
- Rebase to the patch in which convert dp_wait_cond() was changed to
return -ETIMEDOUT and update d71_disconnect_iommu() to be consistent.
- If connected IOMMU failed, set mdev->iommu as NULL.

Thanks,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Adds SMMU support
  dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

 .../devicetree/bindings/display/arm,komeda.txt |  7 
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 7 files changed, 90 insertions(+)

-- 
1.9.1



Re: [PATCH v1 1/2] drm/komeda: Adds SMMU support

2019-06-06 Thread Lowry Li (Arm Technology China)
On Wed, Jun 05, 2019 at 07:19:37PM +0800, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Tue, Apr 30, 2019 at 07:19:29AM +0100, Lowry Li (Arm Technology China) 
> wrote:
> > Adds iommu_connect and disconnect for SMMU support, and configures
> > TBU translation once SMMU has been attached to the display device.
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
> >  drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 
> > ++
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 17 
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
> >  .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
> >  .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
> >  6 files changed, 82 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > index 33ca171..9065040 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > @@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= L_TBU_EN;
> > malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
> >  }
> >  
> > @@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component 
> > *c,
> >fb->pitches[i] & 0x);
> > }
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= LW_TBU_EN;
> > +
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> > malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > index 9603de9..45c98a7 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > @@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
> > table->n_formats = ARRAY_SIZE(d71_format_caps_table);
> >  }
> >  
> > +static int d71_connect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int i, ret;
> > +
> > +   if (!d71->integrates_tbu)
> > +   return -1;
> > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
> > +   100, 1000, 1000);
> > +   if (ret <= 0) {
> > +   DRM_ERROR("connect to TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
> > +   return -ETIMEDOUT;
> > +   }
> > +
> > +   for (i = 0; i < d71->num_pipelines; i++)
> > +   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
> > +   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
> > +   return 0;
> > +}
> > +
> > +static int d71_disconnect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int ret;
> > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
> > +   100, 1000, 1000);
> > +   if (ret <= 0) {
> > +   DRM_ERROR("disconnect from TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
> > +   }
> > +
> > +   return ret > 0 ? 0 : -1;
> 
> For consistency with d71_connect_iommu() you should return -ETIMEDOUT as well.
> I'm sending a patch to convert dp_wait_cond() to return that when it times 
> out,
> so we can be consistent in the futu

[PATCH v3 2/2] dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

2019-06-12 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Updates the device-tree doc about how to enable SMMU by devicetree.

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Liviu Dudau 
Reviewed-by: James Qian Wang (Arm Technology China) 
---
 Documentation/devicetree/bindings/display/arm,komeda.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/arm,komeda.txt 
b/Documentation/devicetree/bindings/display/arm,komeda.txt
index 02b2265..b12c045 100644
--- a/Documentation/devicetree/bindings/display/arm,komeda.txt
+++ b/Documentation/devicetree/bindings/display/arm,komeda.txt
@@ -11,6 +11,10 @@ Required properties:
   - "pclk": for the APB interface clock
 - #address-cells: Must be 1
 - #size-cells: Must be 0
+- iommus: configure the stream id to IOMMU, Must be configured if want to
+enable iommu in display. for how to configure this node please reference
+devicetree/bindings/iommu/arm,smmu-v3.txt,
+devicetree/bindings/iommu/iommu.txt
 
 Required properties for sub-node: pipeline@nq
 Each device contains one or two pipeline sub-nodes (at least one), each
@@ -44,6 +48,9 @@ Example:
interrupts = <0 168 4>;
clocks = <_mclk>, <_aclk>;
clock-names = "mclk", "pclk";
+   iommus = < 0>, < 1>, < 2>, < 3>,
+   < 4>, < 5>, < 6>, < 7>,
+   < 8>, < 9>;
 
dp0_pipe0: pipeline@0 {
clocks = <>, <_aclk>;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 0/2] drm/komeda: Add SMMU support on Komeda driver

2019-06-12 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for SMMU on Komeda driver.
Also updates the device-tree doc about how to enable SMMU by devicetree.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/61650/

Changes since v1:
- Rebase to the patch in which convert dp_wait_cond() was changed to
return -ETIMEDOUT and update d71_disconnect_iommu() to be consistent.
- If connected IOMMU failed, set mdev->iommu as NULL.

Changes since v2:
- Correct the code flow by not returning -ETIMEDOUT if dp_wait_cond()
returns zero in d71_connect_iommu().

Thanks,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Adds SMMU support
  dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

 .../devicetree/bindings/display/arm,komeda.txt |  7 
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 7 files changed, 90 insertions(+)

-- 
1.9.1



[PATCH v3 2/2] dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

2019-06-12 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Updates the device-tree doc about how to enable SMMU by devicetree.

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Liviu Dudau 
Reviewed-by: James Qian Wang (Arm Technology China) 
---
 Documentation/devicetree/bindings/display/arm,komeda.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/arm,komeda.txt 
b/Documentation/devicetree/bindings/display/arm,komeda.txt
index 02b2265..b12c045 100644
--- a/Documentation/devicetree/bindings/display/arm,komeda.txt
+++ b/Documentation/devicetree/bindings/display/arm,komeda.txt
@@ -11,6 +11,10 @@ Required properties:
   - "pclk": for the APB interface clock
 - #address-cells: Must be 1
 - #size-cells: Must be 0
+- iommus: configure the stream id to IOMMU, Must be configured if want to
+enable iommu in display. for how to configure this node please reference
+devicetree/bindings/iommu/arm,smmu-v3.txt,
+devicetree/bindings/iommu/iommu.txt
 
 Required properties for sub-node: pipeline@nq
 Each device contains one or two pipeline sub-nodes (at least one), each
@@ -44,6 +48,9 @@ Example:
interrupts = <0 168 4>;
clocks = <_mclk>, <_aclk>;
clock-names = "mclk", "pclk";
+   iommus = < 0>, < 1>, < 2>, < 3>,
+   < 4>, < 5>, < 6>, < 7>,
+   < 8>, < 9>;
 
dp0_pipe0: pipeline@0 {
clocks = <>, <_aclk>;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 1/2] drm/komeda: Adds SMMU support

2019-06-12 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds iommu_connect and disconnect for SMMU support, and configures
TBU translation once SMMU has been attached to the display device.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 6 files changed, 83 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 4e26a80..4a48dd6 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
+   if (kfb->is_va)
+   ctrl |= L_TBU_EN;
malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
 }
 
@@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component *c,
   fb->pitches[i] & 0x);
}
 
+   if (kfb->is_va)
+   ctrl |= LW_TBU_EN;
+
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 8e682c7..f88d93a 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
+static int d71_connect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int i, ret;
+
+   if (!d71->integrates_tbu)
+   return -1;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
+
+   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
+   100, 1000, 1000);
+   if (ret < 0) {
+   DRM_ERROR("connect to TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   return -ETIMEDOUT;
+   }
+
+   for (i = 0; i < d71->num_pipelines; i++)
+   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
+   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
+   return 0;
+}
+
+static int d71_disconnect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int ret;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
+
+   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
+   100, 1000, 1000);
+   if (ret < 0) {
+   DRM_ERROR("disconnect from TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   }
+
+   return ret;
+}
+
 static struct komeda_dev_funcs d71_chip_funcs = {
.init_format_table = d71_init_fmt_tbl,
.enum_resources = d71_enum_resources,
@@ -527,6 +574,8 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
.on_off_vblank  = d71_on_off_vblank,
.change_opmode  = d71_change_opmode,
.flush  = d71_flush,
+   .connect_iommu  = d71_connect_iommu,
+   .disconnect_iommu = d71_disconnect_iommu,
 };
 
 struct komeda_dev_funcs *
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index c92e161..e80e673 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -253,6 +253,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
dev->dma_parms = >dma_parms;
dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
+   mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
+   if (!mdev->iommu)
+   DRM_INFO("continue without IOMMU support!\n");
+
+   if (mdev->iommu && mde

[PATCH v2 1/2] drm/komeda: Add slave pipeline support

2019-06-11 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

One crtc can use two komeda_pipeline, and one works as master and as
slave. the slave pipeline doesn't have its own output and timing
ctrlr, but pre-composite the input layer data flow and then feed the
result to master. the pipeline configuration like:

slave-layer-0 \
...slave->CU
slave-layer-4 / \
\
master-layer-0 > master->CU -> ...
 ...  /
master-layer-4 -->

Since komeda Compiz doesn't output alpha, so the slave->CU result
only can be used as bottom input when blend it with master input data
flows.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 41 --
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c| 10 ++
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h|  9 +
 .../gpu/drm/arm/display/komeda/komeda_pipeline.c   | 22 
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline_state.c | 15 
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 32 -
 7 files changed, 128 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index a2d656f..cafb445 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -64,6 +64,10 @@ static void komeda_crtc_update_clock_ratio(struct 
komeda_crtc_state *kcrtc_st)
}
 
/* release unclaimed pipeline resources */
+   err = komeda_release_unclaimed_resources(kcrtc->slave, kcrtc_st);
+   if (err)
+   return err;
+
err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st);
if (err)
return err;
@@ -226,6 +230,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state);
struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave = kcrtc->slave;
struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
struct drm_connector_state *conn_st;
 
@@ -237,6 +242,9 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
if (has_bit(master->id, kcrtc_st->affected_pipes))
komeda_pipeline_update(master, old->state);
 
+   if (slave && has_bit(slave->id, kcrtc_st->affected_pipes))
+   komeda_pipeline_update(slave, old->state);
+
conn_st = wb_conn ? wb_conn->base.base.state : NULL;
if (conn_st && conn_st->writeback_job)
drm_writeback_queue_job(_conn->base, conn_st);
@@ -262,6 +270,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
struct komeda_crtc_state *old_st = to_kcrtc_st(old);
struct komeda_dev *mdev = crtc->dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave  = kcrtc->slave;
struct completion *disable_done = >state->commit->flip_done;
struct completion temp;
int timeout;
@@ -270,6 +279,9 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 drm_crtc_index(crtc),
 old_st->active_pipes, old_st->affected_pipes);
 
+   if (slave && has_bit(slave->id, old_st->active_pipes))
+   komeda_pipeline_disable(slave, old->state);
+
if (has_bit(master->id, old_st->active_pipes))
komeda_pipeline_disable(master, old->state);
 
@@ -414,6 +426,7 @@ static void komeda_crtc_reset(struct drm_crtc *crtc)
 
new->affected_pipes = old->active_pipes;
new->clock_ratio = old->clock_ratio;
+   new->max_slave_zorder = old->max_slave_zorder;
 
return >base;
 }
@@ -488,7 +501,7 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
master = mdev->pipelines[i];
 
crtc->master = master;
-   crtc->slave  = NULL;
+   crtc->slave  = komeda_pipeline_get_slave(master);
 
if (crtc->slave)
sprintf(str, "pipe-%d", crtc->slave->id);
@@ -522,6 +535,26 @@ static int komeda_crtc_create_clock_ratio_property(struct 
komeda_crtc *kcrtc)
return 0;
 }
 
+static int komeda_crtc_create_slave_planes_property(struct komeda_crtc *kcrtc)
+{
+   struct drm_crtc *crtc = >base;
+   struct drm_property *prop;
+
+   if (kcrtc->slave_planes == 0)
+   return 0;
+
+   prop = drm_property_create_range(crtc->dev, DRM_MODE_PROP_IMMUTABLE,
+"slave_planes", 0, 

[PATCH v2 0/2] Adds slave pipeline support

2019-06-11 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for slave pipeline on Komeda
driver. Also adds drop_master to shutdown the device and make sure
all the komeda resources shared between crtcs have been released.

Change since v1:
Rebases the code and resolves the conflict.

This patch series depends on:
- https://patchwork.freedesktop.org/series/60856/

Regards,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add slave pipeline support
  drm/komeda: Adds komeda_kms_drop_master

 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 41 --
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c| 23 
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h|  9 +
 .../gpu/drm/arm/display/komeda/komeda_pipeline.c   | 22 
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline_state.c | 15 
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 32 -
 7 files changed, 141 insertions(+), 3 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 2/2] drm/komeda: Adds komeda_kms_drop_master

2019-06-11 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

The komeda internal resources (pipelines) are shared between crtcs,
and resources release by disable_crtc. This commit is working for once
user forgot disabling crtc like app quit abnomally, and then the
resources can not be used by another crtc. Adds drop_master to
shutdown the device and make sure all the komeda resources have been
released and can be used for the next usage.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 8543860..647bce5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -54,11 +54,24 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void 
*data)
return status;
 }
 
+/* Komeda internal resources (pipelines) are shared between crtcs, and 
resources
+ * are released by disable_crtc. But if user forget disabling crtc like app 
quit
+ * abnormally, the resources can not be used by another crtc.
+ * Use drop_master to shutdown the device and make sure all the komeda 
resources
+ * have been released, and can be used for the next usage.
+ */
+static void komeda_kms_drop_master(struct drm_device *dev,
+  struct drm_file *file_priv)
+{
+   drm_atomic_helper_shutdown(dev);
+}
+
 static struct drm_driver komeda_kms_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC |
   DRIVER_PRIME | DRIVER_HAVE_IRQ,
.lastclose  = drm_fb_helper_lastclose,
.irq_handler= komeda_kms_irq_handler,
+   .master_drop= komeda_kms_drop_master,
.gem_free_object_unlocked   = drm_gem_cma_free_object,
.gem_vm_ops = _gem_cma_vm_ops,
.dumb_create= komeda_gem_cma_dumb_create,
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 1/2] drm/komeda: Adds SMMU support

2019-06-09 Thread Lowry Li (Arm Technology China)
Hi Liviu,
On Fri, Jun 07, 2019 at 05:05:59PM +0800, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Thu, Jun 06, 2019 at 10:53:05AM +0100, Lowry Li (Arm Technology China) 
> wrote:
> > From: "Lowry Li (Arm Technology China)" 
> > 
> > Adds iommu_connect and disconnect for SMMU support, and configures
> > TBU translation once SMMU has been attached to the display device.
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
> >  drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 
> > ++
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
> >  .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
> >  .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
> >  6 files changed, 83 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > index 4e26a80..4a48dd6 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > @@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= L_TBU_EN;
> > malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
> >  }
> >  
> > @@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component 
> > *c,
> >fb->pitches[i] & 0x);
> > }
> >  
> > +   if (kfb->is_va)
> > +   ctrl |= LW_TBU_EN;
> > +
> > malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
> > malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
> > malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > index 8e682c7..1b9e734 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > @@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
> > table->n_formats = ARRAY_SIZE(d71_format_caps_table);
> >  }
> >  
> > +static int d71_connect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int i, ret;
> > +
> > +   if (!d71->integrates_tbu)
> > +   return -1;
 > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
> > +   100, 1000, 1000);
> > +   if (ret <= 0) {
> 
> You don't want to return -ETIMEDOUT if dp_wait_cond() returns zero. Maybe
> follow the same flow as in d71_disconnect_iommu() ?
> 
Sorry, it should be changed as in d71_disconnect_iommu(). Thanks a lot
for pointing this out.
> > +   DRM_ERROR("connect to TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
> > +   return -ETIMEDOUT;
> > +   }
> > +
> > +   for (i = 0; i < d71->num_pipelines; i++)
> > +   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
> > +   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
> > +   return 0;
> > +}
> > +
> > +static int d71_disconnect_iommu(struct komeda_dev *mdev)
> > +{
> > +   struct d71_dev *d71 = mdev->chip_data;
> > +   u32 __iomem *reg = d71->gcu_addr;
> > +   u32 check_bits = (d71->num_pipelines == 2) ?
> > +GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
> > +   int ret;
> > +
> > +   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
> > +
> > +   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
> > +   100, 1000, 1000);
> > +   if (ret < 0) {
> > +   DRM_ERROR("disconnect from TCU timeout!\n");
> > +   malidp_write32_mask(reg, BLK_CO

[PATCH v3 0/2] drm/komeda: Add SMMU support on Komeda driver

2019-06-12 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for SMMU on Komeda driver.
Also updates the device-tree doc about how to enable SMMU by devicetree.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/61650/

Changes since v1:
- Rebase to the patch in which convert dp_wait_cond() was changed to
return -ETIMEDOUT and update d71_disconnect_iommu() to be consistent.
- If connected IOMMU failed, set mdev->iommu as NULL.

Changes since v2:
- Correct the code flow by not returning -ETIMEDOUT if dp_wait_cond()
returns zero in d71_connect_iommu().

Thanks,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Adds SMMU support
  dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

 .../devicetree/bindings/display/arm,komeda.txt |  7 
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 7 files changed, 90 insertions(+)

-- 
1.9.1



[PATCH v3 1/2] drm/komeda: Adds SMMU support

2019-06-12 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds iommu_connect and disconnect for SMMU support, and configures
TBU translation once SMMU has been attached to the display device.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 18 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 6 files changed, 83 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 4e26a80..4a48dd6 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
+   if (kfb->is_va)
+   ctrl |= L_TBU_EN;
malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
 }
 
@@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component *c,
   fb->pitches[i] & 0x);
}
 
+   if (kfb->is_va)
+   ctrl |= LW_TBU_EN;
+
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 8e682c7..3dab5077 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
+static int d71_connect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int i, ret;
+
+   if (!d71->integrates_tbu)
+   return -1;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
+
+   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
+   100, 1000, 1000);
+   if (ret < 0) {
+   DRM_ERROR("connect to TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   return ret;
+   }
+
+   for (i = 0; i < d71->num_pipelines; i++)
+   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
+   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
+   return 0;
+}
+
+static int d71_disconnect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int ret;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
+
+   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
+   100, 1000, 1000);
+   if (ret < 0) {
+   DRM_ERROR("disconnect from TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   }
+
+   return ret;
+}
+
 static struct komeda_dev_funcs d71_chip_funcs = {
.init_format_table = d71_init_fmt_tbl,
.enum_resources = d71_enum_resources,
@@ -527,6 +574,8 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
.on_off_vblank  = d71_on_off_vblank,
.change_opmode  = d71_change_opmode,
.flush  = d71_flush,
+   .connect_iommu  = d71_connect_iommu,
+   .disconnect_iommu = d71_disconnect_iommu,
 };
 
 struct komeda_dev_funcs *
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index c92e161..e80e673 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -253,6 +253,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
dev->dma_parms = >dma_parms;
dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
+   mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
+   if (!mdev->iommu)
+   DRM_INFO("continue without IOMMU support!\n");
+
+   if (mdev->iommu && mde

[PATCH] drm/komeda: Adds output-color format/depth support

2019-06-19 Thread Lowry Li (Arm Technology China)
Sets color_depth according to connector->bpc.
Adds a new optional DT attribute "color-format" to represent a
preferred color formats for a specific pipeline, and the select order
is:
YCRCB420 > YCRCB422 > YCRCB444 > RGB444
The color-format can be anyone of these 4 format, one color-format not
only represent one format, but also include the lower formats, like

color-format preferred_color_formats
YCRCB420YCRCB420 > YCRCB422 > YCRCB444 > RGB444
YCRCB422YCRCB422 > YCRCB444 > RGB444
YCRCB444YCRCB444 > RGB444
RGB444  RGB444

Then the final color_format is calculated by 3 steps:
1. calculate HW available formats.
  avail_formats = connector_color_formats & improc->color_formats;
2. filter out un-preferred format.
  avail_formats &= preferred_color_formats;
3. select the final format according to the preferred order.
  color_format = BIT(__fls(aval_formats));

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c | 14 --
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 27 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 32 +-
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h|  2 ++
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  3 ++
 .../drm/arm/display/komeda/komeda_pipeline_state.c | 31 +
 .../drm/arm/display/komeda/komeda_wb_connector.c   |  5 
 7 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 01dd426..5135577 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -955,6 +955,7 @@ static void d71_improc_update(struct komeda_component *c,
   to_d71_input_id(state, index));
 
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
+   malidp_write32(reg, IPS_DEPTH, st->color_depth);
 
if (crtc_st->color_mgmt_changed) {
mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
@@ -974,8 +975,17 @@ static void d71_improc_update(struct komeda_component *c,
}
}
 
-   if (mask)
-   malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
+   mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
+
+   /* config color format */
+   if (st->color_format == DRM_COLOR_FORMAT_YCRCB420)
+   ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
+   else if (st->color_format == DRM_COLOR_FORMAT_YCRCB422)
+   ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422;
+   else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
+   ctrl |= IPS_CTRL_YUV;
+
+   malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
 }
 
 static void d71_improc_dump(struct komeda_component *c, struct seq_file *sf)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cc6582f..ae67894 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -18,6 +18,33 @@
 #include "komeda_dev.h"
 #include "komeda_kms.h"
 
+void komeda_crtc_get_color_config(struct drm_crtc_state *crtc_st,
+ u32 *color_depths, u32 *color_formats)
+{
+   struct drm_connector *conn;
+   struct drm_connector_state *conn_st;
+   u32 conn_color_formats = ~0u;
+   int i, min_bpc = 31, conn_bpc = 0;
+
+   for_each_new_connector_in_state(crtc_st->state, conn, conn_st, i) {
+   if (conn_st->crtc != crtc_st->crtc)
+   continue;
+
+   conn_bpc = conn->display_info.bpc ? conn->display_info.bpc : 8;
+   conn_color_formats &= conn->display_info.color_formats;
+
+   if (conn_bpc < min_bpc)
+   min_bpc = conn_bpc;
+   }
+
+   /* connector doesn't config any color_format, use RGB444 as default */
+   if (conn_color_formats == 0)
+   conn_color_formats = DRM_COLOR_FORMAT_RGB444;
+
+   *color_depths = GENMASK(conn_bpc, 0);
+   *color_formats = conn_color_formats;
+}
+
 static void komeda_crtc_update_clock_ratio(struct komeda_crtc_state *kcrtc_st)
 {
u64 pxlclk, aclk;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 591da1e..a09de45 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -102,12 +102,34 @@ static void komeda_debugfs_init(struct komeda_dev *mdev)
.attrs = komeda_sysfs_entries,
 };
 
+static int to_color_format(const char *str)
+{
+   int format;
+
+   if (!strncmp(str, "RGB444", 7)

Re: [PATCH] drm/komeda: Adds power management support

2019-06-20 Thread Lowry Li (Arm Technology China)
Hi Liviu,

On Thu, Jun 20, 2019 at 12:15:22AM +0800, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Mon, Jun 17, 2019 at 06:55:49AM +0100, Lowry Li (Arm Technology China) 
> wrote:
> > Adds runtime and system power management support in KMS kernel driver.
> > 
> > Depends on:
> > - https://patchwork.freedesktop.org/series/61650/
> > - https://patchwork.freedesktop.org/series/60083/
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  2 +
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 30 +
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
> >  drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 54 
> > ++--
> >  4 files changed, 85 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > index 66c5e0d..1b4ea8a 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > @@ -257,6 +257,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   
> > *kcrtc,
> >  komeda_crtc_atomic_enable(struct drm_crtc *crtc,
> >   struct drm_crtc_state *old)
> >  {
> > +   pm_runtime_get_sync(crtc->dev->dev);
> > komeda_crtc_prepare(to_kcrtc(crtc));
> > drm_crtc_vblank_on(crtc);
> > komeda_crtc_do_flush(crtc, old);
> > @@ -330,6 +331,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   
> > *kcrtc,
> >  
> > drm_crtc_vblank_off(crtc);
> > komeda_crtc_unprepare(kcrtc);
> > +   pm_runtime_put(crtc->dev->dev);
> >  }
> >  
> >  static void
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > index 405c64d..edd0943 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > @@ -308,3 +308,33 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
> >  
> > devm_kfree(dev, mdev);
> >  }
> > +
> > +int komeda_dev_resume(struct komeda_dev *mdev)
> > +{
> > +   int ret = 0;
> > +
> > +   if (mdev->iommu && mdev->funcs->connect_iommu) {
> > +   ret = mdev->funcs->connect_iommu(mdev);
> > +   if (ret < 0) {
> > +   DRM_ERROR("connect iommu failed.\n");
> > +   return ret;
> > +   }
> > +   }
> > +
> > +   return mdev->funcs->enable_irq(mdev);
> > +}
> > +
> > +int komeda_dev_suspend(struct komeda_dev *mdev)
> > +{
> > +   int ret = 0;
> > +
> > +   if (mdev->iommu && mdev->funcs->disconnect_iommu) {
> > +   ret = mdev->funcs->disconnect_iommu(mdev);
> > +   if (ret < 0) {
> > +   DRM_ERROR("disconnect iommu failed.\n");
> > +   return ret;
> > +   }
> > +   }
> > +
> > +   return mdev->funcs->disable_irq(mdev);
> > +}
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > index d1c86b6..096f9f7 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > @@ -207,4 +207,6 @@ struct komeda_dev {
> >  
> >  struct komeda_dev *dev_to_mdev(struct device *dev);
> >  
> > +int komeda_dev_resume(struct komeda_dev *mdev);
> > +int komeda_dev_suspend(struct komeda_dev *mdev);
> >  #endif /*_KOMEDA_DEV_H_*/
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > index cfa5068..aa4cef1 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > @@ -8,6 +8,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include "komeda_dev.h"
> >  #include "komeda_kms.h"
> > @@ -32,6 +33,9 @@ static void komeda_unbind(struct device *dev)
> > return;
> >  
> > komeda_kms_detach(mdrv->kms);
> > +
> > +   pm_runtime_disable(dev);
> > +
> > komeda_dev_destroy(mdrv->mdev);
> >  
> > dev_set_drvdata(dev, NULL);
> > @@ -52,6 +56,9 @@ static int komeda_bind(struct device *dev)
> >

[PATCH] drm/komeda: Adds system power management support

2019-06-21 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds system power management support in KMS kernel driver.

Depends on:
- https://patchwork.freedesktop.org/series/61650/
- https://patchwork.freedesktop.org/series/60083/

Changes since v1:
Since we have unified mclk/pclk/pipeline->aclk to one mclk, which will
be turned on/off when crtc atomic enable/disable, removed runtime power
management.
Adds to disable the aclk when register access finished.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 63 +---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 35 +++--
 4 files changed, 93 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cafb445..85eccdda 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -257,6 +257,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 komeda_crtc_atomic_enable(struct drm_crtc *crtc,
  struct drm_crtc_state *old)
 {
+   pm_runtime_get_sync(crtc->dev->dev);
komeda_crtc_prepare(to_kcrtc(crtc));
drm_crtc_vblank_on(crtc);
komeda_crtc_do_flush(crtc, old);
@@ -330,6 +331,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 
drm_crtc_vblank_off(crtc);
komeda_crtc_unprepare(kcrtc);
+   pm_runtime_put(crtc->dev->dev);
 }
 
 static void
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index e1aa58e..c9837dc 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -209,7 +209,7 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
  product->product_id,
  MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
err = -ENODEV;
-   goto err_cleanup;
+   goto disable_clk;
}
 
DRM_INFO("Found ARM Mali-D%x version r%dp%d\n",
@@ -222,19 +222,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
err = mdev->funcs->enum_resources(mdev);
if (err) {
DRM_ERROR("enumerate display resource failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_parse_dt(dev, mdev);
if (err) {
DRM_ERROR("parse device tree failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_assemble_pipelines(mdev);
if (err) {
DRM_ERROR("assemble display pipelines failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
dev->dma_parms = >dma_parms;
@@ -247,11 +247,13 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
if (mdev->iommu && mdev->funcs->connect_iommu) {
err = mdev->funcs->connect_iommu(mdev);
if (err) {
-   mdev->iommu = NULL;
-   goto err_cleanup;
+   DRM_ERROR("connect iommu failed.\n");
+   goto disable_clk;
}
}
 
+   clk_disable_unprepare(mdev->aclk);
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
@@ -264,6 +266,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 
return mdev;
 
+disable_clk:
+   clk_disable_unprepare(mdev->aclk);
 err_cleanup:
komeda_dev_destroy(mdev);
return ERR_PTR(err);
@@ -281,6 +285,9 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
debugfs_remove_recursive(mdev->debugfs_root);
 #endif
 
+   if (mdev->aclk)
+   clk_prepare_enable(mdev->aclk);
+
if (mdev->iommu && mdev->funcs->disconnect_iommu)
mdev->funcs->disconnect_iommu(mdev);
mdev->iommu = NULL;
@@ -308,3 +315,47 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
devm_kfree(dev, mdev);
 }
+
+int komeda_dev_resume(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   clk_prepare_enable(mdev->aclk);
+
+   if (mdev->iommu && mdev->funcs->connect_iommu) {
+   ret = mdev->funcs->connect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("connect iommu failed.\n");
+   goto disable_clk;
+   }
+   }
+
+   ret = mdev->funcs->enable_irq(mdev);
+
+disable_clk:
+   clk_disable_unpre

[PATCH] drm/komeda: Adds system power management support

2019-06-21 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds system power management support in KMS kernel driver.

Depends on:
- https://patchwork.freedesktop.org/series/61650/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/61647/

Changes since v1:
Since we have unified mclk/pclk/pipeline->aclk to one mclk, which will
be turned on/off when crtc atomic enable/disable, removed runtime power
management.
Adds to disable the aclk when register access finished.

Changes since v2:
Removes run time get/put related flow.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  1 -
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 63 +---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 35 +++--
 4 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cafb445..d14e7f3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,7 +5,6 @@
  *
  */
 #include 
-#include 
 #include 
 
 #include 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index e1aa58e..c9837dc 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -209,7 +209,7 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
  product->product_id,
  MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
err = -ENODEV;
-   goto err_cleanup;
+   goto disable_clk;
}
 
DRM_INFO("Found ARM Mali-D%x version r%dp%d\n",
@@ -222,19 +222,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
err = mdev->funcs->enum_resources(mdev);
if (err) {
DRM_ERROR("enumerate display resource failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_parse_dt(dev, mdev);
if (err) {
DRM_ERROR("parse device tree failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_assemble_pipelines(mdev);
if (err) {
DRM_ERROR("assemble display pipelines failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
dev->dma_parms = >dma_parms;
@@ -247,11 +247,13 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
if (mdev->iommu && mdev->funcs->connect_iommu) {
err = mdev->funcs->connect_iommu(mdev);
if (err) {
-   mdev->iommu = NULL;
-   goto err_cleanup;
+   DRM_ERROR("connect iommu failed.\n");
+   goto disable_clk;
}
}
 
+   clk_disable_unprepare(mdev->aclk);
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
@@ -264,6 +266,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 
return mdev;
 
+disable_clk:
+   clk_disable_unprepare(mdev->aclk);
 err_cleanup:
komeda_dev_destroy(mdev);
return ERR_PTR(err);
@@ -281,6 +285,9 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
debugfs_remove_recursive(mdev->debugfs_root);
 #endif
 
+   if (mdev->aclk)
+   clk_prepare_enable(mdev->aclk);
+
if (mdev->iommu && mdev->funcs->disconnect_iommu)
mdev->funcs->disconnect_iommu(mdev);
mdev->iommu = NULL;
@@ -308,3 +315,47 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
devm_kfree(dev, mdev);
 }
+
+int komeda_dev_resume(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   clk_prepare_enable(mdev->aclk);
+
+   if (mdev->iommu && mdev->funcs->connect_iommu) {
+   ret = mdev->funcs->connect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("connect iommu failed.\n");
+   goto disable_clk;
+   }
+   }
+
+   ret = mdev->funcs->enable_irq(mdev);
+
+disable_clk:
+   clk_disable_unprepare(mdev->aclk);
+
+   return ret;
+}
+
+int komeda_dev_suspend(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   clk_prepare_enable(mdev->aclk);
+
+   if (mdev->iommu && mdev->funcs->disconnect_iommu) {
+   ret = mdev->funcs->disconnect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("disconnec

Re: [PATCH v2 2/2] drm/komeda: Adds komeda_kms_drop_master

2019-06-17 Thread Lowry Li (Arm Technology China)
Hi Daniel,
On Fri, Jun 14, 2019 at 04:53:08PM +0800, james qian wang (Arm Technology 
China) wrote:
> On Fri, Jun 14, 2019 at 09:01:11AM +0200, Daniel Vetter wrote:
> > On Fri, Jun 14, 2019 at 05:46:04AM +, james qian wang (Arm Technology 
> > China) wrote:
> > > On Thu, Jun 13, 2019 at 04:30:08PM +0200, Daniel Vetter wrote:
> > > > On Thu, Jun 13, 2019 at 02:24:37PM +0100, Liviu Dudau wrote:
> > > > > On Thu, Jun 13, 2019 at 11:08:14AM +0200, Daniel Vetter wrote:
> > > > > > On Thu, Jun 13, 2019 at 09:28:13AM +0100, Liviu Dudau wrote:
> > > > > > > On Thu, Jun 13, 2019 at 10:17:27AM +0200, Daniel Vetter wrote:
> > > > > > > > On Wed, Jun 12, 2019 at 02:26:24AM +, james qian wang (Arm 
> > > > > > > > Technology China) wrote:
> > > > > > > > > On Tue, Jun 11, 2019 at 02:30:38PM +0200, Daniel Vetter wrote:
> > > > > > > > > > On Tue, Jun 11, 2019 at 11:13:45AM +, Lowry Li (Arm 
> > > > > > > > > > Technology China) wrote:
> > > > > > > > > > > From: "Lowry Li (Arm Technology China)" 
> > > > > > > > > > >
> > > > > > > > > > > The komeda internal resources (pipelines) are shared 
> > > > > > > > > > > between crtcs,
> > > > > > > > > > > and resources release by disable_crtc. This commit is 
> > > > > > > > > > > working for once
> > > > > > > > > > > user forgot disabling crtc like app quit abnomally, and 
> > > > > > > > > > > then the
> > > > > > > > > > > resources can not be used by another crtc. Adds 
> > > > > > > > > > > drop_master to
> > > > > > > > > > > shutdown the device and make sure all the komeda 
> > > > > > > > > > > resources have been
> > > > > > > > > > > released and can be used for the next usage.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Lowry Li (Arm Technology China) 
> > > > > > > > > > > 
> > > > > > > > > > > ---
> > > > > > > > > > >  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 13 
> > > > > > > > > > > +
> > > > > > > > > > >  1 file changed, 13 insertions(+)
> > > > > > > > > > >
> > > > > > > > > > > diff --git 
> > > > > > > > > > > a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
> > > > > > > > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> > > > > > > > > > > index 8543860..647bce5 100644
> > > > > > > > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> > > > > > > > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> > > > > > > > > > > @@ -54,11 +54,24 @@ static irqreturn_t 
> > > > > > > > > > > komeda_kms_irq_handler(int irq, void *data)
> > > > > > > > > > >  return status;
> > > > > > > > > > >  }
> > > > > > > > > > >
> > > > > > > > > > > +/* Komeda internal resources (pipelines) are shared 
> > > > > > > > > > > between crtcs, and resources
> > > > > > > > > > > + * are released by disable_crtc. But if user forget 
> > > > > > > > > > > disabling crtc like app quit
> > > > > > > > > > > + * abnormally, the resources can not be used by another 
> > > > > > > > > > > crtc.
> > > > > > > > > > > + * Use drop_master to shutdown the device and make sure 
> > > > > > > > > > > all the komeda resources
> > > > > > > > > > > + * have been released, and can be used for the next 
> > > > > > > > > > > usage.
> > > > > > > > > > > + */
> > > > > > > > > >
> > > > > > > > > > No. If we want this, we need to 

[PATCH] drm/komeda: Adds power management support

2019-06-16 Thread Lowry Li (Arm Technology China)
Adds runtime and system power management support in KMS kernel driver.

Depends on:
- https://patchwork.freedesktop.org/series/61650/
- https://patchwork.freedesktop.org/series/60083/

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 30 +
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 54 ++--
 4 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 66c5e0d..1b4ea8a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -257,6 +257,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 komeda_crtc_atomic_enable(struct drm_crtc *crtc,
  struct drm_crtc_state *old)
 {
+   pm_runtime_get_sync(crtc->dev->dev);
komeda_crtc_prepare(to_kcrtc(crtc));
drm_crtc_vblank_on(crtc);
komeda_crtc_do_flush(crtc, old);
@@ -330,6 +331,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 
drm_crtc_vblank_off(crtc);
komeda_crtc_unprepare(kcrtc);
+   pm_runtime_put(crtc->dev->dev);
 }
 
 static void
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 405c64d..edd0943 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -308,3 +308,33 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
devm_kfree(dev, mdev);
 }
+
+int komeda_dev_resume(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   if (mdev->iommu && mdev->funcs->connect_iommu) {
+   ret = mdev->funcs->connect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("connect iommu failed.\n");
+   return ret;
+   }
+   }
+
+   return mdev->funcs->enable_irq(mdev);
+}
+
+int komeda_dev_suspend(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   if (mdev->iommu && mdev->funcs->disconnect_iommu) {
+   ret = mdev->funcs->disconnect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("disconnect iommu failed.\n");
+   return ret;
+   }
+   }
+
+   return mdev->funcs->disable_irq(mdev);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index d1c86b6..096f9f7 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -207,4 +207,6 @@ struct komeda_dev {
 
 struct komeda_dev *dev_to_mdev(struct device *dev);
 
+int komeda_dev_resume(struct komeda_dev *mdev);
+int komeda_dev_suspend(struct komeda_dev *mdev);
 #endif /*_KOMEDA_DEV_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index cfa5068..aa4cef1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "komeda_dev.h"
 #include "komeda_kms.h"
@@ -32,6 +33,9 @@ static void komeda_unbind(struct device *dev)
return;
 
komeda_kms_detach(mdrv->kms);
+
+   pm_runtime_disable(dev);
+
komeda_dev_destroy(mdrv->mdev);
 
dev_set_drvdata(dev, NULL);
@@ -52,6 +56,9 @@ static int komeda_bind(struct device *dev)
err = PTR_ERR(mdrv->mdev);
goto free_mdrv;
}
+   dev_set_drvdata(dev, mdrv);
+
+   pm_runtime_enable(dev);
 
mdrv->kms = komeda_kms_attach(mdrv->mdev);
if (IS_ERR(mdrv->kms)) {
@@ -59,11 +66,10 @@ static int komeda_bind(struct device *dev)
goto destroy_mdev;
}
 
-   dev_set_drvdata(dev, mdrv);
-
return 0;
 
 destroy_mdev:
+   pm_runtime_disable(dev);
komeda_dev_destroy(mdrv->mdev);
 
 free_mdrv:
@@ -134,13 +140,55 @@ static int komeda_platform_remove(struct platform_device 
*pdev)
 
 MODULE_DEVICE_TABLE(of, komeda_of_match);
 
+static int komeda_rt_pm_suspend(struct device *dev)
+{
+   dev_info(dev, "%s\n", __func__);
+   return 0;
+}
+
+static int komeda_rt_pm_resume(struct device *dev)
+{
+   dev_info(dev, "%s\n", __func__);
+   return 0;
+}
+
+static int __maybe_unused komeda_pm_suspend(struct device *dev)
+{
+   struct komeda_drv *mdrv = dev_get_drvdata(dev);
+   struct drm_device *drm = >kms->base;
+   int res;
+
+   dev_info(dev, "%s\n", __func__);
+   res = drm_mode_confi

[PATCH] drm/komeda: Clear enable bit in CU_INPUTx_CONTROL

2019-05-14 Thread Lowry Li (Arm Technology China)
Besides clearing the input ID to zero, D71 compiz also has input
enable bit in CU_INPUTx_CONTROL which need to be cleared.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_component.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 1135e38..f8846c6 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -435,8 +435,18 @@ static void d71_component_disable(struct komeda_component 
*c)
 
malidp_write32(reg, BLK_CONTROL, 0);
 
-   for (i = 0; i < c->max_active_inputs; i++)
+   for (i = 0; i < c->max_active_inputs; i++) {
malidp_write32(reg, BLK_INPUT_ID0 + (i << 2), 0);
+
+   /* Besides clearing the input ID to zero, D71 compiz also has
+* input enable bit in CU_INPUTx_CONTROL which need to be
+* cleared.
+*/
+   if (has_bit(c->id, KOMEDA_PIPELINE_COMPIZS))
+   malidp_write32(reg, CU_INPUT0_CONTROL +
+  i * CU_PER_INPUT_REGS * 4,
+  CU_INPUT_CTRL_ALPHA(0xFF));
+   }
 }
 
 static void compiz_enable_input(u32 __iomem *id_reg,
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/komeda: Creates plane alpha and blend mode properties

2019-05-24 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Creates plane alpha and blend mode properties attached to plane.

This patch depends on:
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/58665/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59471/

Changes since v1:
- Adds patch denpendency in the comment

Changes since v2:
- Remove [RFC] from the subject

Changes since v3:
- Rebase the code

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index e7cd690..9b87c25 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -303,6 +303,17 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_alpha_property(plane);
+   if (err)
+   goto cleanup;
+
+   err = drm_plane_create_blend_mode_property(plane,
+   BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+   BIT(DRM_MODE_BLEND_PREMULTI)   |
+   BIT(DRM_MODE_BLEND_COVERAGE));
+   if (err)
+   goto cleanup;
+
err = komeda_plane_create_layer_properties(kplane, layer);
if (err)
goto cleanup;
-- 
1.9.1



[PATCH] drm/komeda: Adds zorder support

2019-05-19 Thread Lowry Li (Arm Technology China)
- Creates the zpos property.
- Implement komeda_crtc_normalize_zpos to replace
drm_atomic_normalize_zpos, reasons as the following:

1. The drm_atomic_normalize_zpos allows to configure same zpos for
different planes, but komeda doesn't support such configuration.
2. For further slave pipline case, Komeda need to calculate the
max_slave_zorder, we will merge such calculation into
komed_crtc_normalize_zpos to save a separated plane_state loop.
3. For feature none-scaling layer_split, which a plane_state will be
assigned to two individual layers(left/right), which requires two
normalize_zpos for this plane, plane_st->normalize_zpos will be used
by left layer, normalize_zpos + 1 for right_layer.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59747/
- https://patchwork.freedesktop.org/series/59915/
- https://patchwork.freedesktop.org/series/60083/
- https://patchwork.freedesktop.org/series/60698/

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c   | 90 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h   |  3 +
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c |  6 +-
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 306ea06..0ec7665 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -100,6 +100,90 @@ static void komeda_kms_commit_tail(struct drm_atomic_state 
*old_state)
.atomic_commit_tail = komeda_kms_commit_tail,
 };
 
+static int komeda_plane_state_list_add(struct drm_plane_state *plane_st,
+  struct list_head *zorder_list)
+{
+   struct komeda_plane_state *new = to_kplane_st(plane_st);
+   struct komeda_plane_state *node, *last;
+
+   last = list_empty(zorder_list) ?
+  NULL : list_last_entry(zorder_list, typeof(*last), zlist_node);
+
+   /* Considering the list sequence is zpos increasing, so if list is empty
+* or the zpos of new node bigger than the last node in list, no need
+* loop and just insert the new one to the tail of the list.
+*/
+   if (!last || (new->base.zpos > last->base.zpos)) {
+   list_add_tail(>zlist_node, zorder_list);
+   return 0;
+   }
+
+   /* Build the list by zpos increasing */
+   list_for_each_entry(node, zorder_list, zlist_node) {
+   if (new->base.zpos < node->base.zpos) {
+   list_add_tail(>zlist_node, >zlist_node);
+   break;
+   } else if (node->base.zpos == new->base.zpos) {
+   struct drm_plane *a = node->base.plane;
+   struct drm_plane *b = new->base.plane;
+
+   /* Komeda doesn't support setting a same zpos for
+* different planes.
+*/
+   DRM_DEBUG_ATOMIC("PLANE: %s and PLANE: %s are 
configured same zpos: %d.\n",
+a->name, b->name, node->base.zpos);
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
+static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_st)
+{
+   struct drm_atomic_state *state = crtc_st->state;
+   struct komeda_plane_state *kplane_st;
+   struct drm_plane_state *plane_st;
+   struct drm_framebuffer *fb;
+   struct drm_plane *plane;
+   struct list_head zorder_list;
+   int order = 0, err;
+
+   DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
+crtc->base.id, crtc->name);
+
+   INIT_LIST_HEAD(_list);
+
+   /* This loop also added all effected planes into the new state */
+   drm_for_each_plane_mask(plane, crtc->dev, crtc_st->plane_mask) {
+   plane_st = drm_atomic_get_plane_state(state, plane);
+   if (IS_ERR(plane_st))
+   return PTR_ERR(plane_st);
+
+   /* Build a list by zpos increasing */
+   err = komeda_plane_state_list_add(plane_st, _list);
+   if (err)
+   return err;
+   }
+
+   list_for_each_entry(kplane_st, _list, zlist_node) {
+   plane_st = _st->base;
+   fb = plane_st->fb;
+   plane = plane_st->plane;
+
+   plane_st->normalized_zpos = order++;
+
+   DRM_DEBUG_ATOMIC("[PLANE:%d:%s] zpos:%d, normalized zpos: %d\n",
+   

[PATCH v1 0/2] drm/komeda: Add SMMU support on Komeda driver

2019-04-30 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for SMMU on Komeda driver.
Also updates the device-tree doc about how to enable SMMU by devicetree.

This patch series depends on:
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/

Thanks,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Adds SMMU support
  dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

 .../devicetree/bindings/display/arm,komeda.txt |  7 
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 17 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 7 files changed, 89 insertions(+)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 1/2] drm/komeda: Adds SMMU support

2019-04-30 Thread Lowry Li (Arm Technology China)
Adds iommu_connect and disconnect for SMMU support, and configures
TBU translation once SMMU has been attached to the display device.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  5 +++
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 49 ++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c| 17 
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h|  7 
 .../drm/arm/display/komeda/komeda_framebuffer.c|  2 +
 .../drm/arm/display/komeda/komeda_framebuffer.h|  2 +
 6 files changed, 82 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 33ca171..9065040 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -215,6 +215,8 @@ static void d71_layer_update(struct komeda_component *c,
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
 
+   if (kfb->is_va)
+   ctrl |= L_TBU_EN;
malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
 }
 
@@ -348,6 +350,9 @@ static void d71_wb_layer_update(struct komeda_component *c,
   fb->pitches[i] & 0x);
}
 
+   if (kfb->is_va)
+   ctrl |= LW_TBU_EN;
+
malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(>inputs[0]));
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 9603de9..45c98a7 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -517,6 +517,53 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
+static int d71_connect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int i, ret;
+
+   if (!d71->integrates_tbu)
+   return -1;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_CONNECT_MODE);
+
+   ret = dp_wait_cond(has_bits(check_bits, malidp_read32(reg, BLK_STATUS)),
+   100, 1000, 1000);
+   if (ret <= 0) {
+   DRM_ERROR("connect to TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   return -ETIMEDOUT;
+   }
+
+   for (i = 0; i < d71->num_pipelines; i++)
+   malidp_write32_mask(d71->pipes[i]->lpu_addr, LPU_TBU_CONTROL,
+   LPU_TBU_CTRL_TLBPEN, LPU_TBU_CTRL_TLBPEN);
+   return 0;
+}
+
+static int d71_disconnect_iommu(struct komeda_dev *mdev)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+   u32 __iomem *reg = d71->gcu_addr;
+   u32 check_bits = (d71->num_pipelines == 2) ?
+GCU_STATUS_TCS0 | GCU_STATUS_TCS1 : GCU_STATUS_TCS0;
+   int ret;
+
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, TBU_DISCONNECT_MODE);
+
+   ret = dp_wait_cond(((malidp_read32(reg, BLK_STATUS) & check_bits) == 0),
+   100, 1000, 1000);
+   if (ret <= 0) {
+   DRM_ERROR("disconnect from TCU timeout!\n");
+   malidp_write32_mask(reg, BLK_CONTROL, 0x7, INACTIVE_MODE);
+   }
+
+   return ret > 0 ? 0 : -1;
+}
+
 static struct komeda_dev_funcs d71_chip_funcs = {
.init_format_table = d71_init_fmt_tbl,
.enum_resources = d71_enum_resources,
@@ -527,6 +574,8 @@ static void d71_init_fmt_tbl(struct komeda_dev *mdev)
.on_off_vblank  = d71_on_off_vblank,
.change_opmode  = d71_change_opmode,
.flush  = d71_flush,
+   .connect_iommu  = d71_connect_iommu,
+   .disconnect_iommu = d71_disconnect_iommu,
 };
 
 struct komeda_dev_funcs *
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index e4e5b58..2d97c82 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -251,6 +251,18 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
dev->dma_parms = >dma_parms;
dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
+   mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
+   if (!mdev->iommu)
+   DRM_INFO("continue without IOMMU support!\n");
+
+   if (mdev->iommu && mdev->funcs->connect

[PATCH v1 2/2] dt/bindings: drm/komeda: Adds SMMU support for D71 devicetree

2019-04-30 Thread Lowry Li (Arm Technology China)
Updates the device-tree doc about how to enable SMMU by devicetree.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 Documentation/devicetree/bindings/display/arm,komeda.txt | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/arm,komeda.txt 
b/Documentation/devicetree/bindings/display/arm,komeda.txt
index 02b2265..b12c045 100644
--- a/Documentation/devicetree/bindings/display/arm,komeda.txt
+++ b/Documentation/devicetree/bindings/display/arm,komeda.txt
@@ -11,6 +11,10 @@ Required properties:
   - "pclk": for the APB interface clock
 - #address-cells: Must be 1
 - #size-cells: Must be 0
+- iommus: configure the stream id to IOMMU, Must be configured if want to
+enable iommu in display. for how to configure this node please reference
+devicetree/bindings/iommu/arm,smmu-v3.txt,
+devicetree/bindings/iommu/iommu.txt
 
 Required properties for sub-node: pipeline@nq
 Each device contains one or two pipeline sub-nodes (at least one), each
@@ -44,6 +48,9 @@ Example:
interrupts = <0 168 4>;
clocks = <_mclk>, <_aclk>;
clock-names = "mclk", "pclk";
+   iommus = < 0>, < 1>, < 2>, < 3>,
+   < 4>, < 5>, < 6>, < 7>,
+   < 8>, < 9>;
 
dp0_pipe0: pipeline@0 {
clocks = <>, <_aclk>;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 0/2] drm/komeda: Add rotation support on Komeda driver

2019-04-19 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for rotation on Komeda driver.
This patch series depends on:
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/
- https://patchwork.freedesktop.org/series/59471/

Regards,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add rotation support on Komeda driver
  drm/komeda: Adds limitation check for AFBC wide block not support
Rot90

 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c  | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c   |  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h   | 19 ++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c   | 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h   |  5 +++--
 .../drm/arm/display/komeda/komeda_pipeline_state.c| 15 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 18 +-
 7 files changed, 82 insertions(+), 15 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 2/2] drm/komeda: Adds limitation check for AFBC wide block not support Rot90

2019-04-19 Thread Lowry Li (Arm Technology China)
Komeda series hardware doesn't support Rot90 for AFBC wide block. So
add limitation check to reject it if such configuration has been posted.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c|  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h|  8 +++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c| 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h|  5 +++--
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c |  8 +++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  |  2 +-
 7 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 34506ef..9603de9 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -494,11 +494,26 @@ static int d71_enum_resources(struct komeda_dev *mdev)
{__HW_ID(6, 7), 0/*DRM_FORMAT_YUV420_10BIT*/, 1,RICH,   
Rot_ALL_H_V,LYT_NM, AFB_TH},
 };
 
+static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot)
+{
+   uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
+
+   if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
+   drm_rotation_90_or_270(rot)) {
+   DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
+   return false;
+   }
+
+   return true;
+}
+
 static void d71_init_fmt_tbl(struct komeda_dev *mdev)
 {
struct komeda_format_caps_table *table = >fmt_tbl;
 
table->format_caps = d71_format_caps_table;
+   table->format_mod_supported = d71_format_mod_supported;
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
index b219514..cd4d9f5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
@@ -74,7 +74,8 @@
 };
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier)
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot)
 {
const struct komeda_format_caps *caps;
 
@@ -85,6 +86,10 @@ bool komeda_format_mod_supported(struct 
komeda_format_caps_table *table,
if (!(caps->supported_layer_types & layer_type))
return false;
 
+   if (table->format_mod_supported)
+   return table->format_mod_supported(caps, layer_type, modifier,
+  rot);
+
return true;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index 96de22e..381e873 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -71,10 +71,15 @@ struct komeda_format_caps {
  *
  * @n_formats: the size of format_caps list.
  * @format_caps: format_caps list.
+ * @format_mod_supported: Optional. Some HW may have special requirements or
+ * limitations which can not be described by format_caps, this func supply HW
+ * the ability to do the further HW specific check.
  */
 struct komeda_format_caps_table {
u32 n_formats;
const struct komeda_format_caps *format_caps;
+   bool (*format_mod_supported)(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot);
 };
 
 extern u64 komeda_supported_modifiers[];
@@ -100,6 +105,7 @@ u32 *komeda_get_layer_fourcc_list(struct 
komeda_format_caps_table *table,
 void komeda_put_fourcc_list(u32 *fourcc_list);
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier);
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot);
 
 #endif
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index f842c88..d5822a3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -239,20 +239,20 @@ struct drm_framebuffer *
 }
 
 /* if the fb can be supported by a specific layer */
-bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type)
+bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type,
+ u32 rot)
 {
struct drm_fra

[PATCH v1 1/2] drm/komeda: Add rotation support on Komeda driver

2019-04-19 Thread Lowry Li (Arm Technology China)
- Adds rotation property to plane.
- Komeda display rotation support diverges from the specific formats,
so need to check the user required rotation type with the format caps
and reject the commit if it can not be supported.
- In the layer validate flow, sets the rotation value to the layer
state. If r90 or r270, swap the width and height of the data flow
for next stage.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h  | 11 +++
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c   |  7 +++
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c| 16 
 3 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index bc3b2df36..96de22e 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -79,6 +79,17 @@ struct komeda_format_caps_table {
 
 extern u64 komeda_supported_modifiers[];
 
+static inline const char *komeda_get_format_name(u32 fourcc, u64 modifier)
+{
+   struct drm_format_name_buf buf;
+   static char name[64];
+
+   snprintf(name, sizeof(name), "%s with modifier: 0x%llx.",
+drm_get_format_name(fourcc, ), modifier);
+
+   return name;
+}
+
 const struct komeda_format_caps *
 komeda_get_format_caps(struct komeda_format_caps_table *table,
   u32 fourcc, u64 modifier);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 9b29e9a..8c133e4 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -317,6 +317,13 @@ struct komeda_pipeline_state *
/* update the data flow for the next stage */
komeda_component_set_output(>input, >base, 0);
 
+   /*
+* The rotation has been handled by layer, so adjusted the data flow for
+* the next stage.
+*/
+   if (drm_rotation_90_or_270(st->rot))
+   swap(dflow->in_h, dflow->in_w);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 14d6861..5e5bfdb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -9,12 +9,14 @@
 #include 
 #include "komeda_dev.h"
 #include "komeda_kms.h"
+#include "komeda_framebuffer.h"
 
 static int
 komeda_plane_init_data_flow(struct drm_plane_state *st,
struct komeda_data_flow_cfg *dflow)
 {
struct drm_framebuffer *fb = st->fb;
+   const struct komeda_format_caps *caps = to_kfb(fb)->format_caps;
 
memset(dflow, 0, sizeof(*dflow));
 
@@ -35,6 +37,15 @@
dflow->in_w = st->src_w >> 16;
dflow->in_h = st->src_h >> 16;
 
+   dflow->rot = drm_rotation_simplify(st->rotation, caps->supported_rots);
+   if (!has_bits(dflow->rot, caps->supported_rots)) {
+   DRM_DEBUG_ATOMIC("rotation(0x%x) isn't supported by %s.\n",
+dflow->rot,
+komeda_get_format_name(caps->fourcc,
+   fb->modifier));
+   return -EINVAL;
+   }
+
return 0;
 }
 
@@ -233,6 +244,11 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
+layer->supported_rots);
+   if (err)
+   goto cleanup;
+
err = drm_plane_create_alpha_property(plane);
if (err)
goto cleanup;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/komeda: Adds VRR support

2019-07-03 Thread Lowry Li (Arm Technology China)
Adds a new drm property "vrr" and "vrr_enable" and implemented
the set/get functions, through which userspace could set vfp
data to komeda.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c |  6 +++
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c   | 62 ++
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h| 12 +
 .../gpu/drm/arm/display/komeda/komeda_pipeline.h   |  4 +-
 4 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index ed3f273..c1355f5 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1065,6 +1065,7 @@ static void d71_timing_ctrlr_update(struct 
komeda_component *c,
struct komeda_component_state *state)
 {
struct drm_crtc_state *crtc_st = state->crtc->state;
+   struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
struct drm_display_mode *mode = _st->adjusted_mode;
u32 __iomem *reg = c->reg;
u32 hactive, hfront_porch, hback_porch, hsync_len;
@@ -1102,6 +1103,9 @@ static void d71_timing_ctrlr_update(struct 
komeda_component *c,
value |= BS_CTRL_DL;
}
 
+   if (kcrtc_st->en_vrr)
+   malidp_write32_mask(reg, BS_VINTERVALS, 0x3FFF, kcrtc_st->vfp);
+
malidp_write32(reg, BLK_CONTROL, value);
 }
 
@@ -1171,6 +1175,8 @@ static int d71_timing_ctrlr_init(struct d71_dev *d71,
ctrlr = to_ctrlr(c);
 
ctrlr->supports_dual_link = true;
+   ctrlr->supports_vrr = true;
+   set_range(>vfp_range, 0, 0x3FF);
 
return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 4f580b0..3744e6d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -467,6 +467,8 @@ static void komeda_crtc_reset(struct drm_crtc *crtc)
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state) {
+   state->vfp = 0;
+   state->en_vrr = 0;
crtc->state = >base;
crtc->state->crtc = crtc;
}
@@ -487,6 +489,8 @@ static void komeda_crtc_reset(struct drm_crtc *crtc)
new->affected_pipes = old->active_pipes;
new->clock_ratio = old->clock_ratio;
new->max_slave_zorder = old->max_slave_zorder;
+   new->vfp = old->vfp;
+   new->en_vrr = old->en_vrr;
 
return >base;
 }
@@ -525,6 +529,30 @@ static void komeda_crtc_vblank_disable(struct drm_crtc 
*crtc)
 
if (property == kcrtc->clock_ratio_property) {
*val = kcrtc_st->clock_ratio;
+   } else if (property == kcrtc->vrr_property) {
+   *val = kcrtc_st->vfp;
+   } else if (property == kcrtc->vrr_enable_property) {
+   *val = kcrtc_st->en_vrr;
+   } else {
+   DRM_DEBUG_DRIVER("Unknown property %s\n", property->name);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int komeda_crtc_atomic_set_property(struct drm_crtc *crtc,
+  struct drm_crtc_state *state,
+  struct drm_property *property,
+  uint64_t val)
+{
+   struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+   struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
+
+   if (property == kcrtc->vrr_property) {
+   kcrtc_st->vfp = val;
+   } else if (property == kcrtc->vrr_enable_property) {
+   kcrtc_st->en_vrr = val;
} else {
DRM_DEBUG_DRIVER("Unknown property %s\n", property->name);
return -EINVAL;
@@ -544,6 +572,7 @@ static void komeda_crtc_vblank_disable(struct drm_crtc 
*crtc)
.enable_vblank  = komeda_crtc_vblank_enable,
.disable_vblank = komeda_crtc_vblank_disable,
.atomic_get_property= komeda_crtc_atomic_get_property,
+   .atomic_set_property= komeda_crtc_atomic_set_property,
 };
 
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
@@ -613,6 +642,35 @@ static int komeda_crtc_create_slave_planes_property(struct 
komeda_crtc *kcrtc)
return 0;
 }
 
+static int komeda_crtc_create_vrr_property(struct komeda_crtc *kcrtc)
+{
+   struct drm_crtc *crtc = >base;
+   struct drm_property *prop;
+   struct komeda_timing_ctrlr *ctrlr = kcrtc->master->ctrlr;
+
+   if (!ctrlr->supports_vrr)
+   return 0;
+
+   prop = drm_property_create_range(crtc->dev, DRM_MODE_PROP_ATOMIC, "vrr",
+

[PATCH] drm/komeda: Adds register dump support for gcu, lup and dou

2019-06-26 Thread Lowry Li (Arm Technology China)
Adds to support register dump on lpu and dou of pipeline and gcu on D71

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_component.c | 86 +-
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 23 +++---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.h   |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c|  2 +
 4 files changed, 101 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index ecec6ce..ed3f273 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1253,6 +1253,90 @@ int d71_probe_block(struct d71_dev *d71,
return err;
 }
 
+static void d71_gcu_dump(struct d71_dev *d71, struct seq_file *sf)
+{
+   u32 v[5];
+
+   seq_printf(sf, "\n-- GCU --\n");
+
+   get_values_from_reg(d71->gcu_addr, 0, 3, v);
+   seq_printf(sf, "GLB_ARCH_ID:\t\t0x%X\n", v[0]);
+   seq_printf(sf, "GLB_CORE_ID:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "GLB_CORE_INFO:\t\t0x%X\n", v[2]);
+
+   get_values_from_reg(d71->gcu_addr, 0x10, 1, v);
+   seq_printf(sf, "GLB_IRQ_STATUS:\t\t0x%X\n", v[0]);
+
+   get_values_from_reg(d71->gcu_addr, 0xA0, 5, v);
+   seq_printf(sf, "GCU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "GCU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "GCU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "GCU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "GCU_STATUS:\t\t0x%X\n", v[4]);
+
+   get_values_from_reg(d71->gcu_addr, 0xD0, 3, v);
+   seq_printf(sf, "GCU_CONTROL:\t\t0x%X\n", v[0]);
+   seq_printf(sf, "GCU_CONFIG_VALID0:\t0x%X\n", v[1]);
+   seq_printf(sf, "GCU_CONFIG_VALID1:\t0x%X\n", v[2]);
+}
+
+static void d71_lpu_dump(struct d71_pipeline *pipe, struct seq_file *sf)
+{
+   u32 v[6];
+
+   seq_printf(sf, "\n-- LPU%d --\n", pipe->base.id);
+
+   dump_block_header(sf, pipe->lpu_addr);
+
+   get_values_from_reg(pipe->lpu_addr, 0xA0, 6, v);
+   seq_printf(sf, "LPU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "LPU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "LPU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "LPU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "LPU_STATUS:\t\t0x%X\n", v[4]);
+   seq_printf(sf, "LPU_TBU_STATUS:\t\t0x%X\n", v[5]);
+
+   get_values_from_reg(pipe->lpu_addr, 0xC0, 1, v);
+   seq_printf(sf, "LPU_INFO:\t\t0x%X\n", v[0]);
+
+   get_values_from_reg(pipe->lpu_addr, 0xD0, 3, v);
+   seq_printf(sf, "LPU_RAXI_CONTROL:\t0x%X\n", v[0]);
+   seq_printf(sf, "LPU_WAXI_CONTROL:\t0x%X\n", v[1]);
+   seq_printf(sf, "LPU_TBU_CONTROL:\t0x%X\n", v[2]);
+}
+
+static void d71_dou_dump(struct d71_pipeline *pipe, struct seq_file *sf)
+{
+   u32 v[5];
+
+   seq_printf(sf, "\n-- DOU%d --\n", pipe->base.id);
+
+   dump_block_header(sf, pipe->dou_addr);
+
+   get_values_from_reg(pipe->dou_addr, 0xA0, 5, v);
+   seq_printf(sf, "DOU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "DOU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "DOU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "DOU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "DOU_STATUS:\t\t0x%X\n", v[4]);
+}
+
+static void d71_pipeline_dump(struct komeda_pipeline *pipe, struct seq_file 
*sf)
+{
+   struct d71_pipeline *d71_pipe = to_d71_pipeline(pipe);
+
+   d71_lpu_dump(d71_pipe, sf);
+   d71_dou_dump(d71_pipe, sf);
+}
+
 const struct komeda_pipeline_funcs d71_pipeline_funcs = {
-   .downscaling_clk_check = d71_downscaling_clk_check,
+   .downscaling_clk_check  = d71_downscaling_clk_check,
+   .dump_register  = d71_pipeline_dump,
 };
+
+void d71_dump(struct komeda_dev *mdev, struct seq_file *sf)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+
+   d71_gcu_dump(d71, sf);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index caaa2b2..7e7c9e9 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -561,17 +561,18 @@ static int d71_disconnect_iommu(struct komeda_dev *mdev)
 }
 
 static const struct komeda_dev_funcs d71_chip_funcs = {
-   .init_format_table = d71_init_fmt_tbl,
-   .enum_resources = d71_enum_resources,
-   .cleanup= d71_cleanup,
-   .irq_handler= d71_irq_handler,
-   .enable_irq = d71_enable_irq,
-

[PATCH] drm/komeda: Adds error event print functionality

2019-06-26 Thread Lowry Li (Arm Technology China)
Adds to print the event message when error happens and the same event
will not be printed until next vsync.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/Makefile   |   1 +
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h   |  13 ++
 drivers/gpu/drm/arm/display/komeda/komeda_event.c | 144 ++
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c   |   2 +
 4 files changed, 160 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_event.c

diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile 
b/drivers/gpu/drm/arm/display/komeda/Makefile
index 38aa584..3f53d2d 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -7,6 +7,7 @@ ccflags-y := \
 komeda-y := \
komeda_drv.o \
komeda_dev.o \
+   komeda_event.o \
komeda_format_caps.o \
komeda_coeffs.o \
komeda_color_mgmt.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 096f9f7..e863ec3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -40,6 +40,17 @@
 #define KOMEDA_ERR_TTNGBIT_ULL(30)
 #define KOMEDA_ERR_TTF BIT_ULL(31)
 
+#define KOMEDA_ERR_EVENTS  \
+   (KOMEDA_EVENT_URUN  | KOMEDA_EVENT_IBSY | KOMEDA_EVENT_OVR |\
+   KOMEDA_ERR_TETO | KOMEDA_ERR_TEMR   | KOMEDA_ERR_TITR |\
+   KOMEDA_ERR_CPE  | KOMEDA_ERR_CFGE   | KOMEDA_ERR_AXIE |\
+   KOMEDA_ERR_ACE0 | KOMEDA_ERR_ACE1   | KOMEDA_ERR_ACE2 |\
+   KOMEDA_ERR_ACE3 | KOMEDA_ERR_DRIFTTO| KOMEDA_ERR_FRAMETO |\
+   KOMEDA_ERR_ZME  | KOMEDA_ERR_MERR   | KOMEDA_ERR_TCF |\
+   KOMEDA_ERR_TTNG | KOMEDA_ERR_TTF)
+
+#define KOMEDA_WARN_EVENTS KOMEDA_ERR_CSCE
+
 /* malidp device id */
 enum {
MALI_D71 = 0,
@@ -207,6 +218,8 @@ struct komeda_dev {
 
 struct komeda_dev *dev_to_mdev(struct device *dev);
 
+void komeda_print_events(struct komeda_events *evts);
+
 int komeda_dev_resume(struct komeda_dev *mdev);
 int komeda_dev_suspend(struct komeda_dev *mdev);
 #endif /*_KOMEDA_DEV_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
new file mode 100644
index 000..309dbe2
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang 
+ *
+ */
+#include 
+
+#include "komeda_dev.h"
+
+struct komeda_str {
+   char *str;
+   u32 sz;
+   u32 len;
+};
+
+/* return 0 on success,  < 0 on no space.
+ */
+static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
+{
+   va_list args;
+   int num, free_sz;
+   int err;
+
+   free_sz = str->sz - str->len;
+   if (free_sz <= 0)
+   return -ENOSPC;
+
+   va_start(args, fmt);
+
+   num = vsnprintf(str->str + str->len, free_sz, fmt, args);
+
+   va_end(args);
+
+   if (num <= free_sz) {
+   str->len += num;
+   err = 0;
+   } else {
+   str->len = str->sz;
+   err = -ENOSPC;
+   }
+
+   return err;
+}
+
+static void evt_sprintf(struct komeda_str *str, u64 evt, const char *msg)
+{
+   if (evt)
+   komeda_sprintf(str, msg);
+}
+
+static void evt_str(struct komeda_str *str, u64 events)
+{
+   if (events == 0ULL) {
+   evt_sprintf(str, 1, "None");
+   return;
+   }
+
+   evt_sprintf(str, events & KOMEDA_EVENT_VSYNC, "VSYNC|");
+   evt_sprintf(str, events & KOMEDA_EVENT_FLIP, "FLIP|");
+   evt_sprintf(str, events & KOMEDA_EVENT_EOW, "EOW|");
+   evt_sprintf(str, events & KOMEDA_EVENT_MODE, "OP-MODE|");
+
+   evt_sprintf(str, events & KOMEDA_EVENT_URUN, "UNDERRUN|");
+   evt_sprintf(str, events & KOMEDA_EVENT_OVR, "OVERRUN|");
+
+   /* GLB error */
+   evt_sprintf(str, events & KOMEDA_ERR_MERR, "MERR|");
+   evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
+
+   /* DOU error */
+   evt_sprintf(str, events & KOMEDA_ERR_DRIFTTO, "DRIFTTO|");
+   evt_sprintf(str, events & KOMEDA_ERR_FRAMETO, "FRAMETO|");
+   evt_sprintf(str, events & KOMEDA_ERR_TETO, "TETO|");
+   evt_sprintf(str, events & KOMEDA_ERR_CSCE, "CSCE|");
+
+   /* LPU errors or events */
+   evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|");
+   evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|");
+   evt_sprintf(str, events & KOMEDA_ER

[PATCH v1 2/2] drm/komeda: Adds limitation check for AFBC wide block not support Rot90

2019-04-21 Thread Lowry Li (Arm Technology China)
Komeda series hardware doesn't support Rot90 for AFBC wide block. So
add limitation check to reject it if such configuration has been posted.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c   | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c|  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h|  8 +++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c| 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h|  5 +++--
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c |  8 +++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  |  2 +-
 7 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 34506ef..9603de9 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -494,11 +494,26 @@ static int d71_enum_resources(struct komeda_dev *mdev)
{__HW_ID(6, 7), 0/*DRM_FORMAT_YUV420_10BIT*/, 1,RICH,   
Rot_ALL_H_V,LYT_NM, AFB_TH},
 };
 
+static bool d71_format_mod_supported(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot)
+{
+   uint64_t layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
+
+   if ((layout == AFBC_FORMAT_MOD_BLOCK_SIZE_32x8) &&
+   drm_rotation_90_or_270(rot)) {
+   DRM_DEBUG_ATOMIC("D71 doesn't support ROT90 for WB-AFBC.\n");
+   return false;
+   }
+
+   return true;
+}
+
 static void d71_init_fmt_tbl(struct komeda_dev *mdev)
 {
struct komeda_format_caps_table *table = >fmt_tbl;
 
table->format_caps = d71_format_caps_table;
+   table->format_mod_supported = d71_format_mod_supported;
table->n_formats = ARRAY_SIZE(d71_format_caps_table);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
index b219514..cd4d9f5 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
@@ -74,7 +74,8 @@
 };
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier)
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot)
 {
const struct komeda_format_caps *caps;
 
@@ -85,6 +86,10 @@ bool komeda_format_mod_supported(struct 
komeda_format_caps_table *table,
if (!(caps->supported_layer_types & layer_type))
return false;
 
+   if (table->format_mod_supported)
+   return table->format_mod_supported(caps, layer_type, modifier,
+  rot);
+
return true;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index 96de22e..381e873 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -71,10 +71,15 @@ struct komeda_format_caps {
  *
  * @n_formats: the size of format_caps list.
  * @format_caps: format_caps list.
+ * @format_mod_supported: Optional. Some HW may have special requirements or
+ * limitations which can not be described by format_caps, this func supply HW
+ * the ability to do the further HW specific check.
  */
 struct komeda_format_caps_table {
u32 n_formats;
const struct komeda_format_caps *format_caps;
+   bool (*format_mod_supported)(const struct komeda_format_caps *caps,
+u32 layer_type, u64 modifier, u32 rot);
 };
 
 extern u64 komeda_supported_modifiers[];
@@ -100,6 +105,7 @@ u32 *komeda_get_layer_fourcc_list(struct 
komeda_format_caps_table *table,
 void komeda_put_fourcc_list(u32 *fourcc_list);
 
 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
-u32 layer_type, u32 fourcc, u64 modifier);
+u32 layer_type, u32 fourcc, u64 modifier,
+u32 rot);
 
 #endif
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index f842c88..d5822a3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -239,20 +239,20 @@ struct drm_framebuffer *
 }
 
 /* if the fb can be supported by a specific layer */
-bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type)
+bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type,
+ u32 rot)
 {
struct drm_fra

[PATCH v1 1/2] drm/komeda: Add rotation support on Komeda driver

2019-04-21 Thread Lowry Li (Arm Technology China)
- Adds rotation property to plane.
- Komeda display rotation support diverges from the specific formats,
so need to check the user required rotation type with the format caps
and reject the commit if it can not be supported.
- In the layer validate flow, sets the rotation value to the layer
state. If r90 or r270, swap the width and height of the data flow
for next stage.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h  | 11 +++
 .../gpu/drm/arm/display/komeda/komeda_pipeline_state.c   |  7 +++
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c| 16 
 3 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
index bc3b2df36..96de22e 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
@@ -79,6 +79,17 @@ struct komeda_format_caps_table {
 
 extern u64 komeda_supported_modifiers[];
 
+static inline const char *komeda_get_format_name(u32 fourcc, u64 modifier)
+{
+   struct drm_format_name_buf buf;
+   static char name[64];
+
+   snprintf(name, sizeof(name), "%s with modifier: 0x%llx.",
+drm_get_format_name(fourcc, ), modifier);
+
+   return name;
+}
+
 const struct komeda_format_caps *
 komeda_get_format_caps(struct komeda_format_caps_table *table,
   u32 fourcc, u64 modifier);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 9b29e9a..8c133e4 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -317,6 +317,13 @@ struct komeda_pipeline_state *
/* update the data flow for the next stage */
komeda_component_set_output(>input, >base, 0);
 
+   /*
+* The rotation has been handled by layer, so adjusted the data flow for
+* the next stage.
+*/
+   if (drm_rotation_90_or_270(st->rot))
+   swap(dflow->in_h, dflow->in_w);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 14d6861..5e5bfdb 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -9,12 +9,14 @@
 #include 
 #include "komeda_dev.h"
 #include "komeda_kms.h"
+#include "komeda_framebuffer.h"
 
 static int
 komeda_plane_init_data_flow(struct drm_plane_state *st,
struct komeda_data_flow_cfg *dflow)
 {
struct drm_framebuffer *fb = st->fb;
+   const struct komeda_format_caps *caps = to_kfb(fb)->format_caps;
 
memset(dflow, 0, sizeof(*dflow));
 
@@ -35,6 +37,15 @@
dflow->in_w = st->src_w >> 16;
dflow->in_h = st->src_h >> 16;
 
+   dflow->rot = drm_rotation_simplify(st->rotation, caps->supported_rots);
+   if (!has_bits(dflow->rot, caps->supported_rots)) {
+   DRM_DEBUG_ATOMIC("rotation(0x%x) isn't supported by %s.\n",
+dflow->rot,
+komeda_get_format_name(caps->fourcc,
+   fb->modifier));
+   return -EINVAL;
+   }
+
return 0;
 }
 
@@ -233,6 +244,11 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
+   err = drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
+layer->supported_rots);
+   if (err)
+   goto cleanup;
+
err = drm_plane_create_alpha_property(plane);
if (err)
goto cleanup;
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 0/2] drm/komeda: Add rotation support on Komeda driver

2019-04-21 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the support for rotation on Komeda driver.
For rotation, D71 doesn't support Rot90 for AFBC wide block. So this patch
set also includes the limitation check.

This patch series depends on:
- https://patchwork.freedesktop.org/series/54449/
- https://patchwork.freedesktop.org/series/54450/
- https://patchwork.freedesktop.org/series/58710/
- https://patchwork.freedesktop.org/series/59000/
- https://patchwork.freedesktop.org/series/59002/

Regards,
Lowry

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add rotation support on Komeda driver
  drm/komeda: Adds limitation check for AFBC wide block not support
Rot90

 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c  | 15 +++
 .../gpu/drm/arm/display/komeda/komeda_format_caps.c   |  7 ++-
 .../gpu/drm/arm/display/komeda/komeda_format_caps.h   | 19 ++-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.c   | 18 +-
 .../gpu/drm/arm/display/komeda/komeda_framebuffer.h   |  5 +++--
 .../drm/arm/display/komeda/komeda_pipeline_state.c| 15 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 18 +-
 7 files changed, 82 insertions(+), 15 deletions(-)

-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH] drm/komeda: Adds system power management support

2019-07-01 Thread Lowry Li (Arm Technology China)
Hi,

This is a duplicated patchset and please ignore this.
The latest changes for power management  have been committed at:
https://patchwork.freedesktop.org/series/62181/
Sorry for the inconvenience.

Best regards,
Lowry

On Fri, Jun 21, 2019 at 03:57:29PM +0800, Lowry Li (Arm Technology China) wrote:
> From: "Lowry Li (Arm Technology China)" 
> 
> Adds system power management support in KMS kernel driver.
> 
> Depends on:
> - https://patchwork.freedesktop.org/series/61650/
> - https://patchwork.freedesktop.org/series/60083/
> - https://patchwork.freedesktop.org/series/61647/
> 
> Changes since v1:
> Since we have unified mclk/pclk/pipeline->aclk to one mclk, which will
> be turned on/off when crtc atomic enable/disable, removed runtime power
> management.
> Adds to disable the aclk when register access finished.
> 
> Changes since v2:
> Removes run time get/put related flow.
> 
> Signed-off-by: Lowry Li (Arm Technology China) 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  1 -
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 63 
> +---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
>  drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 35 +++--
>  4 files changed, 91 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> index cafb445..d14e7f3 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> @@ -5,7 +5,6 @@
>   *
>   */
>  #include 
> -#include 
>  #include 
>  
>  #include 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> index e1aa58e..c9837dc 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> @@ -209,7 +209,7 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
> product->product_id,
> MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
>   err = -ENODEV;
> - goto err_cleanup;
> + goto disable_clk;
>   }
>  
>   DRM_INFO("Found ARM Mali-D%x version r%dp%d\n",
> @@ -222,19 +222,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
>   err = mdev->funcs->enum_resources(mdev);
>   if (err) {
>   DRM_ERROR("enumerate display resource failed.\n");
> - goto err_cleanup;
> + goto disable_clk;
>   }
>  
>   err = komeda_parse_dt(dev, mdev);
>   if (err) {
>   DRM_ERROR("parse device tree failed.\n");
> - goto err_cleanup;
> + goto disable_clk;
>   }
>  
>   err = komeda_assemble_pipelines(mdev);
>   if (err) {
>   DRM_ERROR("assemble display pipelines failed.\n");
> - goto err_cleanup;
> + goto disable_clk;
>   }
>  
>   dev->dma_parms = >dma_parms;
> @@ -247,11 +247,13 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
>   if (mdev->iommu && mdev->funcs->connect_iommu) {
>   err = mdev->funcs->connect_iommu(mdev);
>   if (err) {
> - mdev->iommu = NULL;
> - goto err_cleanup;
> + DRM_ERROR("connect iommu failed.\n");
> + goto disable_clk;
>   }
>   }
>  
> + clk_disable_unprepare(mdev->aclk);
> +
>   err = sysfs_create_group(>kobj, _sysfs_attr_group);
>   if (err) {
>   DRM_ERROR("create sysfs group failed.\n");
> @@ -264,6 +266,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
>  
>   return mdev;
>  
> +disable_clk:
> + clk_disable_unprepare(mdev->aclk);
>  err_cleanup:
>   komeda_dev_destroy(mdev);
>   return ERR_PTR(err);
> @@ -281,6 +285,9 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
>   debugfs_remove_recursive(mdev->debugfs_root);
>  #endif
>  
> + if (mdev->aclk)
> + clk_prepare_enable(mdev->aclk);
> +
>   if (mdev->iommu && mdev->funcs->disconnect_iommu)
>   mdev->funcs->disconnect_iommu(mdev);
>   mdev->iommu = NULL;
> @@ -308,3 +315,47 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
>  
>   devm_kfree(dev, mdev);
>  }
> +
> +int komeda_dev_resume(struct komeda_dev *mdev)
> +{
> + int ret = 0;
> +
> + clk_p

[PATCH] drm/komeda: Adds power management support

2019-07-01 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds system power management support in KMS kernel driver.

Depends on:
- https://patchwork.freedesktop.org/series/61650/
- https://patchwork.freedesktop.org/series/60083/

Changes since v1:
Since we have unified mclk/pclk/pipeline->aclk to one mclk, which will
be turned on/off when crtc atomic enable/disable, removed runtime power
management.
Removes run time get/put related flow.
Adds to disable the aclk when register access finished.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_crtc.c |  1 -
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 65 +---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h  |  2 +
 drivers/gpu/drm/arm/display/komeda/komeda_drv.c  | 30 ++-
 4 files changed, 90 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cafb445..d14e7f3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,7 +5,6 @@
  *
  */
 #include 
-#include 
 #include 
 
 #include 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index e1aa58e..a82f67b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -209,7 +209,7 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
  product->product_id,
  MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
err = -ENODEV;
-   goto err_cleanup;
+   goto disable_clk;
}
 
DRM_INFO("Found ARM Mali-D%x version r%dp%d\n",
@@ -222,19 +222,19 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
err = mdev->funcs->enum_resources(mdev);
if (err) {
DRM_ERROR("enumerate display resource failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_parse_dt(dev, mdev);
if (err) {
DRM_ERROR("parse device tree failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
err = komeda_assemble_pipelines(mdev);
if (err) {
DRM_ERROR("assemble display pipelines failed.\n");
-   goto err_cleanup;
+   goto disable_clk;
}
 
dev->dma_parms = >dma_parms;
@@ -247,11 +247,14 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
if (mdev->iommu && mdev->funcs->connect_iommu) {
err = mdev->funcs->connect_iommu(mdev);
if (err) {
+   DRM_ERROR("connect iommu failed.\n");
mdev->iommu = NULL;
-   goto err_cleanup;
+   goto disable_clk;
}
}
 
+   clk_disable_unprepare(mdev->aclk);
+
err = sysfs_create_group(>kobj, _sysfs_attr_group);
if (err) {
DRM_ERROR("create sysfs group failed.\n");
@@ -264,6 +267,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 
return mdev;
 
+disable_clk:
+   clk_disable_unprepare(mdev->aclk);
 err_cleanup:
komeda_dev_destroy(mdev);
return ERR_PTR(err);
@@ -281,8 +286,12 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
debugfs_remove_recursive(mdev->debugfs_root);
 #endif
 
+   if (mdev->aclk)
+   clk_prepare_enable(mdev->aclk);
+
if (mdev->iommu && mdev->funcs->disconnect_iommu)
-   mdev->funcs->disconnect_iommu(mdev);
+   if (mdev->funcs->disconnect_iommu(mdev))
+   DRM_ERROR("disconnect iommu failed.\n");
mdev->iommu = NULL;
 
for (i = 0; i < mdev->n_pipelines; i++) {
@@ -308,3 +317,47 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
devm_kfree(dev, mdev);
 }
+
+int komeda_dev_resume(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   clk_prepare_enable(mdev->aclk);
+
+   if (mdev->iommu && mdev->funcs->connect_iommu) {
+   ret = mdev->funcs->connect_iommu(mdev);
+   if (ret < 0) {
+   DRM_ERROR("connect iommu failed.\n");
+   goto disable_clk;
+   }
+   }
+
+   ret = mdev->funcs->enable_irq(mdev);
+
+disable_clk:
+   clk_disable_unprepare(mdev->aclk);
+
+   return ret;
+}
+
+int komeda_dev_suspend(struct komeda_dev *mdev)
+{
+   int ret = 0;
+
+   clk_prepare_enable(mdev->aclk);
+
+   if (mdev->iommu && mdev->funcs->disconnect_iommu) {
+   ret

[PATCH v1 2/2] drm/komeda: Adds layer horizontal input size limitation check for D71

2019-08-30 Thread Lowry Li (Arm Technology China)
Adds maximum line size check according to the AFBC decoder limitation
and special Line size limitation(2046) for format: YUV420_10BIT and X0L2.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c| 49 +++
 1 file changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index a56dc56a72fb..41b5bfcbd027 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -401,7 +401,56 @@ static void d71_layer_dump(struct komeda_component *c, 
struct seq_file *sf)
seq_printf(sf, "%sAD_V_CROP:\t\t0x%X\n", prefix, v[2]);
 }
 
+static int d71_layer_validate(struct komeda_component *c,
+ struct komeda_component_state *state)
+{
+   struct komeda_layer_state *st = to_layer_st(state);
+   struct komeda_layer *layer = to_layer(c);
+   struct drm_plane_state *plane_st;
+   struct drm_framebuffer *fb;
+   u32 fourcc, line_sz, max_line_sz;
+
+   plane_st = drm_atomic_get_new_plane_state(state->obj.state,
+ state->plane);
+   fb = plane_st->fb;
+   fourcc = fb->format->format;
+
+   if (drm_rotation_90_or_270(st->rot))
+   line_sz = st->vsize - st->afbc_crop_t - st->afbc_crop_b;
+   else
+   line_sz = st->hsize - st->afbc_crop_l - st->afbc_crop_r;
+
+   if (fb->modifier) {
+   if ((fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) ==
+   AFBC_FORMAT_MOD_BLOCK_SIZE_32x8)
+   max_line_sz = layer->line_sz;
+   else
+   max_line_sz = layer->line_sz / 2;
+
+   if (line_sz > max_line_sz) {
+   DRM_DEBUG_ATOMIC("afbc request line_sz: %d exceed the 
max afbc line_sz: %d.\n",
+line_sz, max_line_sz);
+   return -EINVAL;
+   }
+   }
+
+   if (fourcc == DRM_FORMAT_YUV420_10BIT && line_sz > 2046 && 
(st->afbc_crop_l % 4)) {
+   DRM_DEBUG_ATOMIC("YUV420_10BIT input_hsize: %d exceed the max 
size 2046.\n",
+line_sz);
+   return -EINVAL;
+   }
+
+   if (fourcc == DRM_FORMAT_X0L2 && line_sz > 2046 && (st->addr[0] % 16)) {
+   DRM_DEBUG_ATOMIC("X0L2 input_hsize: %d exceed the max size 
2046.\n",
+line_sz);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static const struct komeda_component_funcs d71_layer_funcs = {
+   .validate   = d71_layer_validate,
.update = d71_layer_update,
.disable= d71_layer_disable,
.dump_register  = d71_layer_dump,
-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 1/2] drm/komeda: Add line size support

2019-08-30 Thread Lowry Li (Arm Technology China)
On D71, we are using the global line size. From D32, every
component have a line size register to indicate the fifo size.

So this patch is to set line size support and do the line size
check.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c| 56 ---
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h |  8 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  2 +
 .../display/komeda/komeda_pipeline_state.c| 17 ++
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index c985932954cb..a56dc56a72fb 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -116,6 +116,23 @@ static void dump_block_header(struct seq_file *sf, void 
__iomem *reg)
   i, hdr.output_ids[i]);
 }
 
+/* On D71, we are using the global line size. From D32, every component have
+ * a line size register to indicate the fifo size.
+ */
+static u32 __get_blk_line_size(struct d71_dev *d71, u32 __iomem *reg,
+  u32 max_default)
+{
+   if (!d71->periph_addr)
+   max_default = malidp_read32(reg, BLK_MAX_LINE_SIZE);
+
+   return max_default;
+}
+
+static u32 get_blk_line_size(struct d71_dev *d71, u32 __iomem *reg)
+{
+   return __get_blk_line_size(d71, reg, d71->max_line_size);
+}
+
 static u32 to_rot_ctrl(u32 rot)
 {
u32 lr_ctrl = 0;
@@ -423,7 +440,27 @@ static int d71_layer_init(struct d71_dev *d71,
layer->color_mgr.fgamma_mgr = d71->glb_lt_mgr;
}
 
-   set_range(>hsize_in, 4, d71->max_line_size);
+   if (!d71->periph_addr) {
+   /* D32 or newer product */
+   layer->line_sz = malidp_read32(reg, BLK_MAX_LINE_SIZE);
+   layer->yuv_line_sz = L_INFO_YUV_MAX_LINESZ(layer_info);
+   } else if (d71->max_line_size > 2048) {
+   /* D71 4K */
+   layer->line_sz = d71->max_line_size;
+   layer->yuv_line_sz = layer->line_sz / 2;
+   } else  {
+   /* D71 2K */
+   if (layer->layer_type == KOMEDA_FMT_RICH_LAYER) {
+   /* rich layer is 4K configuration */
+   layer->line_sz = d71->max_line_size * 2;
+   layer->yuv_line_sz = layer->line_sz / 2;
+   } else {
+   layer->line_sz = d71->max_line_size;
+   layer->yuv_line_sz = 0;
+   }
+   }
+
+   set_range(>hsize_in, 4, layer->line_sz);
set_range(>vsize_in, 4, d71->max_vsize);
 
malidp_write32(reg, LAYER_PALPHA, D71_PALPHA_DEF_MAP);
@@ -676,9 +713,11 @@ static int d71_wb_layer_init(struct d71_dev *d71,
 
wb_layer = to_layer(c);
wb_layer->layer_type = KOMEDA_FMT_WB_LAYER;
+   wb_layer->line_sz = get_blk_line_size(d71, reg);
+   wb_layer->yuv_line_sz = wb_layer->line_sz;
 
-   set_range(_layer->hsize_in, D71_MIN_LINE_SIZE, d71->max_line_size);
-   set_range(_layer->vsize_in, D71_MIN_VERTICAL_SIZE, d71->max_vsize);
+   set_range(_layer->hsize_in, 64, wb_layer->line_sz);
+   set_range(_layer->vsize_in, 64, d71->max_vsize);
 
return 0;
 }
@@ -822,8 +861,8 @@ static int d71_compiz_init(struct d71_dev *d71,
if (komeda_product_match(d71->mdev, MALIDP_D77_PRODUCT_ID))
compiz->support_channel_scaling = true;
 
-   set_range(>hsize, D71_MIN_LINE_SIZE, d71->max_line_size);
-   set_range(>vsize, D71_MIN_VERTICAL_SIZE, d71->max_vsize);
+   set_range(>hsize, 64, get_blk_line_size(d71, reg));
+   set_range(>vsize, 64, d71->max_vsize);
 
return 0;
 }
@@ -980,7 +1019,7 @@ static int d71_scaler_init(struct d71_dev *d71,
}
 
scaler = to_scaler(c);
-   set_range(>hsize, 4, 2048);
+   set_range(>hsize, 4, __get_blk_line_size(d71, reg, 2048));
set_range(>vsize, 4, 4096);
scaler->max_downscaling = 6;
scaler->max_upscaling = 64;
@@ -1089,7 +1128,7 @@ static int d71_splitter_init(struct d71_dev *d71,
 
splitter = to_splitter(c);
 
-   set_range(>hsize, 4, d71->max_line_size);
+   set_range(>hsize, 4, get_blk_line_size(d71, reg));
set_range(>vsize, 4, d71->max_vsize);
 
return 0;
@@ -1240,7 +1279,8 @@ static int d71_merger_init(struct d71_dev *d71,
 
merger = to_merger(c);
 
-   set_range(>hsize_merged, 4, 4032);
+   set_range(>hsize_merged, 4,
+ __get_blk_line_size(d71, reg, 4032));
set_range(>vsize_merged, 4, 4096);
 
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h 
b/drivers

[PATCH v1 0/2] drm/komeda: Add layer line size support

2019-08-30 Thread Lowry Li (Arm Technology China)
Hi,

From D32 every component have a line size register to indicate internal
fifo size, instead of using the global line_sz.

This serie aims at adding the layer line size support and check
accordingly on both D71 and D32 or newer.

Lowry Li (Arm Technology China) (2):
  drm/komeda: Add line size support
  drm/komeda: Adds layer horizontal input size limitation check for D71

 .../arm/display/komeda/d71/d71_component.c| 105 --
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h |   8 +-
 .../drm/arm/display/komeda/komeda_pipeline.h  |   2 +
 .../display/komeda/komeda_pipeline_state.c|  17 +++
 4 files changed, 117 insertions(+), 15 deletions(-)

-- 
2.17.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/komeda: SW workaround for D71 doesn't flush shadow registers

2019-09-06 Thread Lowry Li (Arm Technology China)
This is a SW workaround for shadow un-flushed when together with the
DOU Timing-disable.

D71 HW doesn't update shadow registers when display output is turned
off. So when we disable all pipeline components together with display
output disabling by one flush or one operation, the disable operation
updated registers will not be flushed or valid in HW, which may lead
problem. To workaround this problem, introduce a two phase disable for
pipeline disable.

Phase1: Disable components with display is on and flush it, this phase
for flushing or validating the shadow registers.
Phase2: Turn-off display output.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 16 
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 73 ---
 .../drm/arm/display/komeda/komeda_pipeline.h  | 14 +++-
 .../display/komeda/komeda_pipeline_state.c| 30 +++-
 4 files changed, 103 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 2151cb3f9e68..e74069ef3b7b 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -487,6 +487,22 @@ static int d71_enum_resources(struct komeda_dev *mdev)
err = PTR_ERR(pipe);
goto err_cleanup;
}
+
+   /* D71 HW doesn't update shadow registers when display output
+* is turning off, so when we disable all pipeline components
+* together with display output disable by one flush or one
+* operation, the disable operation updated registers will not
+* be flush to or valid in HW, which may leads problem.
+* To workaround this problem, introduce a two phase disable.
+* Phase1: Disabling components with display is on to make sure
+* the disable can be flushed to HW.
+* Phase2: Only turn-off display output.
+*/
+   value = KOMEDA_PIPELINE_IMPROCS |
+   BIT(KOMEDA_COMPONENT_TIMING_CTRLR);
+
+   pipe->standalone_disabled_comps = value;
+
d71->pipes[i] = to_d71_pipeline(pipe);
}
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 3155bb17ea1b..c0c803d56d5c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -280,20 +280,53 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,
komeda_crtc_do_flush(crtc, old);
 }
 
+static void
+komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
+struct completion *input_flip_done)
+{
+   struct drm_device *drm = kcrtc->base.dev;
+   struct komeda_dev *mdev = kcrtc->master->mdev;
+   struct completion *flip_done;
+   struct completion temp;
+   int timeout;
+
+   /* if caller doesn't send a flip_done, use a private flip_done */
+   if (input_flip_done) {
+   flip_done = input_flip_done;
+   } else {
+   init_completion();
+   kcrtc->disable_done = 
+   flip_done = 
+   }
+
+   mdev->funcs->flush(mdev, kcrtc->master->id, 0);
+
+   /* wait the flip take affect.*/
+   timeout = wait_for_completion_timeout(flip_done, HZ);
+   if (timeout == 0) {
+   DRM_ERROR("wait pipe%d flip done timeout\n", kcrtc->master->id);
+   if (!input_flip_done) {
+   unsigned long flags;
+
+   spin_lock_irqsave(>event_lock, flags);
+   kcrtc->disable_done = NULL;
+   spin_unlock_irqrestore(>event_lock, flags);
+   }
+   }
+}
+
 static void
 komeda_crtc_atomic_disable(struct drm_crtc *crtc,
   struct drm_crtc_state *old)
 {
struct komeda_crtc *kcrtc = to_kcrtc(crtc);
struct komeda_crtc_state *old_st = to_kcrtc_st(old);
-   struct komeda_dev *mdev = crtc->dev->dev_private;
struct komeda_pipeline *master = kcrtc->master;
struct komeda_pipeline *slave  = kcrtc->slave;
struct completion *disable_done = >state->commit->flip_done;
-   struct completion temp;
-   int timeout;
+   bool needs_phase2 = false;
 
-   DRM_DEBUG_ATOMIC("CRTC%d_DISABLE: active_pipes: 0x%x, affected: 
0x%x.\n",
+   DRM_DEBUG_ATOMIC("CRTC%d_DISABLE: active_pipes: 0x%x, affected: 0x%x\n",
 drm_crtc_index(crtc),
 old_st->active_pipes, old_st->affected_pipes);
 
@@ -301,7 +334,7 @@ komeda_crtc_atomic_disable(struct drm_crtc *crtc,

[PATCH] drm/komeda: Adds register dump support for gcu, lup and dou

2019-09-17 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds to support register dump on lpu and dou of pipeline and gcu on D71

Changes since v1:
- For a constant format without additional arguments, use seq_puts()
instead of seq_printf().

Signed-off-by: Lowry Li (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c| 86 ++-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 23 ++---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.h  |  2 +
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  2 +
 4 files changed, 101 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 4073a452e24a..7ba3c135142c 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1206,6 +1206,90 @@ int d71_probe_block(struct d71_dev *d71,
return err;
 }
 
+static void d71_gcu_dump(struct d71_dev *d71, struct seq_file *sf)
+{
+   u32 v[5];
+
+   seq_puts(sf, "\n-- GCU --\n");
+
+   get_values_from_reg(d71->gcu_addr, 0, 3, v);
+   seq_printf(sf, "GLB_ARCH_ID:\t\t0x%X\n", v[0]);
+   seq_printf(sf, "GLB_CORE_ID:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "GLB_CORE_INFO:\t\t0x%X\n", v[2]);
+
+   get_values_from_reg(d71->gcu_addr, 0x10, 1, v);
+   seq_printf(sf, "GLB_IRQ_STATUS:\t\t0x%X\n", v[0]);
+
+   get_values_from_reg(d71->gcu_addr, 0xA0, 5, v);
+   seq_printf(sf, "GCU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "GCU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "GCU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "GCU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "GCU_STATUS:\t\t0x%X\n", v[4]);
+
+   get_values_from_reg(d71->gcu_addr, 0xD0, 3, v);
+   seq_printf(sf, "GCU_CONTROL:\t\t0x%X\n", v[0]);
+   seq_printf(sf, "GCU_CONFIG_VALID0:\t0x%X\n", v[1]);
+   seq_printf(sf, "GCU_CONFIG_VALID1:\t0x%X\n", v[2]);
+}
+
+static void d71_lpu_dump(struct d71_pipeline *pipe, struct seq_file *sf)
+{
+   u32 v[6];
+
+   seq_printf(sf, "\n-- LPU%d --\n", pipe->base.id);
+
+   dump_block_header(sf, pipe->lpu_addr);
+
+   get_values_from_reg(pipe->lpu_addr, 0xA0, 6, v);
+   seq_printf(sf, "LPU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "LPU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "LPU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "LPU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "LPU_STATUS:\t\t0x%X\n", v[4]);
+   seq_printf(sf, "LPU_TBU_STATUS:\t\t0x%X\n", v[5]);
+
+   get_values_from_reg(pipe->lpu_addr, 0xC0, 1, v);
+   seq_printf(sf, "LPU_INFO:\t\t0x%X\n", v[0]);
+
+   get_values_from_reg(pipe->lpu_addr, 0xD0, 3, v);
+   seq_printf(sf, "LPU_RAXI_CONTROL:\t0x%X\n", v[0]);
+   seq_printf(sf, "LPU_WAXI_CONTROL:\t0x%X\n", v[1]);
+   seq_printf(sf, "LPU_TBU_CONTROL:\t0x%X\n", v[2]);
+}
+
+static void d71_dou_dump(struct d71_pipeline *pipe, struct seq_file *sf)
+{
+   u32 v[5];
+
+   seq_printf(sf, "\n-- DOU%d --\n", pipe->base.id);
+
+   dump_block_header(sf, pipe->dou_addr);
+
+   get_values_from_reg(pipe->dou_addr, 0xA0, 5, v);
+   seq_printf(sf, "DOU_IRQ_RAW_STATUS:\t0x%X\n", v[0]);
+   seq_printf(sf, "DOU_IRQ_CLEAR:\t\t0x%X\n", v[1]);
+   seq_printf(sf, "DOU_IRQ_MASK:\t\t0x%X\n", v[2]);
+   seq_printf(sf, "DOU_IRQ_STATUS:\t\t0x%X\n", v[3]);
+   seq_printf(sf, "DOU_STATUS:\t\t0x%X\n", v[4]);
+}
+
+static void d71_pipeline_dump(struct komeda_pipeline *pipe, struct seq_file 
*sf)
+{
+   struct d71_pipeline *d71_pipe = to_d71_pipeline(pipe);
+
+   d71_lpu_dump(d71_pipe, sf);
+   d71_dou_dump(d71_pipe, sf);
+}
+
 const struct komeda_pipeline_funcs d71_pipeline_funcs = {
-   .downscaling_clk_check = d71_downscaling_clk_check,
+   .downscaling_clk_check  = d71_downscaling_clk_check,
+   .dump_register  = d71_pipeline_dump,
 };
+
+void d71_dump(struct komeda_dev *mdev, struct seq_file *sf)
+{
+   struct d71_dev *d71 = mdev->chip_data;
+
+   d71_gcu_dump(d71, sf);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index d567ab7ed314..0b763ea543ac 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -561,17 +561,18 @@ static int d71_disconnect_iommu(struct komeda_dev *mdev)
 }
 
 static const struct komeda_dev_funcs d71_chip_funcs = {
-   .init_format_table = d71_init_fmt_tbl,
-   .enum

[PATCH v1 1/2] drm: Free the writeback_job when it with an empty fb

2019-07-31 Thread Lowry Li (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds the check if the writeback_job with an empty fb, then it should
be freed in atomic_check phase.

With this change, the driver users will not check empty fb case any more.
So refined accordingly.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c |  3 +--
 drivers/gpu/drm/arm/malidp_mw.c  |  4 ++--
 drivers/gpu/drm/drm_atomic.c | 13 +
 drivers/gpu/drm/rcar-du/rcar_du_writeback.c  |  4 ++--
 drivers/gpu/drm/vc4/vc4_txp.c|  5 ++---
 5 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 617e1f7..d6103dd 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -43,9 +43,8 @@
struct komeda_data_flow_cfg dflow;
int err;
 
-   if (!writeback_job || !writeback_job->fb) {
+   if (!writeback_job)
return 0;
-   }
 
if (!crtc_st->active) {
DRM_DEBUG_ATOMIC("Cannot write the composition result out on a 
inactive CRTC.\n");
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index 2e81252..a59227b 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -130,7 +130,7 @@ static void malidp_mw_connector_destroy(struct 
drm_connector *connector)
struct drm_framebuffer *fb;
int i, n_planes;
 
-   if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+   if (!conn_state->writeback_job)
return 0;
 
fb = conn_state->writeback_job->fb;
@@ -247,7 +247,7 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
 
mw_state = to_mw_state(conn_state);
 
-   if (conn_state->writeback_job && conn_state->writeback_job->fb) {
+   if (conn_state->writeback_job) {
struct drm_framebuffer *fb = conn_state->writeback_job->fb;
 
DRM_DEV_DEBUG_DRIVER(drm->dev,
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 419381a..14aeaf7 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -430,10 +430,15 @@ static int drm_atomic_connector_check(struct 
drm_connector *connector,
return -EINVAL;
}
 
-   if (writeback_job->out_fence && !writeback_job->fb) {
-   DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence 
without framebuffer\n",
-connector->base.id, connector->name);
-   return -EINVAL;
+   if (!writeback_job->fb) {
+   if (writeback_job->out_fence) {
+   DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting 
out-fence without framebuffer\n",
+connector->base.id, connector->name);
+   return -EINVAL;
+   }
+
+   drm_writeback_cleanup_job(writeback_job);
+   state->writeback_job = NULL;
}
 
return 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c 
b/drivers/gpu/drm/rcar-du/rcar_du_writeback.c
index ae07290..04efa78d 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_writeback.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_writeback.c
@@ -147,7 +147,7 @@ static int rcar_du_wb_enc_atomic_check(struct drm_encoder 
*encoder,
struct drm_device *dev = encoder->dev;
struct drm_framebuffer *fb;
 
-   if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+   if (!conn_state->writeback_job)
return 0;
 
fb = conn_state->writeback_job->fb;
@@ -221,7 +221,7 @@ void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
unsigned int i;
 
state = rcrtc->writeback.base.state;
-   if (!state || !state->writeback_job || !state->writeback_job->fb)
+   if (!state || !state->writeback_job)
return;
 
fb = state->writeback_job->fb;
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index 96f91c1..e92fa12 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -229,7 +229,7 @@ static int vc4_txp_connector_atomic_check(struct 
drm_connector *conn,
int i;
 
conn_state = drm_atomic_get_new_connector_state(state, conn);
-   if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+   if (!conn_state->writeback_job)
return 0;
 
crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
@@ -269,8 +269,7 @@ static void vc4_txp_connector_atomic_commit(s

[PATCH v1 2/2] drm: Clear the fence pointer when writeback job signaled

2019-07-31 Thread Lowry Li (Arm Technology China)
During it signals the completion of a writeback job, after releasing
the out_fence, we'd clear the pointer.

Check if fence left over in drm_writeback_cleanup_job(), release it.

Signed-off-by: Lowry Li (Arm Technology China) 
---
 drivers/gpu/drm/drm_writeback.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index ff138b6..43d9e3b 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -324,6 +324,9 @@ void drm_writeback_cleanup_job(struct drm_writeback_job 
*job)
if (job->fb)
drm_framebuffer_put(job->fb);
 
+   if (job->out_fence)
+   dma_fence_put(job->out_fence);
+
kfree(job);
 }
 EXPORT_SYMBOL(drm_writeback_cleanup_job);
@@ -366,25 +369,29 @@ static void cleanup_work(struct work_struct *work)
 {
unsigned long flags;
struct drm_writeback_job *job;
+   struct dma_fence *out_fence;
 
spin_lock_irqsave(_connector->job_lock, flags);
job = list_first_entry_or_null(_connector->job_queue,
   struct drm_writeback_job,
   list_entry);
-   if (job) {
+   if (job)
list_del(>list_entry);
-   if (job->out_fence) {
-   if (status)
-   dma_fence_set_error(job->out_fence, status);
-   dma_fence_signal(job->out_fence);
-   dma_fence_put(job->out_fence);
-   }
-   }
+
spin_unlock_irqrestore(_connector->job_lock, flags);
 
if (WARN_ON(!job))
return;
 
+   out_fence = job->out_fence;
+   if (out_fence) {
+   if (status)
+   dma_fence_set_error(out_fence, status);
+   dma_fence_signal(out_fence);
+   dma_fence_put(out_fence);
+   job->out_fence = NULL;
+   }
+
INIT_WORK(>cleanup_work, cleanup_work);
queue_work(system_long_wq, >cleanup_work);
 }
-- 
1.9.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v1 0/2] Free the writeback_job when it with an empty fb

2019-07-31 Thread Lowry Li (Arm Technology China)
Hi,

This serie aims at adding the check and free the writeback_job when it
with an empty fb in drm_atomic_connector_check().

Also did some refine in drm_writeback_signal_completion() to clear the
fence pointer when writeback job signaled.

This patchset is based at the drm-misc-fixes branch.

Lowry Li (Arm Technology China) (2):
  drm: Free the writeback_job when it with an empty fb
  drm: Clear the fence pointer when writeback job signaled

 .../drm/arm/display/komeda/komeda_wb_connector.c   |  3 +--
 drivers/gpu/drm/arm/malidp_mw.c|  4 ++--
 drivers/gpu/drm/drm_atomic.c   | 13 
 drivers/gpu/drm/drm_writeback.c| 23 ++
 drivers/gpu/drm/rcar-du/rcar_du_writeback.c|  4 ++--
 drivers/gpu/drm/vc4/vc4_txp.c  |  5 ++---
 6 files changed, 31 insertions(+), 21 deletions(-)

-- 
1.9.1



Re: [PATCH] drm/komeda: Skips the invalid writeback job

2019-07-31 Thread Lowry Li (Arm Technology China)
On Mon, Jul 29, 2019 at 06:11:25PM +0800, Lowry Li wrote:
> On Fri, Jul 26, 2019 at 06:15:46PM +0200, Daniel Vetter wrote:
> > On Fri, Jul 26, 2019 at 4:44 PM Brian Starkey  wrote:
> > >
> > > On Fri, Jul 26, 2019 at 04:23:56PM +0200, Daniel Vetter wrote:
> > > > On Fri, Jul 26, 2019 at 08:13:00AM +, Lowry Li (Arm Technology 
> > > > China) wrote:
> > > > > Current DRM-CORE accepts the writeback_job with a empty fb, but that
> > > > > is an invalid job for HW, so need to skip it when commit it to HW.
> > > > >
> > > > > Signed-off-by: Lowry Li (Arm Technology China) 
> > > >
> > > > Hm, this sounds a bit like an oversight in core writeback code? Not sure
> > > > how this can even happen, setting up a writeback job without an fb 
> > > > sounds
> > > > a bit like a bug to me at least ...
> > > >
> > > > If we don't have a good reason for why other hw needs to accept this, 
> > > > then
> > > > imo this needs to be rejected in shared code. For consistent behaviour
> > > > across all writeback supporting drivers.
> > > > -Daniel
> > >
> > > I think it's only this way to simplify the drm_writeback_set_fb()
> > > implementation in the case where the property is set more than once in
> > > the same commit (to something valid, and then 0).
> > >
> > > The core could indeed handle it - drm_writeback_set_fb() would check
> > > fb. If it's NULL and there's no writeback job, then it can just early
> > > return. If it's NULL and there's already a writeback job then it
> > > should drop the reference on the existing fb and free that job.
> > >
> > > Could lead to the job getting alloc/freed multiple times if userspace
> > > is insane, but meh.
> > 
> > Generally these consistency checks need to be in in the atomic_check
> > phase, not when we set properties. So either somewhere in the helpers,
> > or in drm_atomic_connector_check() if we want it in core, enforced for
> > everyone.
> > -Daniel
> 
> Thanks Daniel and Brian's comments. Agree with it to add the check in
> atomic_check phase. Will send an update patch.
> 
> -Lowry
The new patchset has been committed at:
https://patchwork.freedesktop.org/series/64493/
Thanks again for the comments and this patch will be droped.

Best regards,
Lowry
> > >
> > > -Brian
> > >
> > > >
> > > > > ---
> > > > >  drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 2 +-
> > > > >  drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 9 
> > > > > -
> > > > >  2 files changed, 9 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
> > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > > > > index 2fed1f6..372e99a 100644
> > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > > > > @@ -265,7 +265,7 @@ void komeda_crtc_handle_event(struct komeda_crtc 
> > > > > *kcrtc,
> > > > >  komeda_pipeline_update(slave, old->state);
> > > > >
> > > > >  conn_st = wb_conn ? wb_conn->base.base.state : NULL;
> > > > > -if (conn_st && conn_st->writeback_job)
> > > > > +if (conn_st && conn_st->writeback_job && conn_st->writeback_job->fb)
> > > > >  drm_writeback_queue_job(_conn->base, conn_st);
> > > > >
> > > > >  /* step 2: notify the HW to kickoff the update */
> > > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
> > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> > > > > index 9787745..8e2ef63 100644
> > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> > > > > @@ -52,9 +52,16 @@
> > > > >  struct komeda_data_flow_cfg dflow;
> > > > >  int err;
> > > > >
> > > > > -if (!writeback_job || !writeback_job->fb)
> > > > > +if (!writeback_job)
> > > > >  return 0;
> > > > >
> > > > > +if (!writeback_job->fb) {
> > > > > +if (writeback_job->out_fence)
> > > &g

Re: [PATCH v1 2/2] drm: Clear the fence pointer when writeback job signaled

2019-08-01 Thread Lowry Li (Arm Technology China)
Hi Liviu,

On Wed, Jul 31, 2019 at 01:15:25PM +, Liviu Dudau wrote:
> Hi Lowry,
> 
> On Wed, Jul 31, 2019 at 11:04:45AM +0000, Lowry Li (Arm Technology China) 
> wrote:
> > During it signals the completion of a writeback job, after releasing
> > the out_fence, we'd clear the pointer.
> > 
> > Check if fence left over in drm_writeback_cleanup_job(), release it.
> > 
> > Signed-off-by: Lowry Li (Arm Technology China) 
> > ---
> >  drivers/gpu/drm/drm_writeback.c | 23 +++
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_writeback.c 
> > b/drivers/gpu/drm/drm_writeback.c
> > index ff138b6..43d9e3b 100644
> > --- a/drivers/gpu/drm/drm_writeback.c
> > +++ b/drivers/gpu/drm/drm_writeback.c
> > @@ -324,6 +324,9 @@ void drm_writeback_cleanup_job(struct drm_writeback_job 
> > *job)
> > if (job->fb)
> > drm_framebuffer_put(job->fb);
> >  
> > +   if (job->out_fence)
> > +   dma_fence_put(job->out_fence);
> > +
> > kfree(job);
> >  }
> 
> This change looks good.
> 
> >  EXPORT_SYMBOL(drm_writeback_cleanup_job);
> > @@ -366,25 +369,29 @@ static void cleanup_work(struct work_struct *work)
> >  {
> > unsigned long flags;
> > struct drm_writeback_job *job;
> > +   struct dma_fence *out_fence;
> >  
> > spin_lock_irqsave(_connector->job_lock, flags);
> > job = list_first_entry_or_null(_connector->job_queue,
> >struct drm_writeback_job,
> >list_entry);
> > -   if (job) {
> > +   if (job)
> > list_del(>list_entry);
> > -   if (job->out_fence) {
> > -   if (status)
> > -   dma_fence_set_error(job->out_fence, status);
> > -   dma_fence_signal(job->out_fence);
> > -   dma_fence_put(job->out_fence);
> 
> *Here*
> 
> > -   }
> > -   }
> > +
> > spin_unlock_irqrestore(_connector->job_lock, flags);
> >  
> > if (WARN_ON(!job))
> > return;
> >  
> > +   out_fence = job->out_fence;
> > +   if (out_fence) {
> > +   if (status)
> > +   dma_fence_set_error(out_fence, status);
> > +   dma_fence_signal(out_fence);
> > +   dma_fence_put(out_fence);
> > +   job->out_fence = NULL;
> > +   }
> > +
> 
> I don't get the point of this change. Why not just add job->out_fence = NULL
> where *Here* is?
>
> Best regards,
> Liviu 
Besides setting NULL, also did a refine by moving the fence operation
out of the lock block.

Best regards,
Lowry 
> > INIT_WORK(>cleanup_work, cleanup_work);
> > queue_work(system_long_wq, >cleanup_work);
> >  }
> > -- 
> > 1.9.1
> > 
> 
> -- 
> 
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---
> ¯\_(ツ)_/¯

-- 
Regards,
Lowry
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  1   2   >