Re: [PATCH v3 09/10] drm: rcar-du: Perform group setup from the atomic tail handler

2019-06-18 Thread Ulrich Hecht


> On June 17, 2019 at 11:09 PM Laurent Pinchart 
>  wrote:
> 
> 
> From: Kieran Bingham 
> 
> Create rcar_du_group_atomic_check() and rcar_du_group_atomic_setup()
> functions to track and apply group state through the DRM atomic state.
> The use_count field is moved from the rcar_du_group structure to an
> enabled field in the rcar_du_group_state structure.
> 
> This allows separating group setup from the configuration of the CRTCs
> that are part of the group, simplifying the CRTC code and improving
> overall readability. The existing rcar_du_group_{get,put}() functions
> are now redundant and removed.
> 
> The groups share clocking with the CRTCs within the group, and so are
> accessible only when one of its CRTCs has been powered through
> rcar_du_crtc_atomic_exit_standby().
> 
> Signed-off-by: Kieran Bingham 
> Signed-off-by: Laurent Pinchart 
> ---
> Changes since v2:
> 
> - Simplify error handling in rcar_du_crtc_enable()
> - Rename rcar_du_group_atomic_pre_commit() to
>   rcar_du_group_atomic_setup() and turn it into a void function
> - Remove rcar_du_group_atomic_post_commit()
> - Replace group state use_count field by enabled
> - Rename group state variable from rstate to gstate
> 
> Changes since v1:
> 
> - All register sequences now maintained.
> - Clock management is no longer handled by the group
>   (_crtc_{exit,enter}_standby handles this for us)
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 18 ++---
>  drivers/gpu/drm/rcar-du/rcar_du_group.c | 91 -
>  drivers/gpu/drm/rcar-du/rcar_du_group.h | 12 ++--
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  5 ++
>  4 files changed, 76 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index d11a474f6f72..ab5c288f9d09 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -487,12 +487,10 @@ static int rcar_du_crtc_exit_standby(struct 
> rcar_du_crtc *rcrtc)
>   return ret;
>  
>   ret = clk_prepare_enable(rcrtc->extclock);
> - if (ret < 0)
> - goto error_clock;
> -
> - ret = rcar_du_group_get(rcrtc->group);
> - if (ret < 0)
> - goto error_group;
> + if (ret < 0) {
> + clk_disable_unprepare(rcrtc->clock);
> + return ret;
> + }
>  
>   /* Set display off and background to black. */
>   rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
> @@ -502,18 +500,10 @@ static int rcar_du_crtc_exit_standby(struct 
> rcar_du_crtc *rcrtc)
>   rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
>  
>   return 0;
> -
> -error_group:
> - clk_disable_unprepare(rcrtc->extclock);
> -error_clock:
> - clk_disable_unprepare(rcrtc->clock);
> - return ret;
>  }
>  
>  static void rcar_du_crtc_enter_standby(struct rcar_du_crtc *rcrtc)
>  {
> - rcar_du_group_put(rcrtc->group);
> -
>   clk_disable_unprepare(rcrtc->extclock);
>   clk_disable_unprepare(rcrtc->clock);
>  }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> index 8e12bd42890e..7c9145778567 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
> @@ -24,6 +24,7 @@
>   */
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -173,38 +174,6 @@ static void rcar_du_group_setup(struct rcar_du_group 
> *rgrp)
>   mutex_unlock(>lock);
>  }
>  
> -/*
> - * rcar_du_group_get - Acquire a reference to the DU channels group
> - *
> - * Acquiring the first reference setups core registers. A reference must be 
> held
> - * before accessing any hardware registers.
> - *
> - * This function must be called with the DRM mode_config lock held.
> - *
> - * Return 0 in case of success or a negative error code otherwise.
> - */
> -int rcar_du_group_get(struct rcar_du_group *rgrp)
> -{
> - if (rgrp->use_count)
> - goto done;
> -
> - rcar_du_group_setup(rgrp);
> -
> -done:
> - rgrp->use_count++;
> - return 0;
> -}
> -
> -/*
> - * rcar_du_group_put - Release a reference to the DU
> - *
> - * This function must be called with the DRM mode_config lock held.
> - */
> -void rcar_du_group_put(struct rcar_du_group *rgrp)
> -{
> - --rgrp->use_count;
> -}
> -
>  static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool 
> start)
>  {
>   struct rcar_du_device *rcdu = rgrp->dev;
> @@ -389,6 +358,23 @@ static const struct drm_private_state_funcs 
> rcar_du_group_state_funcs = {
>   .atomic_destroy_state = rcar_du_group_atomic_destroy_state,
>  };
>  
> +#define for_each_oldnew_group_in_state(__state, __obj, __old_state, 
> __new_state, __i) \
> + for_each_oldnew_private_obj_in_state((__state), (__obj), (__old_state), 
> (__new_state), (__i)) \
> + for_each_if((__obj)->funcs == _du_group_state_funcs)
> +
> +static struct rcar_du_group_state *
> 

