Re: [RFC 3/3] drm/omap: Add wide display support using multiple overlays

2018-08-02 Thread Tomi Valkeinen
Hi Benoit,

On 29/06/18 20:02, Benoit Parrot wrote:
> In the case where we need to support wide-display using more than one
> overlay to achieve the needed display resolution, we need to be able to
> dynamically assign overlays to planes instead of having the overlays
> being statically mapped to planes.
> 
> This also means that on occasion where the number of requested planes
> exceeds the numbers of overlays required to display them then a failure
> would be returned for the plane that cannot be handled at that time. It
> is up to user space to make sure the H/W resource are not
> over-subscribed.

This is not a trivial patch, I think it needs much more explanation in
the desc on how the patch solves this issue and what it changes.

I have some small comments below here and there, but overall, I feel
it's rather difficult to review, and I really think this should be split
into multiple smaller patches. Some ideas on the patches it might be
split to:

- add plane state
- add global state
- add code which manages plane-id -> hw plane id
- add dual plane support

> Signed-off-by: Benoit Parrot 
> ---
>  drivers/gpu/drm/omapdrm/Makefile   |   1 +
>  drivers/gpu/drm/omapdrm/omap_drv.c | 119 ++-
>  drivers/gpu/drm/omapdrm/omap_drv.h |  15 +-
>  drivers/gpu/drm/omapdrm/omap_fb.c  |  33 ++-
>  drivers/gpu/drm/omapdrm/omap_fb.h  |   4 +-
>  drivers/gpu/drm/omapdrm/omap_overlay.c | 366 
> +
>  drivers/gpu/drm/omapdrm/omap_overlay.h |  80 +++
>  drivers/gpu/drm/omapdrm/omap_plane.c   | 322 -
>  drivers/gpu/drm/omapdrm/omap_plane.h   |  20 ++
>  9 files changed, 892 insertions(+), 68 deletions(-)
>  create mode 100644 drivers/gpu/drm/omapdrm/omap_overlay.c
>  create mode 100644 drivers/gpu/drm/omapdrm/omap_overlay.h
> 
> diff --git a/drivers/gpu/drm/omapdrm/Makefile 
> b/drivers/gpu/drm/omapdrm/Makefile
> index f115253115c5..800dfd035360 100644
> --- a/drivers/gpu/drm/omapdrm/Makefile
> +++ b/drivers/gpu/drm/omapdrm/Makefile
> @@ -12,6 +12,7 @@ omapdrm-y := omap_drv.o \
>   omap_debugfs.o \
>   omap_crtc.o \
>   omap_plane.o \
> + omap_overlay.o \
>   omap_encoder.o \
>   omap_connector.o \
>   omap_fb.o \
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
> b/drivers/gpu/drm/omapdrm/omap_drv.c
> index ef3b0e3571ec..f0a5c3dab471 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -16,11 +16,7 @@
>   */
>  
>  #include 
> -
> -#include 
> -#include 
> -#include 
> -#include 
> +#include 
>  
>  #include "omap_dmm_tiler.h"
>  #include "omap_drv.h"
> @@ -113,9 +109,100 @@ static void omap_atomic_commit_tail(struct 
> drm_atomic_state *old_state)
>  
>   drm_atomic_helper_cleanup_planes(dev, old_state);
>  
> + omap_overlay_disable_unassigned(old_state);
> +
>   priv->dispc_ops->runtime_put(priv->dispc);
>  }
>  
> +static int drm_atomic_state_normalized_zpos_cmp(const void *a, const void *b)
> +{
> + const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
> + const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
> +
> + if (sa->normalized_zpos != sb->normalized_zpos)
> + return sa->normalized_zpos - sb->normalized_zpos;
> + else
> + return sa->plane->base.id - sb->plane->base.id;
> +}
> +
> +static int omap_atomic_update_normalize_zpos(struct drm_device *dev,
> +  struct drm_atomic_state *state)
> +{
> + struct drm_crtc *crtc;
> + struct drm_crtc_state *old_state, *new_state;
> + struct drm_plane *plane;
> + int i, n, inc;
> + int total_planes = dev->mode_config.num_total_plane;
> + struct drm_plane_state **states;
> + int ret = 0;
> +
> + states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
> + if (!states)
> + return -ENOMEM;
> +
> + for_each_oldnew_crtc_in_state(state, crtc, old_state, new_state, i) {
> + if (old_state->plane_mask == new_state->plane_mask &&
> + !new_state->zpos_changed)
> + continue;
> +
> + /* Reset plane increment and index value for every crtc */
> + n = 0;
> +
> + /*
> +  * Normalization process might create new states for planes
> +  * which normalized_zpos has to be recalculated.
> +  */
> + drm_for_each_plane_mask(plane, dev, new_state->plane_mask) {
> + struct drm_plane_state *plane_state =
> + drm_atomic_get_plane_state(new_state->state,
> +plane);
> + if (IS_ERR(plane_state)) {
> + ret = PTR_ERR(plane_state);
> + goto done;
> + }
> + states[n++] = plane_state;
> + }
> +
> + sort(

[RFC 3/3] drm/omap: Add wide display support using multiple overlays

2018-06-29 Thread Benoit Parrot
In the case where we need to support wide-display using more than one
overlay to achieve the needed display resolution, we need to be able to
dynamically assign overlays to planes instead of having the overlays
being statically mapped to planes.

This also means that on occasion where the number of requested planes
exceeds the numbers of overlays required to display them then a failure
would be returned for the plane that cannot be handled at that time. It
is up to user space to make sure the H/W resource are not
over-subscribed.

Signed-off-by: Benoit Parrot 
---
 drivers/gpu/drm/omapdrm/Makefile   |   1 +
 drivers/gpu/drm/omapdrm/omap_drv.c | 119 ++-
 drivers/gpu/drm/omapdrm/omap_drv.h |  15 +-
 drivers/gpu/drm/omapdrm/omap_fb.c  |  33 ++-
 drivers/gpu/drm/omapdrm/omap_fb.h  |   4 +-
 drivers/gpu/drm/omapdrm/omap_overlay.c | 366 +
 drivers/gpu/drm/omapdrm/omap_overlay.h |  80 +++
 drivers/gpu/drm/omapdrm/omap_plane.c   | 322 -
 drivers/gpu/drm/omapdrm/omap_plane.h   |  20 ++
 9 files changed, 892 insertions(+), 68 deletions(-)
 create mode 100644 drivers/gpu/drm/omapdrm/omap_overlay.c
 create mode 100644 drivers/gpu/drm/omapdrm/omap_overlay.h

diff --git a/drivers/gpu/drm/omapdrm/Makefile b/drivers/gpu/drm/omapdrm/Makefile
index f115253115c5..800dfd035360 100644
--- a/drivers/gpu/drm/omapdrm/Makefile
+++ b/drivers/gpu/drm/omapdrm/Makefile
@@ -12,6 +12,7 @@ omapdrm-y := omap_drv.o \
omap_debugfs.o \
omap_crtc.o \
omap_plane.o \
+   omap_overlay.o \
omap_encoder.o \
omap_connector.o \
omap_fb.o \
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index ef3b0e3571ec..f0a5c3dab471 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -16,11 +16,7 @@
  */
 
 #include 
-
-#include 
-#include 
-#include 
-#include 
+#include 
 
 #include "omap_dmm_tiler.h"
 #include "omap_drv.h"
@@ -113,9 +109,100 @@ static void omap_atomic_commit_tail(struct 
drm_atomic_state *old_state)
 
drm_atomic_helper_cleanup_planes(dev, old_state);
 
+   omap_overlay_disable_unassigned(old_state);
+
priv->dispc_ops->runtime_put(priv->dispc);
 }
 
+static int drm_atomic_state_normalized_zpos_cmp(const void *a, const void *b)
+{
+   const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
+   const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
+
+   if (sa->normalized_zpos != sb->normalized_zpos)
+   return sa->normalized_zpos - sb->normalized_zpos;
+   else
+   return sa->plane->base.id - sb->plane->base.id;
+}
+
+static int omap_atomic_update_normalize_zpos(struct drm_device *dev,
+struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *old_state, *new_state;
+   struct drm_plane *plane;
+   int i, n, inc;
+   int total_planes = dev->mode_config.num_total_plane;
+   struct drm_plane_state **states;
+   int ret = 0;
+
+   states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL);
+   if (!states)
+   return -ENOMEM;
+
+   for_each_oldnew_crtc_in_state(state, crtc, old_state, new_state, i) {
+   if (old_state->plane_mask == new_state->plane_mask &&
+   !new_state->zpos_changed)
+   continue;
+
+   /* Reset plane increment and index value for every crtc */
+   n = 0;
+
+   /*
+* Normalization process might create new states for planes
+* which normalized_zpos has to be recalculated.
+*/
+   drm_for_each_plane_mask(plane, dev, new_state->plane_mask) {
+   struct drm_plane_state *plane_state =
+   drm_atomic_get_plane_state(new_state->state,
+  plane);
+   if (IS_ERR(plane_state)) {
+   ret = PTR_ERR(plane_state);
+   goto done;
+   }
+   states[n++] = plane_state;
+   }
+
+   sort(states, n, sizeof(*states),
+drm_atomic_state_normalized_zpos_cmp, NULL);
+
+   for (i = 0, inc = 0; i < n; i++) {
+   plane = states[i]->plane;
+
+   states[i]->normalized_zpos = i + inc;
+   DRM_DEBUG_ATOMIC("[PLANE:%d:%s] updated normalized zpos 
value %d\n",
+plane->base.id, plane->name,
+states[i]->normalized_zpos);
+
+   if (is_omap_plane_dual_overlay(states[i]))
+   inc++;
+   }
+   new_state->zpos_changed =