diff mbox

[v3,1/3] drm/atomic: Save flip flags in drm_crtct_state

Message ID 1485656811-4211-2-git-send-email-Andrey.Grodzovsky@amd.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andrey Grodzovsky Jan. 29, 2017, 2:26 a.m. UTC
Allows using atomic flip helpers for drivers
using ASYNC flip.
Remove ASYNC_FLIP restriction in helpers and
caches the page flip flags in drm_crtc_state
to be used in the low level drivers.

v2:
Resending the patch since the original was broken.

v3:
Save flag in crtc_state instead of plane_state

Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 19 +++++--------------
 include/drm/drm_crtc.h              |  8 +++++++-
 include/drm/drm_plane.h             |  1 +
 3 files changed, 13 insertions(+), 15 deletions(-)

Comments

Laurent Pinchart Jan. 30, 2017, 11:05 a.m. UTC | #1
Hi Andrey,

Thank you for the patch.

On Saturday 28 Jan 2017 21:26:49 Andrey Grodzovsky wrote:
> Allows using atomic flip helpers for drivers
> using ASYNC flip.
> Remove ASYNC_FLIP restriction in helpers and
> caches the page flip flags in drm_crtc_state
> to be used in the low level drivers.
> 
> v2:
> Resending the patch since the original was broken.
> 
> v3:
> Save flag in crtc_state instead of plane_state
> 
> Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c | 19 +++++--------------
>  include/drm/drm_crtc.h              |  8 +++++++-
>  include/drm/drm_plane.h             |  1 +
>  3 files changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> b/drivers/gpu/drm/drm_atomic_helper.c index a4e5477..28065ee 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2737,7 +2737,8 @@ static int page_flip_common(
>  				struct drm_atomic_state *state,
>  				struct drm_crtc *crtc,
>  				struct drm_framebuffer *fb,
> -				struct drm_pending_vblank_event *event)
> +				struct drm_pending_vblank_event *event,
> +				uint32_t flags)
>  {
>  	struct drm_plane *plane = crtc->primary;
>  	struct drm_plane_state *plane_state;
> @@ -2749,12 +2750,12 @@ static int page_flip_common(
>  		return PTR_ERR(crtc_state);
> 
>  	crtc_state->event = event;
> +	crtc_state->pflip_flags = flags;
> 
>  	plane_state = drm_atomic_get_plane_state(state, plane);
>  	if (IS_ERR(plane_state))
>  		return PTR_ERR(plane_state);
> 
> -
>  	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
>  	if (ret != 0)
>  		return ret;
> @@ -2781,10 +2782,6 @@ static int page_flip_common(
>   * Provides a default &drm_crtc_funcs.page_flip implementation
>   * using the atomic driver interface.
>   *
> - * Note that for now so called async page flips (i.e. updates which are not
> - * synchronized to vblank) are not supported, since the atomic interfaces
> have - * no provisions for this yet.
> - *
>   * Returns:
>   * Returns 0 on success, negative errno numbers on failure.
>   *
> @@ -2800,9 +2797,6 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
> struct drm_atomic_state *state;
>  	int ret = 0;
> 
> -	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
> -		return -EINVAL;
> -
>  	state = drm_atomic_state_alloc(plane->dev);
>  	if (!state)
>  		return -ENOMEM;
> @@ -2810,7 +2804,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
> state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
> 
>  retry:
> -	ret = page_flip_common(state, crtc, fb, event);
> +	ret = page_flip_common(state, crtc, fb, event, flags);
>  	if (ret != 0)
>  		goto fail;
> 
> @@ -2865,9 +2859,6 @@ int drm_atomic_helper_page_flip_target(
>  	struct drm_crtc_state *crtc_state;
>  	int ret = 0;
> 
> -	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
> -		return -EINVAL;
> -
>  	state = drm_atomic_state_alloc(plane->dev);
>  	if (!state)
>  		return -ENOMEM;
> @@ -2875,7 +2866,7 @@ int drm_atomic_helper_page_flip_target(
>  	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
> 
>  retry:
> -	ret = page_flip_common(state, crtc, fb, event);
> +	ret = page_flip_common(state, crtc, fb, event, flags);
>  	if (ret != 0)
>  		goto fail;
> 
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 5c77c3f..76457a4 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -162,10 +162,16 @@ struct drm_crtc_state {
>  	 * Target vertical blank period when a page flip
>  	 * should take effect.
>  	 */
> -
>  	u32 target_vblank;
> 
>  	/**
> +	 * @pflip_flags:
> +	 *
> +	 * Flip related config options

This isn't detailed enough. I propose something along the lines of

"DRM_MODE_PAGE_FLIP_* page flip flags, as passed to the page flip ioctl. 
Always zero for atomic commits that don't originate from a page flip ioctl."

You will then also need to reset the field to 0 at an appropriate point, as 
it's more an atomic commit transaction information than a state. Apart from 
that this patch looks good to me.

> +	 */
> +	u32 pflip_flags;
> +
> +	/**
>  	 * @event:
>  	 *
>  	 * Optional pointer to a DRM event to signal upon completion of the
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index db3bbde..57414ae 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -122,6 +122,7 @@ struct drm_plane_state {
>  	 */
>  	bool visible;
> 
>  	struct drm_atomic_state *state;
>  };
Andrey Grodzovsky Jan. 30, 2017, 7:42 p.m. UTC | #2
> -----Original Message-----
> From: Laurent Pinchart [mailto:laurent.pinchart@ideasonboard.com]
> Sent: Monday, January 30, 2017 6:05 AM
> To: Grodzovsky, Andrey
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org;
> nouveau@lists.freedesktop.org; daniel.vetter@intel.com; dc_upstream
> Subject: Re: [v3 PATCH 1/3] drm/atomic: Save flip flags in drm_crtct_state
> 
> Hi Andrey,
> 
> Thank you for the patch.
> 
> On Saturday 28 Jan 2017 21:26:49 Andrey Grodzovsky wrote:
> > Allows using atomic flip helpers for drivers using ASYNC flip.
> > Remove ASYNC_FLIP restriction in helpers and caches the page flip
> > flags in drm_crtc_state to be used in the low level drivers.
> >
> > v2:
> > Resending the patch since the original was broken.
> >
> > v3:
> > Save flag in crtc_state instead of plane_state
> >
> > Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c | 19 +++++--------------
> >  include/drm/drm_crtc.h              |  8 +++++++-
> >  include/drm/drm_plane.h             |  1 +
> >  3 files changed, 13 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> > b/drivers/gpu/drm/drm_atomic_helper.c index a4e5477..28065ee 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -2737,7 +2737,8 @@ static int page_flip_common(
> >  				struct drm_atomic_state *state,
> >  				struct drm_crtc *crtc,
> >  				struct drm_framebuffer *fb,
> > -				struct drm_pending_vblank_event *event)
> > +				struct drm_pending_vblank_event *event,
> > +				uint32_t flags)
> >  {
> >  	struct drm_plane *plane = crtc->primary;
> >  	struct drm_plane_state *plane_state; @@ -2749,12 +2750,12 @@
> static
> > int page_flip_common(
> >  		return PTR_ERR(crtc_state);
> >
> >  	crtc_state->event = event;
> > +	crtc_state->pflip_flags = flags;
> >
> >  	plane_state = drm_atomic_get_plane_state(state, plane);
> >  	if (IS_ERR(plane_state))
> >  		return PTR_ERR(plane_state);
> >
> > -
> >  	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
> >  	if (ret != 0)
> >  		return ret;
> > @@ -2781,10 +2782,6 @@ static int page_flip_common(
> >   * Provides a default &drm_crtc_funcs.page_flip implementation
> >   * using the atomic driver interface.
> >   *
> > - * Note that for now so called async page flips (i.e. updates which
> > are not
> > - * synchronized to vblank) are not supported, since the atomic
> > interfaces have - * no provisions for this yet.
> > - *
> >   * Returns:
> >   * Returns 0 on success, negative errno numbers on failure.
> >   *
> > @@ -2800,9 +2797,6 @@ int drm_atomic_helper_page_flip(struct drm_crtc
> > *crtc, struct drm_atomic_state *state;
> >  	int ret = 0;
> >
> > -	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
> > -		return -EINVAL;
> > -
> >  	state = drm_atomic_state_alloc(plane->dev);
> >  	if (!state)
> >  		return -ENOMEM;
> > @@ -2810,7 +2804,7 @@ int drm_atomic_helper_page_flip(struct drm_crtc
> > *crtc,
> > state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
> >
> >  retry:
> > -	ret = page_flip_common(state, crtc, fb, event);
> > +	ret = page_flip_common(state, crtc, fb, event, flags);
> >  	if (ret != 0)
> >  		goto fail;
> >
> > @@ -2865,9 +2859,6 @@ int drm_atomic_helper_page_flip_target(
> >  	struct drm_crtc_state *crtc_state;
> >  	int ret = 0;
> >
> > -	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
> > -		return -EINVAL;
> > -
> >  	state = drm_atomic_state_alloc(plane->dev);
> >  	if (!state)
> >  		return -ENOMEM;
> > @@ -2875,7 +2866,7 @@ int drm_atomic_helper_page_flip_target(
> >  	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
> >
> >  retry:
> > -	ret = page_flip_common(state, crtc, fb, event);
> > +	ret = page_flip_common(state, crtc, fb, event, flags);
> >  	if (ret != 0)
> >  		goto fail;
> >
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index
> > 5c77c3f..76457a4 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -162,10 +162,16 @@ struct drm_crtc_state {
> >  	 * Target vertical blank period when a page flip
> >  	 * should take effect.
> >  	 */
> > -
> >  	u32 target_vblank;
> >
> >  	/**
> > +	 * @pflip_flags:
> > +	 *
> > +	 * Flip related config options
> 
> This isn't detailed enough. I propose something along the lines of
> 
> "DRM_MODE_PAGE_FLIP_* page flip flags, as passed to the page flip ioctl.
> Always zero for atomic commits that don't originate from a page flip ioctl."
> 
> You will then also need to reset the field to 0 at an appropriate point, as it's
> more an atomic commit transaction information than a state. Apart from that
> this patch looks good to me.
Thanks for your comments, i am not sure I understand why the reset is needed, 
for any future commit on same crtc the new state will have the field empty and 
if it's a flip IOCTL the field will be filled as needed in page_flip_common, otherwise it 
will stay empty. If the last commit on that crtc was a flip then why not keep this field 
with the bits that the user mode set ?
Thanks,
[Grodzovsky, Andrey] 
> 
> > +	 */
> > +	u32 pflip_flags;
> > +
> > +	/**
> >  	 * @event:
> >  	 *
> >  	 * Optional pointer to a DRM event to signal upon completion of the
> > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index
> > db3bbde..57414ae 100644
> > --- a/include/drm/drm_plane.h
> > +++ b/include/drm/drm_plane.h
> > @@ -122,6 +122,7 @@ struct drm_plane_state {
> >  	 */
> >  	bool visible;
> >
> >  	struct drm_atomic_state *state;
> >  };
> 
> --
> Regards,
> 
> Laurent Pinchart
Laurent Pinchart Feb. 1, 2017, 10:17 a.m. UTC | #3
Hi Andrey,

(by the way there's a typo in the subject)

On Monday 30 Jan 2017 19:42:23 Grodzovsky, Andrey wrote:
> On Monday, January 30, 2017 6:05 AM Laurent Pinchart wrote:
> > On Saturday 28 Jan 2017 21:26:49 Andrey Grodzovsky wrote:
> >> Allows using atomic flip helpers for drivers using ASYNC flip.
> >> Remove ASYNC_FLIP restriction in helpers and caches the page flip
> >> flags in drm_crtc_state to be used in the low level drivers.
> >> 
> >> v2:
> >> Resending the patch since the original was broken.
> >> 
> >> v3:
> >> Save flag in crtc_state instead of plane_state
> >> 
> >> Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com>
> >> ---
> >> 
> >>  drivers/gpu/drm/drm_atomic_helper.c | 19 +++++--------------
> >>  include/drm/drm_crtc.h              |  8 +++++++-
> >>  include/drm/drm_plane.h             |  1 +
> >>  3 files changed, 13 insertions(+), 15 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> >> b/drivers/gpu/drm/drm_atomic_helper.c index a4e5477..28065ee 100644
> >> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >> +++ b/drivers/gpu/drm/drm_atomic_helper.c

[snip]

> >> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index
> >> 5c77c3f..76457a4 100644
> >> --- a/include/drm/drm_crtc.h
> >> +++ b/include/drm/drm_crtc.h
> >> @@ -162,10 +162,16 @@ struct drm_crtc_state {
> >>  	 * Target vertical blank period when a page flip
> >>  	 * should take effect.
> >>  	 */
> >>  	u32 target_vblank;
> >>  	
> >>  	/**
> >> +	 * @pflip_flags:
> >> +	 *
> >> +	 * Flip related config options
> > 
> > This isn't detailed enough. I propose something along the lines of
> > 
> > "DRM_MODE_PAGE_FLIP_* page flip flags, as passed to the page flip ioctl.
> > Always zero for atomic commits that don't originate from a page flip
> > ioctl."
> > 
> > You will then also need to reset the field to 0 at an appropriate point,
> > as it's more an atomic commit transaction information than a state. Apart
> > from that this patch looks good to me.
> 
> Thanks for your comments, i am not sure I understand why the reset is
> needed, for any future commit on same crtc the new state will have the
> field empty

It won't, __drm_atomic_helper_crtc_duplicate_state() memcpy's the state, so 
the page flip flags will be copied to the new state until another legacy page 
flip overwrites them.

> and if it's a flip IOCTL the field will be filled as needed in
> page_flip_common, otherwise it will stay empty. If the last commit on that
> crtc was a flip then why not keep this field with the bits that the user
> mode set ?

The page flip flags are not state information. They describe an operation, not 
a state. They're needed when performing the operation, but if we don't reset 
them when it completes (at the latest when duplicating the state for the next 
atomic commit, but possibly earlier) there's a risk that a driver will 
mistakenly perform an async page flip during a later operation.

> >> +	 */
> >> +	u32 pflip_flags;

[snip]
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index a4e5477..28065ee 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2737,7 +2737,8 @@  static int page_flip_common(
 				struct drm_atomic_state *state,
 				struct drm_crtc *crtc,
 				struct drm_framebuffer *fb,
-				struct drm_pending_vblank_event *event)
+				struct drm_pending_vblank_event *event,
+				uint32_t flags)
 {
 	struct drm_plane *plane = crtc->primary;
 	struct drm_plane_state *plane_state;
@@ -2749,12 +2750,12 @@  static int page_flip_common(
 		return PTR_ERR(crtc_state);
 
 	crtc_state->event = event;
+	crtc_state->pflip_flags = flags;
 
 	plane_state = drm_atomic_get_plane_state(state, plane);
 	if (IS_ERR(plane_state))
 		return PTR_ERR(plane_state);
 
-
 	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
 	if (ret != 0)
 		return ret;
@@ -2781,10 +2782,6 @@  static int page_flip_common(
  * Provides a default &drm_crtc_funcs.page_flip implementation
  * using the atomic driver interface.
  *
- * Note that for now so called async page flips (i.e. updates which are not
- * synchronized to vblank) are not supported, since the atomic interfaces have
- * no provisions for this yet.
- *
  * Returns:
  * Returns 0 on success, negative errno numbers on failure.
  *
@@ -2800,9 +2797,6 @@  int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
 	struct drm_atomic_state *state;
 	int ret = 0;
 
-	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
-		return -EINVAL;
-
 	state = drm_atomic_state_alloc(plane->dev);
 	if (!state)
 		return -ENOMEM;
@@ -2810,7 +2804,7 @@  int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
 	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
 
 retry:
-	ret = page_flip_common(state, crtc, fb, event);
+	ret = page_flip_common(state, crtc, fb, event, flags);
 	if (ret != 0)
 		goto fail;
 
@@ -2865,9 +2859,6 @@  int drm_atomic_helper_page_flip_target(
 	struct drm_crtc_state *crtc_state;
 	int ret = 0;
 
-	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
-		return -EINVAL;
-
 	state = drm_atomic_state_alloc(plane->dev);
 	if (!state)
 		return -ENOMEM;
@@ -2875,7 +2866,7 @@  int drm_atomic_helper_page_flip_target(
 	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
 
 retry:
-	ret = page_flip_common(state, crtc, fb, event);
+	ret = page_flip_common(state, crtc, fb, event, flags);
 	if (ret != 0)
 		goto fail;
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 5c77c3f..76457a4 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -162,10 +162,16 @@  struct drm_crtc_state {
 	 * Target vertical blank period when a page flip
 	 * should take effect.
 	 */
-
 	u32 target_vblank;
 
 	/**
+	 * @pflip_flags:
+	 *
+	 * Flip related config options
+	 */
+	u32 pflip_flags;
+
+	/**
 	 * @event:
 	 *
 	 * Optional pointer to a DRM event to signal upon completion of the
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index db3bbde..57414ae 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -122,6 +122,7 @@  struct drm_plane_state {
 	 */
 	bool visible;
 
 	struct drm_atomic_state *state;
 };
 
-- 
1.9.1