[PATCH v2] drm/imx: Add active plane reconfiguration support

Peter Senna Tschudin peter.senna at gmail.com
Mon Aug 15 13:37:29 UTC 2016


On Mon, Aug 15, 2016 at 10:41 AM, Liu Ying <gnuiyl at gmail.com> wrote:
> We don't support configuring active plane on-the-fly for imx-drm.
> The relevant CRTC should be disabled before the plane configuration.
> Of course, the plane itself should be disabled as well.
> This patch adds active plane reconfiguration support by forcing CRTC
> mode change and disabling-enabling plane in plane's ->atomic_update
> callback.

Solves the black screen issue I was facing.

>
> Suggested-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Philipp Zabel <p.zabel at pengutronix.de>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Peter Senna Tschudin <peter.senna at gmail.com>
> Signed-off-by: Liu Ying <gnuiyl at gmail.com>
Tested-by: Peter Senna Tschudin <peter.senna at gmail.com>

> ---
> v1->v2:
> * Do not reject reconfiguring an active overlay plane.
>
>  drivers/gpu/drm/imx/imx-drm-core.c | 26 +++++++++++++++++++++++++-
>  drivers/gpu/drm/imx/ipuv3-plane.c  | 21 ++++++++++++++-------
>  2 files changed, 39 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index 9f7dafc..7bf90e9 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -171,10 +171,34 @@ static void imx_drm_output_poll_changed(struct drm_device *drm)
>         drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
>  }
>
> +static int imx_drm_atomic_check(struct drm_device *dev,
> +                               struct drm_atomic_state *state)
> +{
> +       int ret;
> +
> +       ret = drm_atomic_helper_check_modeset(dev, state);
> +       if (ret)
> +               return ret;
> +
> +       ret = drm_atomic_helper_check_planes(dev, state);
> +       if (ret)
> +               return ret;
> +
> +       /*
> +        * Check modeset again in case crtc_state->mode_changed is
> +        * updated in plane's ->atomic_check callback.
> +        */
> +       ret = drm_atomic_helper_check_modeset(dev, state);
> +       if (ret)
> +               return ret;
> +
> +       return ret;
> +}
> +
>  static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
>         .fb_create = drm_fb_cma_create,
>         .output_poll_changed = imx_drm_output_poll_changed,
> -       .atomic_check = drm_atomic_helper_check,
> +       .atomic_check = imx_drm_atomic_check,
>         .atomic_commit = drm_atomic_helper_commit,
>  };
>
> diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
> index 4ad67d0..29423e75 100644
> --- a/drivers/gpu/drm/imx/ipuv3-plane.c
> +++ b/drivers/gpu/drm/imx/ipuv3-plane.c
> @@ -319,13 +319,14 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>                 return -EINVAL;
>
>         /*
> -        * since we cannot touch active IDMAC channels, we do not support
> -        * resizing the enabled plane or changing its format
> +        * We support resizing active plane or changing its format by
> +        * forcing CRTC mode change and disabling-enabling plane in plane's
> +        * ->atomic_update callback.
>          */
>         if (old_fb && (state->src_w != old_state->src_w ||
>                               state->src_h != old_state->src_h ||
>                               fb->pixel_format != old_fb->pixel_format))
> -               return -EINVAL;
> +               crtc_state->mode_changed = true;
>
>         eba = drm_plane_state_to_eba(state);
>
> @@ -336,7 +337,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>                 return -EINVAL;
>
>         if (old_fb && fb->pitches[0] != old_fb->pitches[0])
> -               return -EINVAL;
> +               crtc_state->mode_changed = true;
>
>         switch (fb->pixel_format) {
>         case DRM_FORMAT_YUV420:
> @@ -372,7 +373,7 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>                         return -EINVAL;
>
>                 if (old_fb && old_fb->pitches[1] != fb->pitches[1])
> -                       return -EINVAL;
> +                       crtc_state->mode_changed = true;
>         }
>
>         return 0;
> @@ -392,8 +393,14 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
>         enum ipu_color_space ics;
>
>         if (old_state->fb) {
> -               ipu_plane_atomic_set_base(ipu_plane, old_state);
> -               return;
> +               struct drm_crtc_state *crtc_state = state->crtc->state;
> +
> +               if (!crtc_state->mode_changed) {
> +                       ipu_plane_atomic_set_base(ipu_plane, old_state);
> +                       return;
> +               }
> +
> +               ipu_disable_plane(plane);
>         }
>
>         switch (ipu_plane->dp_flow) {
> --
> 2.7.4
>



-- 
Peter


More information about the dri-devel mailing list