[PATCH v3 09/10] drm: rcar-du: Perform group setup from the atomic tail handler

2019-06-17 Thread Laurent Pinchart
From: Kieran Bingham 

Create rcar_du_group_atomic_check() and rcar_du_group_atomic_setup()
functions to track and apply group state through the DRM atomic state.
The use_count field is moved from the rcar_du_group structure to an
enabled field in the rcar_du_group_state structure.

This allows separating group setup from the configuration of the CRTCs
that are part of the group, simplifying the CRTC code and improving
overall readability. The existing rcar_du_group_{get,put}() functions
are now redundant and removed.

The groups share clocking with the CRTCs within the group, and so are
accessible only when one of its CRTCs has been powered through
rcar_du_crtc_atomic_exit_standby().

Signed-off-by: Kieran Bingham 
Signed-off-by: Laurent Pinchart 
---
Changes since v2:

- Simplify error handling in rcar_du_crtc_enable()
- Rename rcar_du_group_atomic_pre_commit() to
  rcar_du_group_atomic_setup() and turn it into a void function
- Remove rcar_du_group_atomic_post_commit()
- Replace group state use_count field by enabled
- Rename group state variable from rstate to gstate

Changes since v1:

- All register sequences now maintained.
- Clock management is no longer handled by the group
  (_crtc_{exit,enter}_standby handles this for us)
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c  | 18 ++---
 drivers/gpu/drm/rcar-du/rcar_du_group.c | 91 -
 drivers/gpu/drm/rcar-du/rcar_du_group.h | 12 ++--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  5 ++
 4 files changed, 76 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index d11a474f6f72..ab5c288f9d09 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -487,12 +487,10 @@ static int rcar_du_crtc_exit_standby(struct rcar_du_crtc 
*rcrtc)
return ret;
 
ret = clk_prepare_enable(rcrtc->extclock);
-   if (ret < 0)
-   goto error_clock;
-
-   ret = rcar_du_group_get(rcrtc->group);
-   if (ret < 0)
-   goto error_group;
+   if (ret < 0) {
+   clk_disable_unprepare(rcrtc->clock);
+   return ret;
+   }
 
/* Set display off and background to black. */
rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0));
@@ -502,18 +500,10 @@ static int rcar_du_crtc_exit_standby(struct rcar_du_crtc 
*rcrtc)
rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, 0);
 
return 0;
-
-error_group:
-   clk_disable_unprepare(rcrtc->extclock);
-error_clock:
-   clk_disable_unprepare(rcrtc->clock);
-   return ret;
 }
 
 static void rcar_du_crtc_enter_standby(struct rcar_du_crtc *rcrtc)
 {
-   rcar_du_group_put(rcrtc->group);
-
clk_disable_unprepare(rcrtc->extclock);
clk_disable_unprepare(rcrtc->clock);
 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c 
b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 8e12bd42890e..7c9145778567 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -24,6 +24,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -173,38 +174,6 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
mutex_unlock(>lock);
 }
 
-/*
- * rcar_du_group_get - Acquire a reference to the DU channels group
- *
- * Acquiring the first reference setups core registers. A reference must be 
held
- * before accessing any hardware registers.
- *
- * This function must be called with the DRM mode_config lock held.
- *
- * Return 0 in case of success or a negative error code otherwise.
- */
-int rcar_du_group_get(struct rcar_du_group *rgrp)
-{
-   if (rgrp->use_count)
-   goto done;
-
-   rcar_du_group_setup(rgrp);
-
-done:
-   rgrp->use_count++;
-   return 0;
-}
-
-/*
- * rcar_du_group_put - Release a reference to the DU
- *
- * This function must be called with the DRM mode_config lock held.
- */
-void rcar_du_group_put(struct rcar_du_group *rgrp)
-{
-   --rgrp->use_count;
-}
-
 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
 {
struct rcar_du_device *rcdu = rgrp->dev;
@@ -389,6 +358,23 @@ static const struct drm_private_state_funcs 
rcar_du_group_state_funcs = {
.atomic_destroy_state = rcar_du_group_atomic_destroy_state,
 };
 
+#define for_each_oldnew_group_in_state(__state, __obj, __old_state, 
__new_state, __i) \
+   for_each_oldnew_private_obj_in_state((__state), (__obj), (__old_state), 
(__new_state), (__i)) \
+   for_each_if((__obj)->funcs == _du_group_state_funcs)
+
+static struct rcar_du_group_state *
+rcar_du_get_group_state(struct drm_atomic_state *state,
+   struct rcar_du_group *rgrp)
+{
+   struct drm_private_state *pstate;
+
+   pstate = drm_atomic_get_private_obj_state(state, >private);
+   if (IS_ERR(pstate))
+   return ERR_CAST(pstate);
+
+   return