All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/38] nonblocking atomic commits for everyone!
@ 2016-06-01 22:06 Daniel Vetter
  2016-06-01 22:06 ` [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
                   ` (38 more replies)
  0 siblings, 39 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

Now without the RFC tag, but with polish:
- kerneldoc for everything!
- tested on virtio, hdlcd, rockchip and i915.

The big upshot is still that the helpers are really picky about drivers sending
out drm events correctly, and that is the area where most of the debug work was
needed in testing these drivers.

What's needed now:
- review and bikesheds (not too many of the latter pls).
- testing on arcpgu, fsl-du & sun4i. Those are among the drivers which didn't
  implement nonblocking and hence will be forcefully upgraded to use these
  helpers. Which might unearth bugs (I tried to fix them, but can't test).

Cheers, Daniel

Daniel Vetter (37):
  drm/atomic-helper: use for_each_*_in_state more
  drm/i915: Use drm_atomic_get_existing_plane_state
  drm/msm: Use for_each_*_in_state
  drm/rcar-du: Use for_each_*_in_state
  drm/vc4: Use for_each_plane_in_state
  drm/omap: Use for_each_plane_in_state
  drm/exynos: Use for_each_crtc_in_state
  drm/atomic: Add __drm_atomic_get_current_plane_state
  drm: Consolidate connector arrays in drm_atomic_state
  drm: Consolidate plane arrays in drm_atomic_state
  drm: Consolidate crtc arrays in drm_atomic_state
  drm/atomic-helper: Massage swap_state signature somewhat
  drm/arc: Nuke event_list
  drm/arc: Actually bother with handling atomic events.
  drm/hdlcd: Clean up crtc hooks
  drm/hdlcd: Fix up crtc_state->event handling
  drm/fsl-du: Implement some semblance of vblank event handling
  drm/hisilicon: Implement some semblance of vblank event handling
  drm/sun4i: Implement some semblance of vblank event handling
  drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
  drm/atomic-helper: nonblocking commit support
  drm/hdlcd: Use helper support for nonblocking commits
  drm/arc: Implement nonblocking commit correctly
  drm/i915: Signal drm events for atomic
  drm/i915: Roll out the helper nonblock tracking
  drm/i915: nonblocking commit
  drm/i915: Use atomic commits for legacy page_flips
  drm/i915: Move fb_bits updating later in atomic_commit
  drm/rockchip: Disarm vop->is_enabled
  drm/rockchip: Fix crtc_state->event signalling
  drm/rockchip: convert to helper nonblocking atomic commit
  drm/rockchip: Nuke pending event handling in preclose
  drm/virtio: Don't reinvent a flipping wheel
  drm: Replace fb_helper->atomic with mode_config->atomic_commit
  drm: Resurrect atomic rmfb code
  drm/sti: Don't call drm_helper_disable_unused_functions
  drm/crtc-helper: disable_unused_functions really isn't for atomic

Gustavo Padovan (1):
  drm/fence: add fence to drm_pending_event

 drivers/gpu/drm/arc/arcpgu.h                    |   1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c               |  19 +-
 drivers/gpu/drm/arc/arcpgu_drv.c                |  27 +-
 drivers/gpu/drm/arm/hdlcd_crtc.c                |  37 +-
 drivers/gpu/drm/arm/hdlcd_drv.c                 |  27 +-
 drivers/gpu/drm/arm/hdlcd_drv.h                 |   1 -
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c    |   2 +-
 drivers/gpu/drm/drm_atomic.c                    | 168 ++++++--
 drivers/gpu/drm/drm_atomic_helper.c             | 532 ++++++++++++++++++++----
 drivers/gpu/drm/drm_crtc.c                      |   9 +
 drivers/gpu/drm/drm_crtc_helper.c               |   3 +
 drivers/gpu/drm/drm_crtc_internal.h             |   1 +
 drivers/gpu/drm/drm_fb_helper.c                 |   6 +-
 drivers/gpu/drm/drm_fops.c                      |  22 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c         |  10 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c      |  23 +-
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c |  20 +-
 drivers/gpu/drm/i915/intel_atomic.c             |   6 +-
 drivers/gpu/drm/i915/intel_display.c            | 178 +++++---
 drivers/gpu/drm/i915/intel_fbdev.c              |   2 -
 drivers/gpu/drm/i915/intel_sprite.c             |  14 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c          |   2 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c         |  20 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c        |  10 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c         |  12 +-
 drivers/gpu/drm/msm/msm_atomic.c                |  37 +-
 drivers/gpu/drm/nouveau/nouveau_usif.c          |   1 -
 drivers/gpu/drm/omapdrm/omap_drv.c              |  13 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c           |  10 +-
 drivers/gpu/drm/rcar-du/rcar_du_plane.c         |  20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c     |  25 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h     |  11 -
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  73 +---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c   |   3 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c     |  68 +--
 drivers/gpu/drm/sti/sti_drv.c                   |   3 +-
 drivers/gpu/drm/sun4i/sun4i_crtc.c              |  12 +
 drivers/gpu/drm/tegra/drm.c                     |   2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c                  |  11 +-
 drivers/gpu/drm/vc4/vc4_drv.h                   |   2 +-
 drivers/gpu/drm/vc4/vc4_kms.c                   |  12 +-
 drivers/gpu/drm/vc4/vc4_plane.c                 |   5 +-
 drivers/gpu/drm/virtio/virtgpu_display.c        |  48 +--
 include/drm/drmP.h                              |   4 +-
 include/drm/drm_atomic.h                        |  79 +++-
 include/drm/drm_atomic_helper.h                 |  12 +-
 include/drm/drm_crtc.h                          | 149 ++++++-
 include/drm/drm_fb_helper.h                     |  11 -
 include/drm/drm_modeset_helper_vtables.h        |  39 ++
 49 files changed, 1165 insertions(+), 637 deletions(-)

-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 11:26   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                   ` (37 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This avois leaking drm_atomic_state internals into the helpers. The
only place where this still happens after this patch is drm_atomic_helper_swap_state().
It's unavoidable there, and maybe a good indicator we should actually
move that function into drm_atomic.c.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 47 +++++++++++++------------------------
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 939df900dcaa..872dbc844d69 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -614,7 +614,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 		if (!funcs || !funcs->atomic_check)
 			continue;
 
-		ret = funcs->atomic_check(crtc, state->crtc_states[i]);
+		ret = funcs->atomic_check(crtc, crtc_state);
 		if (ret) {
 			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
 					 crtc->base.id, crtc->name);
@@ -1252,16 +1252,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 				     struct drm_atomic_state *state)
 {
-	int nplanes = dev->mode_config.num_total_plane;
-	int ret, i;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	int ret, i, j;
 
-	for (i = 0; i < nplanes; i++) {
+	for_each_plane_in_state(state, plane, plane_state, i) {
 		const struct drm_plane_helper_funcs *funcs;
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
 
 		funcs = plane->helper_private;
 
@@ -1275,12 +1271,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 	return 0;
 
 fail:
-	for (i--; i >= 0; i--) {
+	for_each_plane_in_state(state, plane, plane_state, j) {
 		const struct drm_plane_helper_funcs *funcs;
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
 
-		if (!plane)
+		if (j >= i)
 			continue;
 
 		funcs = plane->helper_private;
@@ -1567,35 +1561,26 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 				  struct drm_atomic_state *state)
 {
 	int i;
+	struct drm_connector *connector;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 
-	for (i = 0; i < state->num_connector; i++) {
-		struct drm_connector *connector = state->connectors[i];
-
-		if (!connector)
-			continue;
-
+	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
 		swap(state->connector_states[i], connector->state);
 		connector->state->state = NULL;
 	}
 
-	for (i = 0; i < dev->mode_config.num_crtc; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-
-		if (!crtc)
-			continue;
-
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		crtc->state->state = state;
 		swap(state->crtc_states[i], crtc->state);
 		crtc->state->state = NULL;
 	}
 
-	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
-
-		if (!plane)
-			continue;
-
+	for_each_plane_in_state(state, plane, plane_state, i) {
 		plane->state->state = state;
 		swap(state->plane_states[i], plane->state);
 		plane->state->state = NULL;
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
  2016-06-01 22:06 ` [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 11:25   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 03/38] drm/msm: Use for_each_*_in_state Daniel Vetter
                   ` (36 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to encapsulate the drm_atomic_state internals.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 50ff90aea721..3e6d9ff8840a 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 				continue;
 			}
 
-			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
+			plane_state = to_intel_plane_state(
+				drm_atomic_get_existing_plane_state(drm_state,
+								    plane));
 			scaler_id = &plane_state->scaler_id;
 		}
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 03/38] drm/msm: Use for_each_*_in_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
  2016-06-01 22:06 ` [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:13   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 04/38] drm/rcar-du: " Daniel Vetter
                   ` (35 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to hide drm_atomic_state internals

Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c    | 20 +++++++----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c    | 12 +++-------
 drivers/gpu/drm/msm/msm_atomic.c           | 35 ++++++++++--------------------
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  1 +
 4 files changed, 23 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 67442d50a6c2..f145d256e332 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -106,31 +106,27 @@ out:
 static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-	int i, ncrtcs = state->dev->mode_config.num_crtc;
+	int i;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 
 	mdp4_enable(mdp4_kms);
 
 	/* see 119ecb7fd */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		drm_crtc_vblank_get(crtc);
-	}
 }
 
 static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-	int i, ncrtcs = state->dev->mode_config.num_crtc;
+	int i;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 
 	/* see 119ecb7fd */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		drm_crtc_vblank_put(crtc);
-	}
 
 	mdp4_disable(mdp4_kms);
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 484b4d15e71d..f0c285b1c027 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
 {
 	int i;
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-	int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
-
-	for (i = 0; i < nplanes; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 
+	for_each_plane_in_state(state, plane, plane_state, i)
 		mdp5_plane_complete_commit(plane, plane_state);
-	}
 
 	mdp5_disable(mdp5_kms);
 }
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e3892c263f27..9c0e4261dbba 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
 		struct drm_atomic_state *old_state)
 {
 	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	struct msm_drm_private *priv = old_state->dev->dev_private;
 	struct msm_kms *kms = priv->kms;
-	int ncrtcs = old_state->dev->mode_config.num_crtc;
 	int i;
 
-	for (i = 0; i < ncrtcs; i++) {
-		crtc = old_state->crtcs[i];
-
-		if (!crtc)
-			continue;
-
+	for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
 		if (!crtc->state->enable)
 			continue;
 
@@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
 		struct drm_atomic_state *state, bool nonblock)
 {
 	struct msm_drm_private *priv = dev->dev_private;
-	int nplanes = dev->mode_config.num_total_plane;
-	int ncrtcs = dev->mode_config.num_crtc;
 	struct msm_commit *c;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 	int i, ret;
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
 	/*
 	 * Figure out what crtcs we have:
 	 */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		c->crtc_mask |= (1 << drm_crtc_index(crtc));
-	}
 
 	/*
 	 * Figure out what fence to wait for:
 	 */
-	for (i = 0; i < nplanes; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *new_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
-
-		if ((plane->state->fb != new_state->fb) && new_state->fb) {
-			struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0);
+	for_each_plane_in_state(state, plane, plane_state, i) {
+		if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
+			struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
 			struct msm_gem_object *msm_obj = to_msm_bo(obj);
 
-			new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
+			plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
 		}
 	}
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 755cfdba61cd..03913b483506 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -197,6 +197,7 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_stat
 	struct drm_crtc *crtc;
 	int i, ret;
 
+
 	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
 		/* No one cares about the old state, so abuse it for tracking
 		 * and store whether we hold a vblank reference (and should do a
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 04/38] drm/rcar-du: Use for_each_*_in_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (2 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 03/38] drm/msm: Use for_each_*_in_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:14   ` Maarten Lankhorst
  2016-06-02 21:08   ` Laurent Pinchart
  2016-06-01 22:06 ` [PATCH 05/38] drm/vc4: Use for_each_plane_in_state Daniel Vetter
                   ` (34 subsequent siblings)
  38 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Daniel Vetter

We want to hide drm_atomic_state internals better.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index e70a4f33d970..f315c55c1f65 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 {
 	struct rcar_du_device *rcdu = dev->dev_private;
 	struct rcar_du_commit *commit;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	unsigned int i;
 	int ret;
 
@@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 	/* Wait until all affected CRTCs have completed previous commits and
 	 * mark them as pending.
 	 */
-	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-		if (state->crtcs[i])
-			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-	}
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
+		commit->crtcs |= 1 << drm_crtc_index(crtc);
 
 	spin_lock(&rcdu->commit.wait.lock);
 	ret = wait_event_interruptible_locked(rcdu->commit.wait,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index d445e67f78e1..bfe31ca870cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
 	bool needs_realloc = false;
 	unsigned int groups = 0;
 	unsigned int i;
+	struct drm_plane *drm_plane;
+	struct drm_plane_state *drm_plane_state;
 
 	/* Check if hardware planes need to be reallocated. */
-	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane *plane;
 		unsigned int index;
 
-		if (!state->planes[i])
-			continue;
-
-		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_plane_state(state->plane_states[i]);
+		plane = to_rcar_plane(drm_plane);
+		plane_state = to_rcar_plane_state(drm_plane_state);
 
 		dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
 			plane->group->index, plane - plane->group->planes);
@@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
 	}
 
 	/* Reallocate hardware planes for each plane that needs it. */
-	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane *plane;
 		unsigned int crtc_planes;
 		unsigned int free;
 		int idx;
 
-		if (!state->planes[i])
-			continue;
-
-		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_plane_state(state->plane_states[i]);
+		plane = to_rcar_plane(drm_plane);
+		plane_state = to_rcar_plane_state(drm_plane_state);
 
 		dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
 			plane->group->index, plane - plane->group->planes);
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 05/38] drm/vc4: Use for_each_plane_in_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (3 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 04/38] drm/rcar-du: " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:15   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 06/38] drm/omap: " Daniel Vetter
                   ` (33 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

We want to hide drm_atomic_stat internals a bit better.

Cc: Eric Anholt <eric@anholt.net>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index cb37751bc99f..39c0b2048bfd 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -111,6 +111,8 @@ static int vc4_atomic_commit(struct drm_device *dev,
 	int i;
 	uint64_t wait_seqno = 0;
 	struct vc4_commit *c;
+	struct drm_plane *plane;
+	struct drm_plane_state *new_state;
 
 	c = commit_init(state);
 	if (!c)
@@ -130,13 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
 		return ret;
 	}
 
-	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *new_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
-
+	for_each_plane_in_state(state, plane, new_state, i) {
 		if ((plane->state->fb != new_state->fb) && new_state->fb) {
 			struct drm_gem_cma_object *cma_bo =
 				drm_fb_cma_get_gem_obj(new_state->fb, 0);
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 06/38] drm/omap: Use for_each_plane_in_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (4 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 05/38] drm/vc4: Use for_each_plane_in_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:23   ` Maarten Lankhorst
  2016-06-02 21:08   ` Laurent Pinchart
  2016-06-01 22:06 ` [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
                   ` (32 subsequent siblings)
  38 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	Laurent Pinchart, Daniel Vetter

We want to hide drm_atomic_stat internals a bit better.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index d86f5479345b..4798ba43ff5b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_atomic_state_commit *commit;
-	unsigned int i;
-	int ret;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int i, ret;
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
@@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
 	/* Wait until all affected CRTCs have completed previous commits and
 	 * mark them as pending.
 	 */
-	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-		if (state->crtcs[i])
-			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-	}
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
+		commit->crtcs |= 1 << drm_crtc_index(crtc);
 
 	wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (5 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 06/38] drm/omap: " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:23   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
                   ` (31 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to hide drm_atomic_state internals better.

Cc: Inki Dae <inki.dae@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2dd820e23b0c..cabc5fd0246d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 {
 	struct exynos_drm_private *priv = dev->dev_private;
 	struct exynos_atomic_commit *commit;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	int i, ret;
 
 	commit = kzalloc(sizeof(*commit), GFP_KERNEL);
@@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 	/* Wait until all affected CRTCs have completed previous commits and
 	 * mark them as pending.
 	 */
-	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-		if (state->crtcs[i])
-			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-	}
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
+		commit->crtcs |= 1 << drm_crtc_index(crtc);
 
 	wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (6 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:41   ` Maarten Lankhorst
  2016-06-02 14:21   ` [PATCH] " Daniel Vetter
  2016-06-01 22:06 ` [PATCH 09/38] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
                   ` (30 subsequent siblings)
  38 siblings, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

... and use it in msm&vc4. Again just want to encapsulate
drm_atomic_state internals a bit.

The const threading is a bit awkward in vc4 since C sucks, but I still
think it's worth to enforce this. Eventually I want to make all the
obj->state pointers const too, but that's a lot more work ...

Cc: Eric Anholt <eric@anholt.net>
Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++------
 drivers/gpu/drm/vc4/vc4_crtc.c           | 11 +++-------
 drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
 drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
 include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
 5 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 88fe256c1931..6d4086ee0503 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	 */
 	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *pstate;
+		const struct drm_plane_state *pstate;
 		if (cnt >= (hw_cfg->lm.nb_stages)) {
 			dev_err(dev->dev, "too many planes!\n");
 			return -EINVAL;
 		}
 
-		pstate = state->state->plane_states[drm_plane_index(plane)];
+		pstate = __drm_atomic_get_current_plane_state(state->state,
+							      plane);
 
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!pstate)
-			pstate = plane->state;
 		pstates[cnt].plane = plane;
 		pstates[cnt].state = to_mdp5_plane_state(pstate);
 
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 904d0754ad78..703bda170105 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 		return -EINVAL;
 
 	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *plane_state =
-			state->state->plane_states[drm_plane_index(plane)];
-
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!plane_state)
-			plane_state = plane->state;
+		const struct drm_plane_state *plane_state =
+			__drm_atomic_get_current_plane_state(state->state,
+							     plane);
 
 		dlist_count += vc4_plane_dlist_size(plane_state);
 	}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37cac59401d7..c799baabc008 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
 				 enum drm_plane_type type);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
-u32 vc4_plane_dlist_size(struct drm_plane_state *state);
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
 void vc4_plane_async_set_fb(struct drm_plane *plane,
 			    struct drm_framebuffer *fb);
 
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4037b52fde31..5d2c3d9fd17a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
 	return vc4_state->dlist_count;
 }
 
-u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
 {
-	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+	const struct vc4_plane_state *vc4_state =
+		container_of(state, typeof(*vc4_state), base);
 
 	return vc4_state->dlist_count;
 }
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92c84e9ab09a..4e97186293be 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 	return state->connector_states[index];
 }
 
+/**
+ * __drm_atomic_get_current_plane_state - get current plane state
+ * @state: global atomic state object
+ * @plane: plane to grab
+ *
+ * This function returns the plane state for the given plane, either from
+ * @state, or if the plane isn't part of the atomic state update, from @plane.
+ * This is useful in atomic check callbacks, when drivers need to peek at, but
+ * not change, state of other planes, since it avoids threading an error code
+ * back up the call chain.
+ *
+ * WARNING:
+ *
+ * Note that this function is in general unsafe since it doesn't check for the
+ * required locking for access state structures. Drivers must ensure that it is
+ * save to access the returned state structure through other means. One commone
+ * example is when planes are fixed to a single CRTC, and the driver knows that
+ * the CRTC locks is held already. In that case holding the CRTC locks gives a
+ * read-lock on all planes connected to that CRTC. But if planes can be
+ * reassigned things get more tricky. In that case it's better to use
+ * drm_atomic_get_plane_state and wire up full error handling.
+ *
+ * Returns:
+ *
+ * Read-only pointer to the current plane state.
+ */
+static inline const struct drm_plane_state *
+__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
+				     struct drm_plane *plane)
+{
+	if (state->plane_states[drm_plane_index(plane)])
+		return state->plane_states[drm_plane_index(plane)];
+
+	return plane->state;
+}
+
 int __must_check
 drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
 			     struct drm_display_mode *mode);
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 09/38] drm: Consolidate connector arrays in drm_atomic_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (7 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 10/38] drm: Consolidate plane " Daniel Vetter
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-connector state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
connectors, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h            | 10 +++++-----
 include/drm/drm_crtc.h              | 11 +++++++----
 4 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c204ef32df16..8ca0ae21287f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -44,7 +44,6 @@
 void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
 	kfree(state->connectors);
-	kfree(state->connector_states);
 	kfree(state->crtcs);
 	kfree(state->crtc_states);
 	kfree(state->planes);
@@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
 
 	for (i = 0; i < state->num_connector; i++) {
-		struct drm_connector *connector = state->connectors[i];
+		struct drm_connector *connector = state->connectors[i].ptr;
 
 		if (!connector)
 			continue;
 
 		connector->funcs->atomic_destroy_state(connector,
-						       state->connector_states[i]);
-		state->connectors[i] = NULL;
-		state->connector_states[i] = NULL;
+						       state->connectors[i].state);
+		state->connectors[i].ptr = NULL;
+		state->connectors[i].state = NULL;
 		drm_connector_unreference(connector);
 	}
 
@@ -897,8 +896,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
 	index = drm_connector_index(connector);
 
 	if (index >= state->num_connector) {
-		struct drm_connector **c;
-		struct drm_connector_state **cs;
+		struct __drm_connnectors_state *c;
 		int alloc = max(index + 1, config->num_connector);
 
 		c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
@@ -909,26 +907,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
 		memset(&state->connectors[state->num_connector], 0,
 		       sizeof(*state->connectors) * (alloc - state->num_connector));
 
-		cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
-		if (!cs)
-			return ERR_PTR(-ENOMEM);
-
-		state->connector_states = cs;
-		memset(&state->connector_states[state->num_connector], 0,
-		       sizeof(*state->connector_states) * (alloc - state->num_connector));
 		state->num_connector = alloc;
 	}
 
-	if (state->connector_states[index])
-		return state->connector_states[index];
+	if (state->connectors[index].state)
+		return state->connectors[index].state;
 
 	connector_state = connector->funcs->atomic_duplicate_state(connector);
 	if (!connector_state)
 		return ERR_PTR(-ENOMEM);
 
 	drm_connector_reference(connector);
-	state->connector_states[index] = connector_state;
-	state->connectors[index] = connector;
+	state->connectors[index].state = connector_state;
+	state->connectors[index].ptr = connector;
 	connector_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 872dbc844d69..70504cbb3a9a 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1570,7 +1570,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
-		swap(state->connector_states[i], connector->state);
+		swap(state->connectors[i].state, connector->state);
 		connector->state->state = NULL;
 	}
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 4e97186293be..37478adb6a16 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -106,7 +106,7 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 	if (index >= state->num_connector)
 		return NULL;
 
-	return state->connector_states[index];
+	return state->connectors[index].state;
 }
 
 /**
@@ -175,11 +175,11 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
 int __must_check drm_atomic_commit(struct drm_atomic_state *state);
 int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 
-#define for_each_connector_in_state(state, connector, connector_state, __i) \
+#define for_each_connector_in_state(__state, connector, connector_state, __i) \
 	for ((__i) = 0;							\
-	     (__i) < (state)->num_connector &&				\
-	     ((connector) = (state)->connectors[__i],			\
-	     (connector_state) = (state)->connector_states[__i], 1); 	\
+	     (__i) < (__state)->num_connector &&				\
+	     ((connector) = (__state)->connectors[__i].ptr,			\
+	     (connector_state) = (__state)->connectors[__i].state, 1); 	\
 	     (__i)++)							\
 		for_each_if (connector)
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 5bffb5c86ea8..d4c46bfe4142 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1694,6 +1694,11 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+struct __drm_connnectors_state {
+	struct drm_connector *ptr;
+	struct drm_connector_state *state;
+};
+
 /**
  * struct drm_atomic_state - the global state object for atomic updates
  * @dev: parent DRM device
@@ -1705,8 +1710,7 @@ struct drm_bridge {
  * @crtcs: pointer to array of CRTC pointers
  * @crtc_states: pointer to array of CRTC states pointers
  * @num_connector: size of the @connectors and @connector_states arrays
- * @connectors: pointer to array of connector pointers
- * @connector_states: pointer to array of connector states pointers
+ * @connectors: pointer to array of structures with per-connector data
  * @acquire_ctx: acquire context for this atomic modeset state update
  */
 struct drm_atomic_state {
@@ -1719,8 +1723,7 @@ struct drm_atomic_state {
 	struct drm_crtc **crtcs;
 	struct drm_crtc_state **crtc_states;
 	int num_connector;
-	struct drm_connector **connectors;
-	struct drm_connector_state **connector_states;
+	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 10/38] drm: Consolidate plane arrays in drm_atomic_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (8 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 09/38] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 11/38] drm: Consolidate crtc " Daniel Vetter
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-plane state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
planes, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 17 ++++++-----------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 drivers/gpu/drm/i915/intel_atomic.c |  2 +-
 include/drm/drm_atomic.h            | 14 +++++++-------
 include/drm/drm_crtc.h              | 11 +++++++----
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 8ca0ae21287f..dce4627aa1c6 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -47,7 +47,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
 	kfree(state->crtcs);
 	kfree(state->crtc_states);
 	kfree(state->planes);
-	kfree(state->plane_states);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);
 
@@ -79,10 +78,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 				sizeof(*state->planes), GFP_KERNEL);
 	if (!state->planes)
 		goto fail;
-	state->plane_states = kcalloc(dev->mode_config.num_total_plane,
-				      sizeof(*state->plane_states), GFP_KERNEL);
-	if (!state->plane_states)
-		goto fail;
 
 	state->dev = dev;
 
@@ -163,15 +158,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	}
 
 	for (i = 0; i < config->num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
+		struct drm_plane *plane = state->planes[i].ptr;
 
 		if (!plane)
 			continue;
 
 		plane->funcs->atomic_destroy_state(plane,
-						   state->plane_states[i]);
-		state->planes[i] = NULL;
-		state->plane_states[i] = NULL;
+						   state->planes[i].state);
+		state->planes[i].ptr = NULL;
+		state->planes[i].state = NULL;
 	}
 }
 EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@ -631,8 +626,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
 	if (!plane_state)
 		return ERR_PTR(-ENOMEM);
 
-	state->plane_states[index] = plane_state;
-	state->planes[index] = plane;
+	state->planes[index].state = plane_state;
+	state->planes[index].ptr = plane;
 	plane_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 70504cbb3a9a..451b86ecd253 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1582,7 +1582,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
 		plane->state->state = state;
-		swap(state->plane_states[i], plane->state);
+		swap(state->planes[i].state, plane->state);
 		plane->state->state = NULL;
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3e6d9ff8840a..7542f5f5db1d 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -191,7 +191,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 
 			/* plane scaler case: assign as a plane scaler */
 			/* find the plane that set the bit as scaler_user */
-			plane = drm_state->planes[i];
+			plane = drm_state->planes[i].ptr;
 
 			/*
 			 * to enable/disable hq mode, add planes that are using scaler
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 37478adb6a16..8e616d39353b 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -86,7 +86,7 @@ static inline struct drm_plane_state *
 drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
 				    struct drm_plane *plane)
 {
-	return state->plane_states[drm_plane_index(plane)];
+	return state->planes[drm_plane_index(plane)].state;
 }
 
 /**
@@ -139,8 +139,8 @@ static inline const struct drm_plane_state *
 __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
 				     struct drm_plane *plane)
 {
-	if (state->plane_states[drm_plane_index(plane)])
-		return state->plane_states[drm_plane_index(plane)];
+	if (state->planes[drm_plane_index(plane)].state)
+		return state->planes[drm_plane_index(plane)].state;
 
 	return plane->state;
 }
@@ -191,11 +191,11 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (__i)++)						\
 		for_each_if (crtc_state)
 
-#define for_each_plane_in_state(state, plane, plane_state, __i)		\
+#define for_each_plane_in_state(__state, plane, plane_state, __i)		\
 	for ((__i) = 0;							\
-	     (__i) < (state)->dev->mode_config.num_total_plane &&	\
-	     ((plane) = (state)->planes[__i],				\
-	     (plane_state) = (state)->plane_states[__i], 1);		\
+	     (__i) < (__state)->dev->mode_config.num_total_plane &&	\
+	     ((plane) = (__state)->planes[__i].ptr,				\
+	     (plane_state) = (__state)->planes[__i].state, 1);		\
 	     (__i)++)							\
 		for_each_if (plane_state)
 static inline bool
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d4c46bfe4142..c7c2b3fa7179 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1694,6 +1694,11 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+struct __drm_planes_state {
+	struct drm_plane *ptr;
+	struct drm_plane_state *state;
+};
+
 struct __drm_connnectors_state {
 	struct drm_connector *ptr;
 	struct drm_connector_state *state;
@@ -1705,8 +1710,7 @@ struct __drm_connnectors_state {
  * @allow_modeset: allow full modeset
  * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
  * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
- * @planes: pointer to array of plane pointers
- * @plane_states: pointer to array of plane states pointers
+ * @planes: pointer to array of structures with per-plane data
  * @crtcs: pointer to array of CRTC pointers
  * @crtc_states: pointer to array of CRTC states pointers
  * @num_connector: size of the @connectors and @connector_states arrays
@@ -1718,8 +1722,7 @@ struct drm_atomic_state {
 	bool allow_modeset : 1;
 	bool legacy_cursor_update : 1;
 	bool legacy_set_config : 1;
-	struct drm_plane **planes;
-	struct drm_plane_state **plane_states;
+	struct __drm_planes_state *planes;
 	struct drm_crtc **crtcs;
 	struct drm_crtc_state **crtc_states;
 	int num_connector;
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 11/38] drm: Consolidate crtc arrays in drm_atomic_state
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (9 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 10/38] drm: Consolidate plane " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 14:42   ` Maarten Lankhorst
  2016-06-01 22:06 ` [PATCH 12/38] drm/fence: add fence to drm_pending_event Daniel Vetter
                   ` (27 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's silly to have 2 mallocs when we could tie these two together.

Also, Gustavo adds another one in his per-crtc out-fence patches. And
I want to add more stuff here for nonblocking commit helpers.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 17 ++++++-----------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h            | 10 +++++-----
 include/drm/drm_crtc.h              |  8 ++++++--
 4 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index dce4627aa1c6..5093d81f60f7 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,7 +45,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
 	kfree(state->connectors);
 	kfree(state->crtcs);
-	kfree(state->crtc_states);
 	kfree(state->planes);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);
@@ -70,10 +69,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 			       sizeof(*state->crtcs), GFP_KERNEL);
 	if (!state->crtcs)
 		goto fail;
-	state->crtc_states = kcalloc(dev->mode_config.num_crtc,
-				     sizeof(*state->crtc_states), GFP_KERNEL);
-	if (!state->crtc_states)
-		goto fail;
 	state->planes = kcalloc(dev->mode_config.num_total_plane,
 				sizeof(*state->planes), GFP_KERNEL);
 	if (!state->planes)
@@ -146,15 +141,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	}
 
 	for (i = 0; i < config->num_crtc; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
+		struct drm_crtc *crtc = state->crtcs[i].ptr;
 
 		if (!crtc)
 			continue;
 
 		crtc->funcs->atomic_destroy_state(crtc,
-						  state->crtc_states[i]);
-		state->crtcs[i] = NULL;
-		state->crtc_states[i] = NULL;
+						  state->crtcs[i].state);
+		state->crtcs[i].ptr = NULL;
+		state->crtcs[i].state = NULL;
 	}
 
 	for (i = 0; i < config->num_total_plane; i++) {
@@ -264,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 	if (!crtc_state)
 		return ERR_PTR(-ENOMEM);
 
-	state->crtc_states[index] = crtc_state;
-	state->crtcs[index] = crtc;
+	state->crtcs[index].state = crtc_state;
+	state->crtcs[index].ptr = crtc;
 	crtc_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 451b86ecd253..b2d276d97d32 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1576,7 +1576,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		crtc->state->state = state;
-		swap(state->crtc_states[i], crtc->state);
+		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
 	}
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8e616d39353b..d9504dfcd1cc 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -71,7 +71,7 @@ static inline struct drm_crtc_state *
 drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
 				   struct drm_crtc *crtc)
 {
-	return state->crtc_states[drm_crtc_index(crtc)];
+	return state->crtcs[drm_crtc_index(crtc)].state;
 }
 
 /**
@@ -183,11 +183,11 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (__i)++)							\
 		for_each_if (connector)
 
-#define for_each_crtc_in_state(state, crtc, crtc_state, __i)	\
+#define for_each_crtc_in_state(__state, crtc, crtc_state, __i)	\
 	for ((__i) = 0;						\
-	     (__i) < (state)->dev->mode_config.num_crtc &&	\
-	     ((crtc) = (state)->crtcs[__i],			\
-	     (crtc_state) = (state)->crtc_states[__i], 1);	\
+	     (__i) < (__state)->dev->mode_config.num_crtc &&	\
+	     ((crtc) = (__state)->crtcs[__i].ptr,			\
+	     (crtc_state) = (__state)->crtcs[__i].state, 1);	\
 	     (__i)++)						\
 		for_each_if (crtc_state)
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c7c2b3fa7179..d5d5e343531e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1699,6 +1699,11 @@ struct __drm_planes_state {
 	struct drm_plane_state *state;
 };
 
+struct __drm_crtcs_state {
+	struct drm_crtc *ptr;
+	struct drm_crtc_state *state;
+};
+
 struct __drm_connnectors_state {
 	struct drm_connector *ptr;
 	struct drm_connector_state *state;
@@ -1723,8 +1728,7 @@ struct drm_atomic_state {
 	bool legacy_cursor_update : 1;
 	bool legacy_set_config : 1;
 	struct __drm_planes_state *planes;
-	struct drm_crtc **crtcs;
-	struct drm_crtc_state **crtc_states;
+	struct __drm_crtcs_state *crtcs;
 	int num_connector;
 	struct __drm_connnectors_state *connectors;
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 12/38] drm/fence: add fence to drm_pending_event
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (10 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 11/38] drm: Consolidate crtc " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 18:49   ` Sean Paul
  2016-06-01 22:06 ` [PATCH 13/38] drm/atomic-helper: Massage swap_state signature somewhat Daniel Vetter
                   ` (26 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Now a drm_pending_event can either send a real drm_event or signal a
fence, or both. It allow us to signal via fences when the buffer is
displayed on the screen. Which in turn means that the previous buffer
is not in use anymore and can be freed or sent back to another driver
for processing.

v2: Comments from Daniel Vetter
	- call fence_signal in drm_send_event_locked()
	- remove unneeded !e->event check

v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv
is not set.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> (v2)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic.c                | 19 +++++++++++++------
 drivers/gpu/drm/drm_fops.c                  | 16 +++++++++-------
 drivers/gpu/drm/nouveau/nouveau_usif.c      |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  2 +-
 include/drm/drmP.h                          |  3 ++-
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5093d81f60f7..5e4b820a977c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1413,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
  */
 
 static struct drm_pending_vblank_event *create_vblank_event(
-		struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
+		struct drm_device *dev, struct drm_file *file_priv,
+		struct fence *fence, uint64_t user_data)
 {
 	struct drm_pending_vblank_event *e = NULL;
 	int ret;
@@ -1426,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
 	e->event.base.length = sizeof(e->event);
 	e->event.user_data = user_data;
 
-	ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
-	if (ret) {
-		kfree(e);
-		return NULL;
+	if (file_priv) {
+		ret = drm_event_reserve_init(dev, file_priv, &e->base,
+					     &e->event.base);
+		if (ret) {
+			kfree(e);
+			return NULL;
+		}
 	}
 
+	e->base.fence = fence;
+
 	return e;
 }
 
@@ -1671,7 +1677,8 @@ retry:
 		for_each_crtc_in_state(state, crtc, crtc_state, i) {
 			struct drm_pending_vblank_event *e;
 
-			e = create_vblank_event(dev, file_priv, arg->user_data);
+			e = create_vblank_event(dev, file_priv, NULL,
+						arg->user_data);
 			if (!e) {
 				ret = -ENOMEM;
 				goto out;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 868871068956..4c4b30f7a9f2 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -294,7 +294,7 @@ static void drm_events_release(struct drm_file *file_priv)
 	/* Remove unconsumed events */
 	list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
 		list_del(&e->link);
-		e->destroy(e);
+		kfree(e);
 	}
 
 	spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -525,7 +525,7 @@ put_back_event:
 			}
 
 			ret += length;
-			e->destroy(e);
+			kfree(e);
 		}
 	}
 	mutex_unlock(&file_priv->event_read_lock);
@@ -602,9 +602,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
 	list_add(&p->pending_link, &file_priv->pending_event_list);
 	p->file_priv = file_priv;
 
-	/* we *could* pass this in as arg, but everyone uses kfree: */
-	p->destroy = (void (*) (struct drm_pending_event *)) kfree;
-
 	return 0;
 }
 EXPORT_SYMBOL(drm_event_reserve_init_locked);
@@ -667,7 +664,7 @@ void drm_event_cancel_free(struct drm_device *dev,
 		list_del(&p->pending_link);
 	}
 	spin_unlock_irqrestore(&dev->event_lock, flags);
-	p->destroy(p);
+	kfree(p);
 }
 EXPORT_SYMBOL(drm_event_cancel_free);
 
@@ -689,8 +686,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->fence) {
+		fence_signal(e->fence);
+		fence_put(e->fence);
+	}
+
 	if (!e->file_priv) {
-		e->destroy(e);
+		kfree(e);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
index 675e9e077a95..08f9c6fa0f7f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_usif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
@@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
 	ntfy->p->base.event = &ntfy->p->e.base;
 	ntfy->p->base.file_priv = f;
 	ntfy->p->base.pid = current->pid;
-	ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
 	ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
 	ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1c4d5b5a70a2..5567fb43e674 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
 	if (e && e->base.file_priv == file_priv) {
 		vop->event = NULL;
 
-		e->base.destroy(&e->base);
+		kfree(&e->base);
 		file_priv->event_space += sizeof(e->event);
 	}
 	spin_unlock_irqrestore(&drm->event_lock, flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index f51fa4328494..51f751d1c8a4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -57,6 +57,7 @@
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/fence.h>
 
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
@@ -283,12 +284,12 @@ struct drm_ioctl_desc {
 /* Event queued up for userspace to read */
 struct drm_pending_event {
 	struct drm_event *event;
+	struct fence *fence;
 	struct list_head link;
 	struct list_head pending_link;
 	struct drm_file *file_priv;
 	pid_t pid; /* pid of requester, no guarantee it's valid by the time
 		      we deliver the event, for tracing only */
-	void (*destroy)(struct drm_pending_event *event);
 };
 
 /* initial implementaton using a linked list - todo hashtab */
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 13/38] drm/atomic-helper: Massage swap_state signature somewhat
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (11 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 12/38] drm/fence: add fence to drm_pending_event Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06   ` Daniel Vetter
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

- dev is redundant, we have state->atomic
- add stall parameter, which must be set when swapping needs to stall
  for preceeding commits to stop looking at ->state pointers. Currently
  all drivers need this to be, just prep work for a glorious future.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +-
 drivers/gpu/drm/drm_atomic_helper.c          | 8 ++++----
 drivers/gpu/drm/exynos/exynos_drm_drv.c      | 2 +-
 drivers/gpu/drm/i915/intel_display.c         | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c       | 2 +-
 drivers/gpu/drm/msm/msm_atomic.c             | 2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c           | 2 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c        | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c   | 2 +-
 drivers/gpu/drm/sti/sti_drv.c                | 2 +-
 drivers/gpu/drm/tegra/drm.c                  | 2 +-
 drivers/gpu/drm/vc4/vc4_kms.c                | 2 +-
 include/drm/drm_atomic_helper.h              | 4 ++--
 13 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 6485fa5bee8b..9ecf16c7911d 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -519,7 +519,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
 	}
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (async)
 		queue_work(dc->wq, &commit->work);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index b2d276d97d32..65128f258f84 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1163,7 +1163,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
@@ -1534,8 +1534,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
 
 /**
  * drm_atomic_helper_swap_state - store atomic state into current sw state
- * @dev: DRM device
  * @state: atomic state
+ * @stall: stall for proceeding commits
  *
  * This function stores the atomic state into the current state pointers in all
  * driver objects. It should be called after all failing steps have been done
@@ -1557,8 +1557,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
  */
-void drm_atomic_helper_swap_state(struct drm_device *dev,
-				  struct drm_atomic_state *state)
+void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+				  bool stall)
 {
 	int i;
 	struct drm_connector *connector;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index cabc5fd0246d..deba76982358 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -299,7 +299,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 	priv->pending |= commit->crtcs;
 	spin_unlock(&priv->lock);
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 60cba1956c0d..a59cc0e2e5ca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13726,7 +13726,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 		return ret;
 	}
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 	dev_priv->wm.distrust_bios_wm = false;
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b7e5f4a736f0..04e901a80234 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -91,7 +91,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
 	mutex_lock(&private->commit.lock);
 	flush_work(&private->commit.work);
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (async)
 		mtk_atomic_schedule(private, state);
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9c0e4261dbba..d02bd6a50e90 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -238,7 +238,7 @@ int msm_atomic_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 4798ba43ff5b..402d2d899b65 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -174,7 +174,7 @@ static int omap_atomic_commit(struct drm_device *dev,
 	spin_unlock(&priv->commit.lock);
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index f315c55c1f65..3d04a506cf33 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -327,7 +327,7 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 	}
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 03913b483506..5ea141dfae5b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -290,7 +290,7 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
 	mutex_lock(&commit->lock);
 	flush_work(&commit->work);
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	commit->dev = dev;
 	commit->state = state;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index b440617a7019..dd2c400c4a46 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -215,7 +215,7 @@ static int sti_atomic_commit(struct drm_device *drm,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		sti_atomic_schedule(private, state);
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index b59c3bf0df44..a177a42a9849 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -93,7 +93,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		tegra_atomic_schedule(tegra, state);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 39c0b2048bfd..8f4d5ffc32be 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -148,7 +148,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d473dcc91f54..0276447225ed 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -71,8 +71,8 @@ void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_sta
 void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 					      bool atomic);
 
-void drm_atomic_helper_swap_state(struct drm_device *dev,
-				  struct drm_atomic_state *state);
+void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+				  bool stall);
 
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 14/38] drm/arc: Nuke event_list
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
@ 2016-06-01 22:06   ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (37 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: linux-snps-arc

This is just used for cleanup in preclose, and with the reworked event
handling code this is now done properly by the core.

Nuke it!

But it also shows that arc totally fails at sending out drm events for
flips. Next patch will hack that up.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu.h      |  1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c |  4 ----
 drivers/gpu/drm/arc/arcpgu_drv.c  | 19 -------------------
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h
index 86574b698a78..8c01a25d279a 100644
--- a/drivers/gpu/drm/arc/arcpgu.h
+++ b/drivers/gpu/drm/arc/arcpgu.h
@@ -22,7 +22,6 @@ struct arcpgu_drm_private {
 	struct clk		*clk;
 	struct drm_fbdev_cma	*fbdev;
 	struct drm_framebuffer	*fb;
-	struct list_head	event_list;
 	struct drm_crtc		crtc;
 	struct drm_plane	*plane;
 };
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 92f8beff8e60..d5ca0c280e68 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 		event->pipe = drm_crtc_index(crtc);
 
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &arcpgu->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	}
 }
 
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..d407fd79a400 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = {
 	.mmap = arcpgu_gem_mmap,
 };
 
-static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
-{
-	struct arcpgu_drm_private *arcpgu = drm->dev_private;
-	struct drm_pending_vblank_event *e, *t;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) {
-		if (e->base.file_priv != file)
-			continue;
-		list_del(&e->base.link);
-		e->base.destroy(&e->base);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void arcpgu_lastclose(struct drm_device *drm)
 {
 	struct arcpgu_drm_private *arcpgu = drm->dev_private;
@@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm)
 	if (IS_ERR(arcpgu->clk))
 		return PTR_ERR(arcpgu->clk);
 
-	INIT_LIST_HEAD(&arcpgu->event_list);
-
 	arcpgu_setup_mode_config(drm);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm)
 static struct drm_driver arcpgu_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
 			   DRIVER_ATOMIC,
-	.preclose = arcpgu_preclose,
 	.lastclose = arcpgu_lastclose,
 	.name = "drm-arcpgu",
 	.desc = "ARC PGU Controller",
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 14/38] drm/arc: Nuke event_list
@ 2016-06-01 22:06   ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

This is just used for cleanup in preclose, and with the reworked event
handling code this is now done properly by the core.

Nuke it!

But it also shows that arc totally fails at sending out drm events for
flips. Next patch will hack that up.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu.h      |  1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c |  4 ----
 drivers/gpu/drm/arc/arcpgu_drv.c  | 19 -------------------
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h
index 86574b698a78..8c01a25d279a 100644
--- a/drivers/gpu/drm/arc/arcpgu.h
+++ b/drivers/gpu/drm/arc/arcpgu.h
@@ -22,7 +22,6 @@ struct arcpgu_drm_private {
 	struct clk		*clk;
 	struct drm_fbdev_cma	*fbdev;
 	struct drm_framebuffer	*fb;
-	struct list_head	event_list;
 	struct drm_crtc		crtc;
 	struct drm_plane	*plane;
 };
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 92f8beff8e60..d5ca0c280e68 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 		event->pipe = drm_crtc_index(crtc);
 
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &arcpgu->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	}
 }
 
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..d407fd79a400 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = {
 	.mmap = arcpgu_gem_mmap,
 };
 
-static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
-{
-	struct arcpgu_drm_private *arcpgu = drm->dev_private;
-	struct drm_pending_vblank_event *e, *t;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) {
-		if (e->base.file_priv != file)
-			continue;
-		list_del(&e->base.link);
-		e->base.destroy(&e->base);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void arcpgu_lastclose(struct drm_device *drm)
 {
 	struct arcpgu_drm_private *arcpgu = drm->dev_private;
@@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm)
 	if (IS_ERR(arcpgu->clk))
 		return PTR_ERR(arcpgu->clk);
 
-	INIT_LIST_HEAD(&arcpgu->event_list);
-
 	arcpgu_setup_mode_config(drm);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm)
 static struct drm_driver arcpgu_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
 			   DRIVER_ATOMIC,
-	.preclose = arcpgu_preclose,
 	.lastclose = arcpgu_lastclose,
 	.name = "drm-arcpgu",
 	.desc = "ARC PGU Controller",
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 15/38] drm/arc: Actually bother with handling atomic events.
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
@ 2016-06-01 22:06   ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (37 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: linux-snps-arc

The drm core has a nice ready-made helper for exactly the simple case
where it should fire on the next vblank.

Note that arming the vblank event in _begin is probably too early, and
might easily result in the vblank firing too early, before the new set
of planes are actually disabled. But that's kinda a minor issue
compared to just outright hanging userspace.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index d5ca0c280e68..c9f183b11df9 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -145,16 +145,17 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 				      struct drm_crtc_state *state)
 {
-	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
+	if (event) {
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
 
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 }
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 15/38] drm/arc: Actually bother with handling atomic events.
@ 2016-06-01 22:06   ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

The drm core has a nice ready-made helper for exactly the simple case
where it should fire on the next vblank.

Note that arming the vblank event in _begin is probably too early, and
might easily result in the vblank firing too early, before the new set
of planes are actually disabled. But that's kinda a minor issue
compared to just outright hanging userspace.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index d5ca0c280e68..c9f183b11df9 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -145,16 +145,17 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 				      struct drm_crtc_state *state)
 {
-	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
+	if (event) {
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
 
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 }
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 16/38] drm/hdlcd: Clean up crtc hooks
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (14 preceding siblings ...)
  2016-06-01 22:06   ` Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02 13:33   ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 17/38] drm/hdlcd: Fix up crtc_state->event handling Daniel Vetter
                   ` (22 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau

Those are all no longer needed for a pure atomic driver.

Cc: Liviu Dudau <Liviu.Dudau@arm.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index fef1b04c2aab..b44f72722764 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
 	}
 }
 
-static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
-				    struct drm_crtc_state *state)
-{
-}
-
-static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
-			const struct drm_display_mode *mode,
-			struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
 static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
-	.mode_fixup	= hdlcd_crtc_mode_fixup,
-	.mode_set	= drm_helper_crtc_mode_set,
-	.mode_set_base	= drm_helper_crtc_mode_set_base,
-	.mode_set_nofb	= hdlcd_crtc_mode_set_nofb,
 	.enable		= hdlcd_crtc_enable,
 	.disable	= hdlcd_crtc_disable,
-	.prepare	= hdlcd_crtc_disable,
-	.commit		= hdlcd_crtc_enable,
 	.atomic_check	= hdlcd_crtc_atomic_check,
 	.atomic_begin	= hdlcd_crtc_atomic_begin,
-	.atomic_flush	= hdlcd_crtc_atomic_flush,
 };
 
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 17/38] drm/hdlcd: Fix up crtc_state->event handling
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (15 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 16/38] drm/hdlcd: Clean up crtc hooks Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
                   ` (21 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau, Daniel Vetter

event_list just reimplemented what drm_crtc_arm_vblank_event does. And
we also need to send out drm events when shutting down a pipe.

With this it's possible to use the new nonblocking commit support in
the helpers.

Cc: Liviu Dudau <Liviu.Dudau@arm.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arm/hdlcd_crtc.c | 18 ++++++++----------
 drivers/gpu/drm/arm/hdlcd_drv.c  | 19 +------------------
 drivers/gpu/drm/arm/hdlcd_drv.h  |  1 -
 3 files changed, 9 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index b44f72722764..93486c46c6b0 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -180,19 +180,17 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
 				    struct drm_crtc_state *state)
 {
 	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
+	if (event) {
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
-
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &hdlcd->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 }
 
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 4f909378d581..5178f3489897 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 	atomic_set(&hdlcd->dma_end_count, 0);
 #endif
 
-	INIT_LIST_HEAD(&hdlcd->event_list);
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
 	if (IS_ERR(hdlcd->mmio)) {
@@ -164,24 +162,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
 		atomic_inc(&hdlcd->vsync_count);
 
 #endif
-	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-		bool events_sent = false;
-		unsigned long flags;
-		struct drm_pending_vblank_event	*e, *t;
-
+	if (irq_status & HDLCD_INTERRUPT_VSYNC)
 		drm_crtc_handle_vblank(&hdlcd->crtc);
 
-		spin_lock_irqsave(&drm->event_lock, flags);
-		list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
-			list_del(&e->base.link);
-			drm_crtc_send_vblank_event(&hdlcd->crtc, e);
-			events_sent = true;
-		}
-		if (events_sent)
-			drm_crtc_vblank_put(&hdlcd->crtc);
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-	}
-
 	/* acknowledge interrupt(s) */
 	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
 
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index aa234784f053..cfd7c73a705e 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -10,7 +10,6 @@ struct hdlcd_drm_private {
 	struct clk			*clk;
 	struct drm_fbdev_cma		*fbdev;
 	struct drm_framebuffer		*fb;
-	struct list_head		event_list;
 	struct drm_crtc			crtc;
 	struct drm_plane		*plane;
 #ifdef CONFIG_DEBUG_FS
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (16 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 17/38] drm/hdlcd: Fix up crtc_state->event handling Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-03 17:43   ` Stefan Agner
  2016-06-01 22:06 ` [PATCH 19/38] drm/hisilicon: " Daniel Vetter
                   ` (20 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Stefan Agner, Daniel Vetter

No idea how exactly fsl-du commits hw state changes, but here in flush
is probably the safest place.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Stefan Agner <stefan@agner.ch>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 89c0084c2814..706de3278f1c 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -22,20 +22,21 @@
 #include "fsl_dcu_drm_drv.h"
 #include "fsl_dcu_drm_plane.h"
 
-static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 					  struct drm_crtc_state *old_crtc_state)
 {
-}
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
-static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
-					 struct drm_crtc_state *state)
-{
-	return 0;
-}
+	if (event) {
+		crtc->state->event = NULL;
 
-static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
-					  struct drm_crtc_state *old_crtc_state)
-{
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
@@ -117,8 +118,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
-	.atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
-	.atomic_check = fsl_dcu_drm_crtc_atomic_check,
 	.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
 	.disable = fsl_dcu_drm_disable_crtc,
 	.enable = fsl_dcu_drm_crtc_enable,
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (17 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-17  2:09   ` Xinliang Liu
  2016-06-01 22:06 ` [PATCH 20/38] drm/sun4i: " Daniel Vetter
                   ` (19 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Archit Taneja, Xinliang Liu, Daniel Vetter,
	Intel Graphics Development, Xinwei Kong, Daniel Vetter

atomic_flush seems to be the right place, but I'm not entirely sure
whether this will catch them all. It could be that when disabling the
crtc we'll miss the vblank.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Xinliang Liu <xinliang.liu@linaro.org>
Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
Cc: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index fba6372d060e..ed76baad525f 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
 	acrtc->enable = false;
 }
 
-static int ade_crtc_atomic_check(struct drm_crtc *crtc,
-				 struct drm_crtc_state *state)
-{
-	/* do nothing */
-	return 0;
-}
-
 static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct ade_crtc *acrtc = to_ade_crtc(crtc);
@@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 {
 	struct ade_crtc *acrtc = to_ade_crtc(crtc);
 	struct ade_hw_ctx *ctx = acrtc->ctx;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 	void __iomem *base = ctx->base;
 
 	/* only crtc is enabled regs take effect */
@@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 		/* flush ade registers */
 		writel(ADE_ENABLE, base + ADE_EN);
 	}
+
+	if (event) {
+		crtc->state->event = NULL;
+
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
 	.enable		= ade_crtc_enable,
 	.disable	= ade_crtc_disable,
-	.atomic_check	= ade_crtc_atomic_check,
 	.mode_set_nofb	= ade_crtc_mode_set_nofb,
 	.atomic_begin	= ade_crtc_atomic_begin,
 	.atomic_flush	= ade_crtc_atomic_flush,
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 20/38] drm/sun4i: Implement some semblance of vblank event handling
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (18 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 19/38] drm/hisilicon: " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 21/38] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Maxime Ripard

atomic_flush seems to be the right place, right after we commit the
plane updates. Again use the fullproof version, since the pipe might
be off.

Cc: Boris Brezillon <boris.brezillon@free-electrons.com>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/sun4i/sun4i_crtc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index 4182a21f5923..f628b6d8f23f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -51,10 +51,22 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
 {
 	struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
 	struct sun4i_drv *drv = scrtc->drv;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
 	DRM_DEBUG_DRIVER("Committing plane changes\n");
 
 	sun4i_backend_commit(drv->backend);
+
+	if (event) {
+		crtc->state->event = NULL;
+
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static void sun4i_crtc_disable(struct drm_crtc *crtc)
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 21/38] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (19 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 20/38] drm/sun4i: " Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 22/38] drm/atomic-helper: nonblocking commit support Daniel Vetter
                   ` (17 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Just a bit of drive-by ocd.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 include/drm/drm_atomic.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index d9504dfcd1cc..465a1212f4f0 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -198,6 +198,13 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (plane_state) = (__state)->planes[__i].state, 1);		\
 	     (__i)++)							\
 		for_each_if (plane_state)
+
+/**
+ * drm_atomic_crtc_needs_modeset - compute combined modeset need
+ * @state: &drm_crtc_state for the CRTC
+ *
+ * This computes the combined need for a modeset for @state.
+ */
 static inline bool
 drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
 {
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 22/38] drm/atomic-helper: nonblocking commit support
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (20 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 21/38] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-02  9:56   ` [PATCH 1/2] drm/atomic: Add struct drm_crtc_commit to track async updates Daniel Vetter
  2016-06-01 22:06 ` [PATCH 23/38] drm/hdlcd: Use helper support for nonblocking commits Daniel Vetter
                   ` (16 subsequent siblings)
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Stone, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Daniel Vetter

Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

v7: Fixup the stalls in swap_state for real!!

v8:
- Fixup trailing whitespace, spotted by Maarten.
- Actually wait for flip_done in cleanup_done, like the comment says
  we should do. Thanks a lot for Tomeu for helping with debugging this
  on.

v9: Now with awesome kerneldoc!

Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Tomeu Vizoso <tomeu.vizoso@gmail.com>
Cc: Daniel Stone <daniels@collabora.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c             |  22 ++
 drivers/gpu/drm/drm_atomic_helper.c      | 475 ++++++++++++++++++++++++++++---
 drivers/gpu/drm/drm_crtc.c               |   3 +
 drivers/gpu/drm/drm_fops.c               |   6 +
 include/drm/drmP.h                       |   1 +
 include/drm/drm_atomic.h                 |   6 +
 include/drm/drm_atomic_helper.h          |   8 +
 include/drm/drm_crtc.h                   | 119 +++++++-
 include/drm/drm_modeset_helper_vtables.h |  39 +++
 9 files changed, 634 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5e4b820a977c..d99ab2f6663f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@
 
 #include "drm_crtc_internal.h"
 
+static void crtc_commit_free(struct kref *kref)
+{
+	struct drm_crtc_commit *commit =
+		container_of(kref, struct drm_crtc_commit, ref);
+
+	kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+	kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 
 		crtc->funcs->atomic_destroy_state(crtc,
 						  state->crtcs[i].state);
+
+		if (state->crtcs[i].commit) {
+			kfree(state->crtcs[i].commit->event);
+			state->crtcs[i].commit->event = NULL;
+			drm_crtc_commit_put(state->crtcs[i].commit);
+		}
+
+		state->crtcs[i].commit = NULL;
 		state->crtcs[i].ptr = NULL;
 		state->crtcs[i].state = NULL;
 	}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 65128f258f84..290318d6f5b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1116,22 +1116,17 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
 
 /**
- * drm_atomic_helper_commit - commit validated state object
- * @dev: DRM device
- * @state: the driver state object
- * @nonblocking: whether nonblocking behavior is requested.
+ * drm_atomic_helper_commit_tail - commit atomic update to hardware
+ * @state: new modeset state to be committed
  *
- * This function commits a with drm_atomic_helper_check() pre-validated state
- * object. This can still fail when e.g. the framebuffer reservation fails. For
- * now this doesn't implement nonblocking commits.
+ * This is the default implemenation for the ->atomic_commit_tail() hook of the
+ * &drm_mode_config_helper_funcs vtable.
  *
- * Note that right now this function does not support nonblocking commits, hence
- * driver writers must implement their own version for now. Also note that the
- * default ordering of how the various stages are called is to match the legacy
- * modeset helper library closest. One peculiarity of that is that it doesn't
- * mesh well with runtime PM at all.
+ * Note that the default ordering of how the various stages are called is to
+ * match the legacy modeset helper library closest. One peculiarity of that is
+ * that it doesn't mesh well with runtime PM at all.
  *
- * For drivers supporting runtime PM the recommended sequence is
+ * For drivers supporting runtime PM the recommended sequence is instead ::
  *
  *     drm_atomic_helper_commit_modeset_disables(dev, state);
  *
@@ -1139,7 +1134,73 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  *
  *     drm_atomic_helper_commit_planes(dev, state, true);
  *
- * See the kerneldoc entries for these three functions for more details.
+ * for committing the atomic update to hardware.  See the kerneldoc entries for
+ * these three functions for more details.
+ */
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, false);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_hw_done(state);
+
+	drm_atomic_helper_wait_for_vblanks(dev, state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+
+void commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config_helper_funcs *funcs;
+
+	funcs = dev->mode_config.helper_private;
+
+	drm_atomic_helper_wait_for_fences(dev, state);
+
+	drm_atomic_helper_wait_for_dependencies(state);
+
+	if (funcs && funcs->atomic_commit_tail)
+		funcs->atomic_commit_tail(state);
+	else
+		drm_atomic_helper_commit_tail(state);
+
+	drm_atomic_helper_commit_cleanup_done(state);
+
+	drm_atomic_state_free(state);
+}
+
+static void commit_work(struct work_struct *work)
+{
+	struct drm_atomic_state *state = container_of(work,
+						      struct drm_atomic_state,
+						      commit_work);
+	commit_tail(state);
+}
+
+/**
+ * drm_atomic_helper_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the driver state object
+ * @nonblock: whether nonblocking behavior is requested.
+ *
+ * This function commits a with drm_atomic_helper_check() pre-validated state
+ * object. This can still fail when e.g. the framebuffer reservation fails. This
+ * function implements nonblocking commits, using
+ * drm_atomic_helper_setup_commit() and related functions.
+ *
+ * Note that right now this function does not support nonblocking commits, hence
+ * driver writers must implement their own version for now.
+ *
+ * Committing the actual hardware state is done through the
+ * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable,
+ * or it's default implementation drm_atomic_helper_commit_tail().
  *
  * RETURNS
  * Zero for success or -errno.
@@ -1150,8 +1211,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&state->commit_work, commit_work);
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
@@ -1179,21 +1243,16 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * update. Which is important since compositors need to figure out the
 	 * composition of the next frame right after having submitted the
 	 * current layout.
+	 *
+	 * NOTE: Commit work has multiple phases, first hardware commit, then
+	 * cleanup. We want them to overlap, hence need system_unbound_wq to
+	 * make sure work items don't artifically stall on each another.
 	 */
 
-	drm_atomic_helper_wait_for_fences(dev, state);
-
-	drm_atomic_helper_commit_modeset_disables(dev, state);
-
-	drm_atomic_helper_commit_planes(dev, state, false);
-
-	drm_atomic_helper_commit_modeset_enables(dev, state);
-
-	drm_atomic_helper_wait_for_vblanks(dev, state);
-
-	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
+	if (nonblock)
+		queue_work(system_unbound_wq, &state->commit_work);
+	else
+		commit_tail(state);
 
 	return 0;
 }
@@ -1202,12 +1261,7 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
 /**
  * DOC: implementing nonblocking commit
  *
- * For now the atomic helpers don't support nonblocking commit directly. If
- * there is real need it could be added though, using the dma-buf fence
- * infrastructure for generic synchronization with outstanding rendering.
- *
- * For now drivers have to implement nonblocking commit themselves, with the
- * following sequence being the recommended one:
+ * Nonblocking atomic commits have to be implemented in the following sequence:
  *
  * 1. Run drm_atomic_helper_prepare_planes() first. This is the only function
  * which commit needs to call which can fail, so we want to run it first and
@@ -1219,10 +1273,14 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * cancelled updates. Note that it is important to ensure that the framebuffer
  * cleanup is still done when cancelling.
  *
- * For sufficient parallelism it is recommended to have a work item per crtc
- * (for updates which don't touch global state) and a global one. Then we only
- * need to synchronize with the crtc work items for changed crtcs and the global
- * work item, which allows nice concurrent updates on disjoint sets of crtcs.
+ * Asynchronous workers need to have sufficient parallelism to be able to run
+ * different atomic commits on different CRTCs in parallel. The simplest way to
+ * achive this is by running them on the &system_unbound_wq work queue. Note
+ * that drivers are not required to split up atomic commits and run an
+ * individual commit in parallel - userspace is supposed to do that if it cares.
+ * But it might be beneficial to do that for modesets, since those necessarily
+ * must be done as one global operation, and enabling or disabling a CRTC can
+ * take a long time. But even that is not required.
  *
  * 3. The software state is updated synchronously with
  * drm_atomic_helper_swap_state(). Doing this under the protection of all modeset
@@ -1235,7 +1293,309 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * commit helpers: a) pre-plane commit b) plane commit c) post-plane commit and
  * then cleaning up the framebuffers after the old framebuffer is no longer
  * being displayed.
+ *
+ * The above scheme is implemented in the atomic helper libraries in
+ * drm_atomic_helper_commit() using a bunch of helper functions. See
+ * drm_atomic_helper_setup_commit() for a starting point.
+ */
+
+static int stall_checks(struct drm_crtc *crtc, bool nonblock)
+{
+	struct drm_crtc_commit *commit, *stall_commit = NULL;
+	bool completed = true;
+	int i, ret = 0;
+
+	spin_lock(&crtc->commit_lock);
+	i = 0;
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		if (i == 0) {
+			completed = try_wait_for_completion(&commit->flip_done);
+			/* Userspace is not allowed to get ahead of the previous
+			 * commit with nonblocking ones. */
+			if (!completed && nonblock) {
+				spin_unlock(&crtc->commit_lock);
+				return -EBUSY;
+			}
+		} else if (i == 1) {
+			stall_commit = commit;
+			drm_crtc_commit_get(stall_commit);
+		} else
+			break;
+
+		i++;
+	}
+	spin_unlock(&crtc->commit_lock);
+
+	if (!stall_commit)
+		return 0;
+
+	/* We don't want to let commits get ahead of cleanup work too much,
+	 * stalling on 2nd previous commit means triple-buffer won't ever stall.
+	 */
+	ret = wait_for_completion_interruptible_timeout(&commit->cleanup_done,
+							10*HZ);
+	if (ret == 0)
+		DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
+			  crtc->base.id, crtc->name);
+
+	if (ret == -ERESTARTSYS)
+		ret = -EINTR;
+
+	drm_crtc_commit_put(stall_commit);
+
+	return ret;
+}
+
+/**
+ * drm_atomic_helper_setup_commit - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ * @nonblock: whether nonblocking behavior is requested.
+ *
+ * This function prepares @state to be used by the atomic helper's support for
+ * nonblocking commits. Drivers using the nonblocking commit infrastructure
+ * should always call this function from their ->atomic_commit hook.
+ *
+ * To be able to use this support drivers need to use a few more helper
+ * functions. drm_atomic_helper_wait_for_dependencies() must be called before
+ * actually committing the hardware state, and for nonblocking commits this call
+ * must be placed in the async worker. See also drm_atomic_helper_swap_state()
+ * and it's stall parameter, for when a driver's commit hooks look at the
+ * ->state pointers of struct &drm_crtc, &drm_plane or &drm_connector directly.
+ *
+ * Completion of the hardware commit step must be signalled using
+ * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed
+ * to read or change any permanent software or hardware modeset state. The only
+ * exception is state protected by other means than &drm_modeset_lock locks.
+ * Only the free standing @state with pointers to the old state structures can
+ * be inspected, e.g. to clean up old buffers using
+ * drm_atomic_helper_cleanup_planes().
+ *
+ * At the very end, before cleaning up @state drivers must call
+ * drm_atomic_helper_commit_cleanup_done().
+ *
+ * This is all implemented by in drm_atomic_helper_commit(), giving drivers a
+ * complete and esay-to-use default implementation of the atomic_commit() hook.
+ *
+ * The tracking of asynchronously executed and still pending commits is done
+ * using the core structure &drm_crtc_commit.
+ *
+ * Returns:
+ *
+ * 0 on success. -EBUSY when userspace schedules nonblocking commits too fast,
+ * -ENOMEM on allocation failures and -EINTR when a signal is pending.
+ */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i, ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+		if (!commit)
+			return -ENOMEM;
+
+		init_completion(&commit->flip_done);
+		init_completion(&commit->hw_done);
+		init_completion(&commit->cleanup_done);
+		INIT_LIST_HEAD(&commit->commit_entry);
+		kref_init(&commit->ref);
+		commit->crtc = crtc;
+
+		state->crtcs[i].commit = commit;
+
+		ret = stall_checks(crtc, nonblock);
+		if (ret)
+			return ret;
+
+		/* Drivers only send out events when at least either current or
+		 * new CRTC state is active. Complete right away if everything
+		 * stays off. */
+		if (!crtc->state->active && !crtc_state->active) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		/* Legacy cursor updates are fully unsynced. */
+		if (state->legacy_cursor_update) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		if (!crtc_state->event) {
+			commit->event = kzalloc(sizeof(*commit->event),
+						GFP_KERNEL);
+			if (!commit->event)
+				return -ENOMEM;
+
+			crtc_state->event = commit->event;
+		}
+
+		crtc_state->event->base.completion = &commit->flip_done;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
+
+
+static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_commit *commit;
+	int i = 0;
+
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		/* skip the first entry, that's the current commit */
+		if (i == 1)
+			return commit;
+		i++;
+	}
+
+	return NULL;
+}
+
+/**
+ * drm_atomic_helper_wait_for_dependencies - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This function waits for all preceeding commits that touch the same CRTC as
+ * @state to both be committed to the hardware (as signalled by
+ * drm_atomic_Helper_commit_hw_done) and executed by the hardware (as signalled
+ * by calling drm_crtc_vblank_send_event on the event member of
+ * &drm_crtc_state).
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		spin_lock(&crtc->commit_lock);
+		commit = preceeding_commit(crtc);
+		if (commit)
+			drm_crtc_commit_get(commit);
+		spin_unlock(&crtc->commit_lock);
+
+		if (!commit)
+			continue;
+
+		ret = wait_for_completion_timeout(&commit->hw_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		/* Currently no support for overwriting flips, hence
+		 * stall for previous one to execute completely. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		drm_crtc_commit_put(commit);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
+
+/**
+ * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This function is used to signal completion of the hardware commit step. After
+ * this step the driver is not allowed to read or change any permanent software
+ * or hardware modeset state. The only exception is state protected by other
+ * means than &drm_modeset_lock locks.
+ *
+ * Drivers should try to postpone any expensive or delayed cleanup work after
+ * this function is called.
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
  */
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+
+		/* backend must have consumed any event by now */
+		WARN_ON(crtc->state->event);
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->hw_done);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
+
+/**
+ * drm_atomic_helper_wait_for_dependencies - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This signals completion of the atomic update @state, including any cleanup
+ * work. If used, it must be called right before calling
+ * drm_atomic_state_free().
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (WARN_ON(!commit))
+			continue;
+
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->cleanup_done);
+		WARN_ON(!try_wait_for_completion(&commit->hw_done));
+
+		/* commit_list borrows our reference, need to remove before we
+		 * clean up our drm_atomic_state. But only after it actually
+		 * completed, otherwise subsequent commits won't stall properly. */
+		if (try_wait_for_completion(&commit->flip_done)) {
+			list_del(&commit->commit_entry);
+			spin_unlock(&crtc->commit_lock);
+			continue;
+		}
+
+		spin_unlock(&crtc->commit_lock);
+
+		/* We must wait for the vblank event to signal our completion
+		 * before releasing our reference, since the vblank work does
+		 * not hold a reference of its own. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		spin_lock(&crtc->commit_lock);
+		list_del(&commit->commit_entry);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
 
 /**
  * drm_atomic_helper_prepare_planes - prepare plane resources before commit
@@ -1556,17 +1916,45 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  *
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
+ *
+ * @stall must be set when nonblocking commits for this driver directly access
+ * the ->state pointer of &drm_plane, &drm_crtc or &drm_connector. With the
+ * current atomic helpers this is almost always the case, since the helpers
+ * don't pass the right state structures to the callbacks.
  */
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall)
 {
 	int i;
+	long ret;
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_plane *plane;
 	struct drm_plane_state *plane_state;
+	struct drm_crtc_commit *commit;
+
+	if (stall) {
+		for_each_crtc_in_state(state, crtc, crtc_state, i) {
+			spin_lock(&crtc->commit_lock);
+			commit = list_first_entry_or_null(&crtc->commit_list,
+					struct drm_crtc_commit, commit_entry);
+			if (commit)
+				drm_crtc_commit_get(commit);
+			spin_unlock(&crtc->commit_lock);
+
+			if (!commit)
+				continue;
+
+			ret = wait_for_completion_timeout(&commit->hw_done,
+							  10*HZ);
+			if (ret == 0)
+				DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+					  crtc->base.id, crtc->name);
+			drm_crtc_commit_put(commit);
+		}
+	}
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
@@ -1578,6 +1966,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 		crtc->state->state = state;
 		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
+
+		if (state->crtcs[i].commit) {
+			spin_lock(&crtc->commit_lock);
+			list_add(&state->crtcs[i].commit->commit_entry,
+				 &crtc->commit_list);
+			spin_unlock(&crtc->commit_lock);
+
+			state->crtcs[i].commit->event = NULL;
+		}
 	}
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1cb3b471aadc..1f14c6565210 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -669,6 +669,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 	crtc->dev = dev;
 	crtc->funcs = funcs;
 
+	INIT_LIST_HEAD(&crtc->commit_list);
+	spin_lock_init(&crtc->commit_lock);
+
 	drm_modeset_lock_init(&crtc->mutex);
 	ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 	if (ret)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 4c4b30f7a9f2..5921b203503a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -686,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->completion) {
+		/* ->completion might disappear as soon as it signalled. */
+		complete_all(e->completion);
+		e->completion = NULL;
+	}
+
 	if (e->fence) {
 		fence_signal(e->fence);
 		fence_put(e->fence);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 51f751d1c8a4..781db4f562d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {
+	struct completion *completion;
 	struct drm_event *event;
 	struct fence *fence;
 	struct list_head link;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 465a1212f4f0..abec2a3f0225 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,12 @@
 
 #include <drm/drm_crtc.h>
 
+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
+static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+	kref_get(&commit->ref);
+}
+
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 0276447225ed..5fb8c306e16b 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -38,6 +38,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
 			       struct drm_atomic_state *state);
 int drm_atomic_helper_check(struct drm_device *dev,
 			    struct drm_atomic_state *state);
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
 int drm_atomic_helper_commit(struct drm_device *dev,
 			     struct drm_atomic_state *state,
 			     bool nonblock);
@@ -74,6 +75,13 @@ void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall);
 
+/* nonblocking commit helpers */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock);
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
+
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
 				   struct drm_crtc *crtc,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d5d5e343531e..c0edd87fa0ee 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -725,9 +725,6 @@ struct drm_crtc_funcs {
  * @gamma_store: gamma ramp values
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
- * @state: current atomic state for this CRTC
- * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
- * 	legacy IOCTLs
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -780,11 +777,37 @@ struct drm_crtc {
 
 	struct drm_object_properties properties;
 
+	/**
+	 * @state:
+	 *
+	 * Current atomic state for this CRTC.
+	 */
 	struct drm_crtc_state *state;
 
-	/*
-	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
-	 * acquire context.
+	/**
+	 * @commit_list:
+	 *
+	 * List of &drm_crtc_commit structures tracking pending commits.
+	 * Protected by @commit_lock. This list doesn't hold its own full
+	 * reference, but burrows it from the ongoing commit. Commit entries
+	 * must be removed from this list once the commit is fully completed,
+	 * but before it's correspoding &drm_atomic_state gets destroyed.
+	 */
+	struct list_head commit_list;
+
+	/**
+	 * @commit_lock:
+	 *
+	 * Spinlock to protect @commit_list.
+	 */
+	spinlock_t commit_lock;
+
+	/**
+	 * @acquire_ctx:
+	 *
+	 * Per-CRTC implicit acquire context used by atomic drivers for legacy
+	 * IOCTLs, so that atomic drivers can get at the locking acquire
+	 * context.
 	 */
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
@@ -1694,6 +1717,78 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+/**
+ * struct drm_crtc_commit - track modeset commits on a CRTC
+ */
+struct drm_crtc_commit {
+	/**
+	 * @crtc:
+	 *
+	 * DRM CRTC for this commit.
+	 */
+	struct drm_crtc *crtc;
+
+	/**
+	 * @ref:
+	 *
+	 * Reference count for this structure. Needed to allow blocking on
+	 * completions without the risk of the completion disappearing
+	 * meanwhile.
+	 */
+	struct kref ref;
+
+	/**
+	 * @flip_done:
+	 *
+	 * Will be signaled when the hardware has flipped to the new set of
+	 * buffers. Signals at the same time as when the drm event for this
+	 * commit is sent to userspace, or when an out-fence is singalled. Note
+	 * that for most hardware, in most cases this happens after @hw_done is
+	 * signalled.
+	 */
+	struct completion flip_done;
+
+	/**
+	 * @hw_done:
+	 *
+	 * Will be signalled when all hw register changes for this commit have
+	 * been written out. Especially when disabling a pipe this can be much
+	 * later than than @flip_done, since that can signal already when the
+	 * screen goes black, whereas to fully shut down a pipe more register
+	 * I/O is required.
+	 *
+	 * Note that this does not need to include separately reference-counted
+	 * resources like backing storage buffer pinning, or runtime pm
+	 * management.
+	 */
+	struct completion hw_done;
+
+	/**
+	 * cleanup_done:
+	 *
+	 * Will be signalled after old buffers have been cleaned up again by
+	 * calling drm_atomic_helper_cleanup_planes(). Since this can only
+	 * happen after a vblank wait completed it might be a bit later. This
+	 * completion is useful to throttle updates and avoid hardware updates
+	 * getting ahead of the buffer cleanup too much.
+	 */
+	struct completion cleanup_done;
+
+	/**
+	 * @commit_entry:
+	 *
+	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
+	 */
+	struct list_head commit_entry;
+
+	/**
+	 * @event:
+	 *
+	 * &drm_pending_vblank_event pointer to clean up private events.
+	 */
+	struct drm_pending_vblank_event *event;
+};
+
 struct __drm_planes_state {
 	struct drm_plane *ptr;
 	struct drm_plane_state *state;
@@ -1702,6 +1797,7 @@ struct __drm_planes_state {
 struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
+	struct drm_crtc_commit *commit;
 };
 
 struct __drm_connnectors_state {
@@ -1733,6 +1829,14 @@ struct drm_atomic_state {
 	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
+
+	/**
+	 * @commit_work:
+	 *
+	 * Work item which can be used by the driver or helpers to execute the
+	 * commit without blocking.
+	 */
+	struct work_struct commit_work;
 };
 
 
@@ -2074,6 +2178,7 @@ struct drm_mode_config_funcs {
  * @async_page_flip: does this device support async flips on the primary plane?
  * @cursor_width: hint to userspace for max cursor width
  * @cursor_height: hint to userspace for max cursor height
+ * @helper_private: mid-layer private data
  *
  * Core mode resource tracking structure.  All CRTC, encoders, and connectors
  * enumerated by the driver are added here, as are global properties.  Some
@@ -2193,6 +2298,8 @@ struct drm_mode_config {
 
 	/* cursor size */
 	uint32_t cursor_width, cursor_height;
+
+	struct drm_mode_config_helper_funcs *helper_private;
 };
 
 /**
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index d4619dc2eecb..4723fb96bc1a 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -925,4 +925,43 @@ static inline void drm_plane_helper_add(struct drm_plane *plane,
 	plane->helper_private = funcs;
 }
 
+/**
+ * struct drm_mode_config_helper_funcs - global modeset helper operations
+ *
+ * These helper functions are used by the atomic helpers.
+ */
+struct drm_mode_config_helper_funcs {
+	/**
+	 * @atomic_commit_tail:
+	 *
+	 * This hook is used by the default atomic_commit() hook implemented in
+	 * drm_atomic_helper_commit() together with the nonblocking commit
+	 * helpers (see drm_atomic_helper_setup_commit() for a starting point)
+	 * to implement blocking and nonblocking commits easily. It is not used
+	 * by the atomic helpers
+	 *
+	 * This hook should first commit the given atomic state to the hardware.
+	 * But drivers can add more waiting calls at the start of their
+	 * implementation, e.g. to wait for driver-internal request for implicit
+	 * syncing, before starting to commit the update to the hardware.
+	 *
+	 * After the atomic update is committed to the hardware this hook needs
+	 * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate
+	 * to be executed by the hardware, for example using
+	 * drm_atomic_helper_wait_for_vblanks(), and then clean up the old
+	 * framebuffers using drm_atomic_helper_cleanup_planes().
+	 *
+	 * When disabling a CRTC this hook _must_ stall for the commit to
+	 * complete. Vblank waits don't work on disabled CRTC, hence the core
+	 * can't take care of this. And it also can't rely on the vblank event,
+	 * since that can be signalled already when the screen shows black,
+	 * which can happen much earlier than the last hardware access needed to
+	 * shut off the display pipeline completely.
+	 *
+	 * This hook is optional, the default implementation is
+	 * drm_atomic_helper_commit_tail().
+	 */
+	void (*atomic_commit_tail)(struct drm_atomic_state *state);
+};
+
 #endif
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 23/38] drm/hdlcd: Use helper support for nonblocking commits
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (21 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 22/38] drm/atomic-helper: nonblocking commit support Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06   ` Daniel Vetter
                   ` (15 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau, Daniel Vetter

With the fixed up drm event handling for crtc_state->event we can just
use the helper support for nonblocking commits.

Cc: Liviu Dudau <Liviu.Dudau@arm.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 5178f3489897..9fd7321de838 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -110,17 +110,11 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
 		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
 }
 
-static int hdlcd_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state, bool nonblock)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
 	.fb_create = drm_fb_cma_create,
 	.output_poll_changed = hdlcd_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = hdlcd_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void hdlcd_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 24/38] drm/arc: Implement nonblocking commit correctly
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
@ 2016-06-01 22:06   ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (37 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: linux-snps-arc

Committing with block it is not.

Thanks to the fixed up vblank event handling we can just use the
helper support for nonblocking commits now.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d407fd79a400..a92e533531c3 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
 		drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
 }
 
-static int arcpgu_atomic_commit(struct drm_device *dev,
-				    struct drm_atomic_state *state, bool async)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
 	.fb_create  = drm_fb_cma_create,
 	.output_poll_changed = arcpgu_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = arcpgu_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void arcpgu_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 24/38] drm/arc: Implement nonblocking commit correctly
@ 2016-06-01 22:06   ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

Committing with block it is not.

Thanks to the fixed up vblank event handling we can just use the
helper support for nonblocking commits now.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d407fd79a400..a92e533531c3 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
 		drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
 }
 
-static int arcpgu_atomic_commit(struct drm_device *dev,
-				    struct drm_atomic_state *state, bool async)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
 	.fb_create  = drm_fb_cma_create,
 	.output_poll_changed = arcpgu_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = arcpgu_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void arcpgu_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 25/38] drm/i915: Signal drm events for atomic
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (23 preceding siblings ...)
  2016-06-01 22:06   ` Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 26/38] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

This is part of what atomic must implement. And it's also required
to be able to use the helper nonblocking support.

v2: Always send out the drm event, remove the planes_changed check.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 13 ++++++++++---
 drivers/gpu/drm/i915/intel_sprite.c  | 14 ++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a59cc0e2e5ca..0618916f825b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13797,13 +13797,21 @@ static int intel_atomic_commit(struct drm_device *dev,
 		bool modeset = needs_modeset(crtc->state);
 		struct intel_crtc_state *pipe_config =
 			to_intel_crtc_state(crtc->state);
-		bool update_pipe = !modeset && pipe_config->update_pipe;
 
 		if (modeset && crtc->state->active) {
 			update_scanline_offset(to_intel_crtc(crtc));
 			dev_priv->display.crtc_enable(crtc);
 		}
 
+		/* Complete events for now disable pipes here. */
+		if (modeset && !crtc->state->active && crtc->state->event) {
+			spin_lock_irq(&dev->event_lock);
+			drm_crtc_send_vblank_event(crtc, crtc->state->event);
+			spin_unlock_irq(&dev->event_lock);
+
+			crtc->state->event = NULL;
+		}
+
 		if (!modeset)
 			intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
 
@@ -13811,8 +13819,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 		    drm_atomic_get_existing_plane_state(state, crtc->primary))
 			intel_fbc_enable(intel_crtc);
 
-		if (crtc->state->active &&
-		    (crtc->state->planes_changed || update_pipe))
+		if (crtc->state->active)
 			drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
 
 		if (pipe_config->base.active && needs_vblank_wait(pipe_config))
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 324ccb06397d..fc654173c491 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -166,6 +166,20 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
 
 	trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
 
+	/* We're still in the vblank-evade critical section, this can't race.
+	 * Would be slightly nice to just grab the vblank count and arm the
+	 * event outside of the critical section - the spinlock might spin for a
+	 * while ... */
+	if (crtc->base.state->event) {
+		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
+
+		spin_lock(&crtc->base.dev->event_lock);
+		drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event);
+		spin_unlock(&crtc->base.dev->event_lock);
+
+		crtc->base.state->event = NULL;
+	}
+
 	local_irq_enable();
 
 	if (crtc->debug.start_vbl_count &&
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 26/38] drm/i915: Roll out the helper nonblock tracking
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (24 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 25/38] drm/i915: Signal drm events for atomic Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 27/38] drm/i915: nonblocking commit Daniel Vetter
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Right now still all blocking, no worker anywhere to be seen.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0618916f825b..77ff0903540d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13720,6 +13720,10 @@ static int intel_atomic_commit(struct drm_device *dev,
 	unsigned long put_domains[I915_MAX_PIPES] = {};
 	unsigned crtc_vblank_mask = 0;
 
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
 	ret = intel_atomic_prepare_commit(dev, state, nonblock);
 	if (ret) {
 		DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
@@ -13731,6 +13735,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
 
+	drm_atomic_helper_wait_for_dependencies(state);
+
 	if (intel_state->modeset) {
 		memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
 		       sizeof(intel_state->min_pixclk));
@@ -13826,7 +13832,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 			crtc_vblank_mask |= 1 << i;
 	}
 
-	/* FIXME: add subpixel order */
+	drm_atomic_helper_commit_hw_done(state);
 
 	if (!state->legacy_cursor_update)
 		intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
@@ -13861,6 +13867,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, state);
 	mutex_unlock(&dev->struct_mutex);
 
+	drm_atomic_helper_commit_cleanup_done(state);
+
 	drm_atomic_state_free(state);
 
 	/* As one of the primary mmio accessors, KMS has a high likelihood
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 27/38] drm/i915: nonblocking commit
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (25 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 26/38] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 28/38] drm/i915: Use atomic commits for legacy page_flips Daniel Vetter
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Simply split intel_atomic_commit in half and place the new
nonblocking commit helpers at the right spots.

NOTE: There's still trouble with obj->frontbuffer bits getting mangled
when pipelining atomic commits.

v2:
- Remove the check for nonblocking which returned -EINVAL.
- Do wait for requests in the worker thread before committing
  hw state.

v3: Move hw_done after the optimize_wm/post_plane_update step, plus
add FIXME comment how to fix that up again properly.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 121 ++++++++++++++++++++++++-----------
 1 file changed, 82 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 77ff0903540d..75aa6d90eb13 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13567,11 +13567,6 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
 	struct drm_crtc *crtc;
 	int i, ret;
 
-	if (nonblock) {
-		DRM_DEBUG_KMS("i915 does not yet support nonblocking commit\n");
-		return -EINVAL;
-	}
-
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (state->legacy_cursor_update)
 			continue;
@@ -13690,50 +13685,34 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
 	return false;
 }
 
-/**
- * intel_atomic_commit - commit validated state object
- * @dev: DRM device
- * @state: the top-level driver state object
- * @nonblock: nonblocking commit
- *
- * This function commits a top-level state object that has been validated
- * with drm_atomic_helper_check().
- *
- * FIXME:  Atomic modeset support for i915 is not yet complete.  At the moment
- * we can only handle plane-related operations and do not yet support
- * nonblocking commit.
- *
- * RETURNS
- * Zero for success or -errno.
- */
-static int intel_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool nonblock)
+static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 {
+	struct drm_device *dev = state->dev;
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc_state *old_crtc_state;
 	struct drm_crtc *crtc;
 	struct intel_crtc_state *intel_cstate;
-	int ret = 0, i;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 	bool hw_check = intel_state->modeset;
 	unsigned long put_domains[I915_MAX_PIPES] = {};
 	unsigned crtc_vblank_mask = 0;
+	int i, ret;
 
-	ret = drm_atomic_helper_setup_commit(state, nonblock);
-	if (ret)
-		return ret;
+	for_each_plane_in_state(state, plane, plane_state, i) {
+		struct intel_plane_state *intel_plane_state =
+			to_intel_plane_state(plane_state);
 
-	ret = intel_atomic_prepare_commit(dev, state, nonblock);
-	if (ret) {
-		DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
-		return ret;
-	}
+		if (!intel_plane_state->wait_req)
+			continue;
 
-	drm_atomic_helper_swap_state(state, true);
-	dev_priv->wm.distrust_bios_wm = false;
-	dev_priv->wm.skl_results = intel_state->wm_results;
-	intel_shared_dpll_commit(state);
+		ret = __i915_wait_request(intel_plane_state->wait_req,
+					  true, NULL, NULL);
+		/* EIO should be eaten, and we can't get interrupted in the
+		 * worker, and blocking commits have waited already. */
+		WARN_ON(ret);
+	}
 
 	drm_atomic_helper_wait_for_dependencies(state);
 
@@ -13832,8 +13811,15 @@ static int intel_atomic_commit(struct drm_device *dev,
 			crtc_vblank_mask |= 1 << i;
 	}
 
-	drm_atomic_helper_commit_hw_done(state);
-
+	/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
+	 * already, but still need the state for the delayed optimization. To
+	 * fix this:
+	 * - wrap the optimization/post_plane_update stuff into a per-crtc work.
+	 * - schedule that vblank worker _before_ calling hw_done
+	 * - at the start of commit_tail, cancel it _synchrously
+	 * - switch over to the vblank wait helper in the core after that since
+	 *   we don't need out special handling any more.
+	 */
 	if (!state->legacy_cursor_update)
 		intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
 
@@ -13860,6 +13846,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 		intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
 	}
 
+	drm_atomic_helper_commit_hw_done(state);
+
 	if (intel_state->modeset)
 		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
 
@@ -13883,6 +13871,61 @@ static int intel_atomic_commit(struct drm_device *dev,
 	 * can happen also when the device is completely off.
 	 */
 	intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
+}
+
+static void intel_atomic_commit_work(struct work_struct *work)
+{
+	struct drm_atomic_state *state = container_of(work,
+						      struct drm_atomic_state,
+						      commit_work);
+	intel_atomic_commit_tail(state);
+}
+
+/**
+ * intel_atomic_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the top-level driver state object
+ * @nonblock: nonblocking commit
+ *
+ * This function commits a top-level state object that has been validated
+ * with drm_atomic_helper_check().
+ *
+ * FIXME:  Atomic modeset support for i915 is not yet complete.  At the moment
+ * we can only handle plane-related operations and do not yet support
+ * nonblocking commit.
+ *
+ * RETURNS
+ * Zero for success or -errno.
+ */
+static int intel_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool nonblock)
+{
+	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret = 0;
+
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&state->commit_work, intel_atomic_commit_work);
+
+	ret = intel_atomic_prepare_commit(dev, state, nonblock);
+	if (ret) {
+		DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
+		return ret;
+	}
+
+	drm_atomic_helper_swap_state(state, true);
+	dev_priv->wm.distrust_bios_wm = false;
+	dev_priv->wm.skl_results = intel_state->wm_results;
+	intel_shared_dpll_commit(state);
+
+	if (nonblock)
+		queue_work(system_unbound_wq, &state->commit_work);
+	else
+		intel_atomic_commit_tail(state);
 
 	return 0;
 }
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 28/38] drm/i915: Use atomic commits for legacy page_flips
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (26 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 27/38] drm/i915: nonblocking commit Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 29/38] drm/i915: Move fb_bits updating later in atomic_commit Daniel Vetter
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Note that I didn't start garbage collecting all the legacy flip code
yet, to make it easier to revert this. But there will be _lots_ of
code that can be removed once this is tested on all platforms.

FIXME: obj->frontbuffer_bits gets out of whack when pipelining
commits too hard.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 75aa6d90eb13..14fd10ec1bbf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11642,6 +11642,7 @@ void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
 	spin_unlock(&dev->event_lock);
 }
 
+__attribute__((unused))
 static int intel_crtc_page_flip(struct drm_crtc *crtc,
 				struct drm_framebuffer *fb,
 				struct drm_pending_vblank_event *event,
@@ -13975,7 +13976,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
 	.set_config = drm_atomic_helper_set_config,
 	.set_property = drm_atomic_helper_crtc_set_property,
 	.destroy = intel_crtc_destroy,
-	.page_flip = intel_crtc_page_flip,
+	.page_flip = drm_atomic_helper_page_flip,
 	.atomic_duplicate_state = intel_crtc_duplicate_state,
 	.atomic_destroy_state = intel_crtc_destroy_state,
 };
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 29/38] drm/i915: Move fb_bits updating later in atomic_commit
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (27 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 28/38] drm/i915: Use atomic commits for legacy page_flips Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 30/38] drm/rockchip: Disarm vop->is_enabled Daniel Vetter
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Currently it's part of prepare_fb, still in the first phase of
atomic_commit which might fail. Which means that we need to have some
heuristics in cleanup_fb to figure out whether things failed, or
whether we just clean up the old fbs.

That's fragile, and worse, once we start pipelining commits gets
confused: While the last commit is still getting cleanup up we already
hammer in the new one, and fb_bits aren't refcounted, resulting in
lost bits and WARN_ON galore. We could instead try to make cleanup_fb
more clever, but a simpler fix is to postpone the fb_bits tracking
past the point of no return, where we commit all the software state.

That also makes conceptually more sense, since fb_bits must be updated
synchronously from the ioctl (they track usage from userspace pov, not
from the hw pov), right before we're fully committed to the updated.

This fixes WARNING splats from track_fb with page_flip implemented
through atomic_commit.

Testcase: igt/kms_flip/flip-vs-rmfb
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 41 ++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 14fd10ec1bbf..adf80029ab64 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13882,6 +13882,25 @@ static void intel_atomic_commit_work(struct work_struct *work)
 	intel_atomic_commit_tail(state);
 }
 
+static void intel_atomic_track_fbs(struct drm_atomic_state *state)
+{
+	struct drm_plane_state *old_plane_state;
+	struct drm_plane *plane;
+	struct drm_i915_gem_object *obj, *old_obj;
+	struct intel_plane *intel_plane;
+	int i;
+
+	mutex_lock(&state->dev->struct_mutex);
+	for_each_plane_in_state(state, plane, old_plane_state, i) {
+		obj = intel_fb_obj(plane->state->fb);
+		old_obj = intel_fb_obj(old_plane_state->fb);
+		intel_plane = to_intel_plane(plane);
+
+		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+	}
+	mutex_unlock(&state->dev->struct_mutex);
+}
+
 /**
  * intel_atomic_commit - commit validated state object
  * @dev: DRM device
@@ -13922,6 +13941,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 	dev_priv->wm.distrust_bios_wm = false;
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
+	intel_atomic_track_fbs(state);
 
 	if (nonblock)
 		queue_work(system_unbound_wq, &state->commit_work);
@@ -14001,7 +14021,6 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct drm_framebuffer *fb = new_state->fb;
-	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
 	int ret = 0;
@@ -14058,16 +14077,12 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
 	}
 
-	if (ret == 0) {
-		if (obj) {
-			struct intel_plane_state *plane_state =
-				to_intel_plane_state(new_state);
-
-			i915_gem_request_assign(&plane_state->wait_req,
-						obj->last_write_req);
-		}
+	if (ret == 0 && obj) {
+		struct intel_plane_state *plane_state =
+			to_intel_plane_state(new_state);
 
-		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
+		i915_gem_request_assign(&plane_state->wait_req,
+					obj->last_write_req);
 	}
 
 	return ret;
@@ -14087,7 +14102,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 		       const struct drm_plane_state *old_state)
 {
 	struct drm_device *dev = plane->dev;
-	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct intel_plane_state *old_intel_state;
 	struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
 	struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
@@ -14101,11 +14115,6 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 	    !INTEL_INFO(dev)->cursor_needs_physical))
 		intel_unpin_fb_obj(old_state->fb, old_state->rotation);
 
-	/* prepare_fb aborted? */
-	if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
-	    (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
-		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
-
 	i915_gem_request_assign(&old_intel_state->wait_req, NULL);
 }
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 30/38] drm/rockchip: Disarm vop->is_enabled
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (28 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 29/38] drm/i915: Move fb_bits updating later in atomic_commit Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 31/38] drm/rockchip: Fix crtc_state->event signalling Daniel Vetter
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomeu Vizoso, Mark yao

With atomic helpers there's no need to track the enabled state of a pipe
any more, because atomic helpers track this accurately already.

Just disable the early returns, since the debug checks might be useful.

v2: Don't call drm_helper_disable_unused_functions, it blows up
without this check. At least explains why rockchip still needed this
old legacy-style state tracing - to work around issues from calling
other legacy style functions!

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 3 ---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c   | 6 ------
 2 files changed, 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
index f261512bb4a0..245a567f7b8c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
@@ -156,9 +156,6 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
 		goto err_drm_fb_helper_fini;
 	}
 
-	/* disable all the possible outputs/crtcs before entering KMS mode */
-	drm_helper_disable_unused_functions(dev);
-
 	ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
 	if (ret < 0) {
 		dev_err(dev->dev, "Failed to set initial hw config - %d.\n",
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5567fb43e674..957a6b4917c8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -431,9 +431,6 @@ static void vop_enable(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	int ret;
 
-	if (vop->is_enabled)
-		return;
-
 	ret = pm_runtime_get_sync(vop->dev);
 	if (ret < 0) {
 		dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
@@ -501,9 +498,6 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	int i;
 
-	if (!vop->is_enabled)
-		return;
-
 	/*
 	 * We need to make sure that all windows are disabled before we
 	 * disable that crtc. Otherwise we might try to scan from a destroyed
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 31/38] drm/rockchip: Fix crtc_state->event signalling
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (29 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 30/38] drm/rockchip: Disarm vop->is_enabled Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 32/38] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Tomeu Vizoso

It's not permissible to look at plane->state from interrupt context,
since doing that would need the irq handler to acquire the
plane->mutex lock.

The other problem is that if we pipeline updates using the new
nonblocking atomic helpers new state gets commit before the irq
handler fires, resulting in a lost event.

Fix both issues by caching the necessary values in vop_win, protected
by dev->event_lock.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 957a6b4917c8..94eaeec29b6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -98,7 +98,9 @@ struct vop_win {
 	const struct vop_win_data *data;
 	struct vop *vop;
 
-	struct vop_plane_state state;
+	/* protected by dev->event_lock */
+	bool enable;
+	dma_addr_t yrgb_mst;
 };
 
 struct vop {
@@ -112,6 +114,8 @@ struct vop {
 	bool vsync_work_pending;
 	struct completion dsp_hold_completion;
 	struct completion wait_update_complete;
+
+	/* protected by dev->event_lock */
 	struct drm_pending_vblank_event *event;
 
 	const struct vop_data *data;
@@ -652,6 +656,11 @@ static void vop_plane_atomic_disable(struct drm_plane *plane,
 	if (!old_state->crtc)
 		return;
 
+	spin_lock_irq(&plane->dev->event_lock);
+	vop_win->enable = false;
+	vop_win->yrgb_mst = 0;
+	spin_unlock_irq(&plane->dev->event_lock);
+
 	spin_lock(&vop->reg_lock);
 
 	VOP_WIN_SET(vop, win, enable, 0);
@@ -686,7 +695,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 	/*
 	 * can't update plane when vop is disabled.
 	 */
-	if (!crtc)
+	if (WARN_ON(!crtc))
 		return;
 
 	if (WARN_ON(!vop->is_enabled))
@@ -715,6 +724,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 	offset += (src->y1 >> 16) * fb->pitches[0];
 	vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 
+	spin_lock_irq(&plane->dev->event_lock);
+	vop_win->enable = true;
+	vop_win->yrgb_mst = vop_plane_state->yrgb_mst;
+	spin_unlock_irq(&plane->dev->event_lock);
+
 	spin_lock(&vop->reg_lock);
 
 	VOP_WIN_SET(vop, win, format, vop_plane_state->format);
@@ -1074,16 +1088,14 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
 
 static bool vop_win_pending_is_complete(struct vop_win *vop_win)
 {
-	struct drm_plane *plane = &vop_win->base;
-	struct vop_plane_state *state = to_vop_plane_state(plane->state);
 	dma_addr_t yrgb_mst;
 
-	if (!state->enable)
+	if (!vop_win->enable)
 		return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
 
 	yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
 
-	return yrgb_mst == state->yrgb_mst;
+	return yrgb_mst == vop_win->yrgb_mst;
 }
 
 static void vop_handle_vblank(struct vop *vop)
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 32/38] drm/rockchip: convert to helper nonblocking atomic commit
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (30 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 31/38] drm/rockchip: Fix crtc_state->event signalling Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 33/38] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Tomeu Vizoso

With the various bits fixed rockchip now has an atomic compliant
handling/signalling of crtc_state->event, which means we can just
switch over to the new nonblocking helpers and remove some code.

v2: Fixes from Tomeu.

v3: Send out vblank events correctly when shutting down a crtc for
good. This is part of the atomic interface contract.

v4: Properly protect vop->event.

v5: Add more WARN_ON to check vop->event isn't clobbered.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  3 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 10 ----
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 72 ++++-------------------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +++++++-
 4 files changed, 27 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 09a4d429c0f0..2fac6799ceb2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -145,9 +145,6 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	if (!private)
 		return -ENOMEM;
 
-	mutex_init(&private->commit.lock);
-	INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
-
 	drm_dev->dev_private = private;
 
 	drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 56f43a364c7f..7684503ff765 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -43,13 +43,6 @@ struct rockchip_crtc_funcs {
 	void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
 };
 
-struct rockchip_atomic_commit {
-	struct work_struct	work;
-	struct drm_atomic_state *state;
-	struct drm_device *dev;
-	struct mutex lock;
-};
-
 struct rockchip_crtc_state {
 	struct drm_crtc_state base;
 	int output_type;
@@ -68,11 +61,8 @@ struct rockchip_drm_private {
 	struct drm_fb_helper fbdev_helper;
 	struct drm_gem_object *fbdev_bo;
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
-
-	struct rockchip_atomic_commit commit;
 };
 
-void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 				 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 5ea141dfae5b..9198ee1ddc87 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -229,87 +229,32 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_stat
 }
 
 static void
-rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
+rockchip_atomic_commit_tail(struct drm_atomic_state *state)
 {
-	struct drm_atomic_state *state = commit->state;
-	struct drm_device *dev = commit->dev;
+	struct drm_device *dev = state->dev;
 
-	/*
-	 * TODO: do fence wait here.
-	 */
-
-	/*
-	 * Rockchip crtc support runtime PM, can't update display planes
-	 * when crtc is disabled.
-	 *
-	 * drm_atomic_helper_commit comments detail that:
-	 *     For drivers supporting runtime PM the recommended sequence is
-	 *
-	 *     drm_atomic_helper_commit_modeset_disables(dev, state);
-	 *
-	 *     drm_atomic_helper_commit_modeset_enables(dev, state);
-	 *
-	 *     drm_atomic_helper_commit_planes(dev, state, true);
-	 *
-	 * See the kerneldoc entries for these three functions for more details.
-	 */
 	drm_atomic_helper_commit_modeset_disables(dev, state);
 
 	drm_atomic_helper_commit_modeset_enables(dev, state);
 
 	drm_atomic_helper_commit_planes(dev, state, true);
 
+	drm_atomic_helper_commit_hw_done(state);
+
 	rockchip_atomic_wait_for_complete(dev, state);
 
 	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
-}
-
-void rockchip_drm_atomic_work(struct work_struct *work)
-{
-	struct rockchip_atomic_commit *commit = container_of(work,
-					struct rockchip_atomic_commit, work);
-
-	rockchip_atomic_commit_complete(commit);
 }
 
-int rockchip_drm_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool nonblock)
-{
-	struct rockchip_drm_private *private = dev->dev_private;
-	struct rockchip_atomic_commit *commit = &private->commit;
-	int ret;
-
-	ret = drm_atomic_helper_prepare_planes(dev, state);
-	if (ret)
-		return ret;
-
-	/* serialize outstanding nonblocking commits */
-	mutex_lock(&commit->lock);
-	flush_work(&commit->work);
-
-	drm_atomic_helper_swap_state(state, true);
-
-	commit->dev = dev;
-	commit->state = state;
-
-	if (nonblock)
-		schedule_work(&commit->work);
-	else
-		rockchip_atomic_commit_complete(commit);
-
-	mutex_unlock(&commit->lock);
-
-	return 0;
-}
+struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
+	.atomic_commit_tail = rockchip_atomic_commit_tail,
+};
 
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
 	.fb_create = rockchip_user_fb_create,
 	.output_poll_changed = rockchip_drm_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = rockchip_drm_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 struct drm_framebuffer *
@@ -340,4 +285,5 @@ void rockchip_drm_mode_config_init(struct drm_device *dev)
 	dev->mode_config.max_height = 4096;
 
 	dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
+	dev->mode_config.helper_private = &rockchip_mode_config_helpers;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 94eaeec29b6b..d2932478ff59 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -502,6 +502,8 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	int i;
 
+	WARN_ON(vop->event);
+
 	/*
 	 * We need to make sure that all windows are disabled before we
 	 * disable that crtc. Otherwise we might try to scan from a destroyed
@@ -551,6 +553,14 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	clk_disable(vop->aclk);
 	clk_disable(vop->hclk);
 	pm_runtime_put(vop->dev);
+
+	if (crtc->state->event && !crtc->state->active) {
+		spin_lock_irq(&crtc->dev->event_lock);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+
+		crtc->state->event = NULL;
+	}
 }
 
 static void vop_plane_destroy(struct drm_plane *plane)
@@ -939,6 +949,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	u16 vact_end = vact_st + vdisplay;
 	uint32_t val;
 
+	WARN_ON(vop->event);
+
 	vop_enable(crtc);
 	/*
 	 * If dclk rate is zero, mean that scanout is stop,
@@ -1035,12 +1047,15 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
 {
 	struct vop *vop = to_vop(crtc);
 
+	spin_lock_irq(&crtc->dev->event_lock);
 	if (crtc->state->event) {
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		WARN_ON(vop->event);
 
 		vop->event = crtc->state->event;
 		crtc->state->event = NULL;
 	}
+	spin_unlock_irq(&crtc->dev->event_lock);
 }
 
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
@@ -1110,15 +1125,16 @@ static void vop_handle_vblank(struct vop *vop)
 			return;
 	}
 
+	spin_lock_irqsave(&drm->event_lock, flags);
 	if (vop->event) {
-		spin_lock_irqsave(&drm->event_lock, flags);
 
 		drm_crtc_send_vblank_event(crtc, vop->event);
 		drm_crtc_vblank_put(crtc);
 		vop->event = NULL;
 
-		spin_unlock_irqrestore(&drm->event_lock, flags);
 	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+
 	if (!completion_done(&vop->wait_update_complete))
 		complete(&vop->wait_update_complete);
 }
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 33/38] drm/rockchip: Nuke pending event handling in preclose
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (31 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 32/38] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 34/38] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Mark yao

This is now handled by the core, drivers can totally ignore lifetime
issues of drm events.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 22 ----------------------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 --------------------
 3 files changed, 43 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 2fac6799ceb2..2251121343e6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -257,27 +257,6 @@ static int rockchip_drm_unload(struct drm_device *drm_dev)
 	return 0;
 }
 
-static void rockchip_drm_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-						    struct drm_file *file_priv)
-{
-	struct rockchip_drm_private *priv = crtc->dev->dev_private;
-	int pipe = drm_crtc_index(crtc);
-
-	if (pipe < ROCKCHIP_MAX_CRTC &&
-	    priv->crtc_funcs[pipe] &&
-	    priv->crtc_funcs[pipe]->cancel_pending_vblank)
-		priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
-}
-
-static void rockchip_drm_preclose(struct drm_device *dev,
-				  struct drm_file *file_priv)
-{
-	struct drm_crtc *crtc;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		rockchip_drm_crtc_cancel_pending_vblank(crtc, file_priv);
-}
-
 void rockchip_drm_lastclose(struct drm_device *dev)
 {
 	struct rockchip_drm_private *priv = dev->dev_private;
@@ -303,7 +282,6 @@ static struct drm_driver rockchip_drm_driver = {
 				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.load			= rockchip_drm_load,
 	.unload			= rockchip_drm_unload,
-	.preclose		= rockchip_drm_preclose,
 	.lastclose		= rockchip_drm_lastclose,
 	.get_vblank_counter	= drm_vblank_no_hw_counter,
 	.enable_vblank		= rockchip_drm_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7684503ff765..005634484441 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -40,7 +40,6 @@ struct rockchip_crtc_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	void (*wait_for_update)(struct drm_crtc *crtc);
-	void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
 };
 
 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index d2932478ff59..8cd840f602b7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -894,30 +894,10 @@ static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
 	WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
 }
 
-static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-					   struct drm_file *file_priv)
-{
-	struct drm_device *drm = crtc->dev;
-	struct vop *vop = to_vop(crtc);
-	struct drm_pending_vblank_event *e;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	e = vop->event;
-	if (e && e->base.file_priv == file_priv) {
-		vop->event = NULL;
-
-		kfree(&e->base);
-		file_priv->event_space += sizeof(e->event);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.enable_vblank = vop_crtc_enable_vblank,
 	.disable_vblank = vop_crtc_disable_vblank,
 	.wait_for_update = vop_crtc_wait_for_update,
-	.cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 34/38] drm/virtio: Don't reinvent a flipping wheel
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (32 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 33/38] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 35/38] drm: Replace fb_helper->atomic with mode_config->atomic_commit Daniel Vetter
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Gerd Hoffmann, Daniel Vetter

Now that the core helpers support nonblocking atomic commits there's
no need to invent that wheel separately (instead of fixing the bug in
the atomic implementation of virtio, as it should have been done!).

Cc: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 48 ++------------------------------
 1 file changed, 2 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index d4305da88f44..325c6f73814b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -118,58 +118,13 @@ static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc,
 	return 0;
 }
 
-static int virtio_gpu_page_flip(struct drm_crtc *crtc,
-				struct drm_framebuffer *fb,
-				struct drm_pending_vblank_event *event,
-				uint32_t flags)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-	struct drm_plane *plane = crtc->primary;
-	struct virtio_gpu_framebuffer *vgfb;
-	struct virtio_gpu_object *bo;
-	unsigned long irqflags;
-	uint32_t handle;
-
-	plane->fb = fb;
-	vgfb = to_virtio_gpu_framebuffer(plane->fb);
-	bo = gem_to_virtio_gpu_obj(vgfb->obj);
-	handle = bo->hw_res_handle;
-
-	DRM_DEBUG("handle 0x%x%s, crtc %dx%d\n", handle,
-		  bo->dumb ? ", dumb" : "",
-		  crtc->mode.hdisplay, crtc->mode.vdisplay);
-	if (bo->dumb) {
-		virtio_gpu_cmd_transfer_to_host_2d
-			(vgdev, handle, 0,
-			 cpu_to_le32(crtc->mode.hdisplay),
-			 cpu_to_le32(crtc->mode.vdisplay),
-			 0, 0, NULL);
-	}
-	virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
-				   crtc->mode.hdisplay,
-				   crtc->mode.vdisplay, 0, 0);
-	virtio_gpu_cmd_resource_flush(vgdev, handle, 0, 0,
-				      crtc->mode.hdisplay,
-				      crtc->mode.vdisplay);
-
-	if (event) {
-		spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
-		drm_send_vblank_event(crtc->dev, -1, event);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
-	}
-
-	return 0;
-}
-
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
 	.cursor_set2            = virtio_gpu_crtc_cursor_set,
 	.cursor_move            = virtio_gpu_crtc_cursor_move,
 	.set_config             = drm_atomic_helper_set_config,
 	.destroy                = drm_crtc_cleanup,
 
-	.page_flip              = virtio_gpu_page_flip,
+	.page_flip              = drm_atomic_helper_page_flip,
 	.reset                  = drm_atomic_helper_crtc_reset,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
@@ -267,6 +222,7 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
 	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 	if (crtc->state->event)
 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+	crtc->state->event = NULL;
 	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 }
 
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 35/38] drm: Replace fb_helper->atomic with mode_config->atomic_commit
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (33 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 34/38] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:06 ` [PATCH 36/38] drm: Resurrect atomic rmfb code Daniel Vetter
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Drivers transitioning to atomic might not yet want to enable full
DRIVER_ATOMIC support when it's not entirely working. But using atomic
internally makes a lot more sense earlier.

Instead of spreading such flags to more places I figured it's simpler
to just check for mode_config->funcs->atomic_commit, and use atomic
paths if that is set. For the only driver currently transitioning
(i915) this does the right thing.

Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_fb_helper.c    |  6 ++----
 drivers/gpu/drm/i915/intel_fbdev.c |  2 --
 include/drm/drm_fb_helper.h        | 11 -----------
 3 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index c0e0a2e78d75..ba2fcb2a68ad 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -385,7 +385,7 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
 
 	drm_warn_on_modeset_not_all_locked(dev);
 
-	if (fb_helper->atomic)
+	if (dev->mode_config.funcs->atomic_commit)
 		return restore_fbdev_mode_atomic(fb_helper);
 
 	drm_for_each_plane(plane, dev) {
@@ -716,8 +716,6 @@ int drm_fb_helper_init(struct drm_device *dev,
 		i++;
 	}
 
-	fb_helper->atomic = !!drm_core_check_feature(dev, DRIVER_ATOMIC);
-
 	return 0;
 out_free:
 	drm_fb_helper_crtc_free(fb_helper);
@@ -1344,7 +1342,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
 		return -EBUSY;
 	}
 
-	if (fb_helper->atomic) {
+	if (dev->mode_config.funcs->atomic_commit) {
 		ret = pan_display_atomic(var, info);
 		goto unlock;
 	}
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index ef8e67690f3d..4c725ad6fb54 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -724,8 +724,6 @@ int intel_fbdev_init(struct drm_device *dev)
 		return ret;
 	}
 
-	ifbdev->helper.atomic = true;
-
 	dev_priv->fbdev = ifbdev;
 	INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker);
 
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 5b4aa35026a3..db8d4780eaa2 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -212,17 +212,6 @@ struct drm_fb_helper {
 	 * needs to be reprobe when fbdev is in control again.
 	 */
 	bool delayed_hotplug;
-
-	/**
-	 * @atomic:
-	 *
-	 * Use atomic updates for restore_fbdev_mode(), etc.  This defaults to
-	 * true if driver has DRIVER_ATOMIC feature flag, but drivers can
-	 * override it to true after drm_fb_helper_init() if they support atomic
-	 * modeset but do not yet advertise DRIVER_ATOMIC (note that fb-helper
-	 * does not require ASYNC commits).
-	 */
-	bool atomic;
 };
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 36/38] drm: Resurrect atomic rmfb code
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (34 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 35/38] drm: Replace fb_helper->atomic with mode_config->atomic_commit Daniel Vetter
@ 2016-06-01 22:06 ` Daniel Vetter
  2016-06-01 22:07 ` [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions Daniel Vetter
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:06 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This was somehow lost between v3 and the merged version in Maarten's
patch merged as:

commit f2d580b9a8149735cbc4b59c4a8df60173658140
Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date:   Wed May 4 14:38:26 2016 +0200

    drm/core: Do not preserve framebuffer on rmfb, v4.

Actual code copied from Maarten's patch, but with the slight change to
just use dev->mode_config.funcs->atomic_commit to decide whether to
use the atomic path or not.

Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 66 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_crtc.c          |  6 ++++
 drivers/gpu/drm/drm_crtc_internal.h |  1 +
 3 files changed, 73 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d99ab2f6663f..dac0875e669c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1564,6 +1564,72 @@ void drm_atomic_clean_old_fb(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_atomic_clean_old_fb);
 
+int drm_atomic_remove_fb(struct drm_framebuffer *fb)
+{
+	struct drm_modeset_acquire_ctx ctx;
+	struct drm_device *dev = fb->dev;
+	struct drm_atomic_state *state;
+	struct drm_plane *plane;
+	int ret = 0;
+	unsigned plane_mask;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return -ENOMEM;
+
+	drm_modeset_acquire_init(&ctx, 0);
+	state->acquire_ctx = &ctx;
+
+retry:
+	plane_mask = 0;
+	ret = drm_modeset_lock_all_ctx(dev, &ctx);
+	if (ret)
+		goto unlock;
+
+	drm_for_each_plane(plane, dev) {
+		struct drm_plane_state *plane_state;
+
+		if (plane->state->fb != fb)
+			continue;
+
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state)) {
+			ret = PTR_ERR(plane_state);
+			goto unlock;
+		}
+
+		drm_atomic_set_fb_for_plane(plane_state, NULL);
+		ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
+		if (ret)
+			goto unlock;
+
+		plane_mask |= BIT(drm_plane_index(plane));
+
+		plane->old_fb = plane->fb;
+		plane->fb = NULL;
+	}
+
+	if (plane_mask)
+		ret = drm_atomic_commit(state);
+
+unlock:
+	if (plane_mask)
+		drm_atomic_clean_old_fb(dev, plane_mask, ret);
+
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+
+	if (ret || !plane_mask)
+		drm_atomic_state_free(state);
+
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+
+	return ret;
+}
+
 int drm_mode_atomic_ioctl(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv)
 {
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1f14c6565210..9e4bc06361ba 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -600,6 +600,11 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 	 * in this manner.
 	 */
 	if (drm_framebuffer_read_refcount(fb) > 1) {
+		if (dev->mode_config.funcs->atomic_commit) {
+			drm_atomic_remove_fb(fb);
+			goto out;
+		}
+
 		drm_modeset_lock_all(dev);
 		/* remove from any CRTC */
 		drm_for_each_crtc(crtc, dev) {
@@ -621,6 +626,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
 		drm_modeset_unlock_all(dev);
 	}
 
+out:
 	drm_framebuffer_unreference(fb);
 }
 EXPORT_SYMBOL(drm_framebuffer_remove);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 8186c0e05c42..b426d37bc916 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -125,4 +125,5 @@ int drm_atomic_get_property(struct drm_mode_object *obj,
 			    struct drm_property *property, uint64_t *val);
 int drm_mode_atomic_ioctl(struct drm_device *dev,
 			  void *data, struct drm_file *file_priv);
+int drm_atomic_remove_fb(struct drm_framebuffer *fb);
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (35 preceding siblings ...)
  2016-06-01 22:06 ` [PATCH 36/38] drm: Resurrect atomic rmfb code Daniel Vetter
@ 2016-06-01 22:07 ` Daniel Vetter
  2016-06-17 10:04   ` Benjamin Gaignard
  2016-06-01 22:07 ` [PATCH 38/38] drm/crtc-helper: disable_unused_functions really isn't for atomic Daniel Vetter
  2016-06-02 13:10 ` ✗ Ro.CI.BAT: failure for nonblocking atomic commits for everyone! Patchwork
  38 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:07 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Atomic drivers are supposed to do hw/sw state reset with the
drm_mode_config_reset() call right above it.

Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/sti/sti_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index dd2c400c4a46..26aa85d4b872 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -279,7 +279,6 @@ static int sti_load(struct drm_device *dev, unsigned long flags)
 
 	drm_mode_config_reset(dev);
 
-	drm_helper_disable_unused_functions(dev);
 	drm_fbdev_cma_init(dev, 32,
 			   dev->mode_config.num_crtc,
 			   dev->mode_config.num_connector);
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 38/38] drm/crtc-helper: disable_unused_functions really isn't for atomic
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (36 preceding siblings ...)
  2016-06-01 22:07 ` [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions Daniel Vetter
@ 2016-06-01 22:07 ` Daniel Vetter
  2016-06-02 13:10 ` ✗ Ro.CI.BAT: failure for nonblocking atomic commits for everyone! Patchwork
  38 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:07 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Tomeu Vizoso

Rockchip just blew up here on testing, because I removed some "is this
crtc already disabled/enabled" state tracking from callbacks (not needed
with atomic). Turns out that was needed to work around rockchip still
calling legacy helper code.

Since me explaining on irc/mailing-list plus kerneldoc isn't enough,
be more verbose and add dmesg output. Not that anyone actually reads that,
either.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_crtc_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index a6e42433ef0e..b47ec24939a0 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -232,6 +232,9 @@ static void __drm_helper_disable_unused_functions(struct drm_device *dev)
  */
 void drm_helper_disable_unused_functions(struct drm_device *dev)
 {
+	if (drm_core_check_feature(dev, DRIVER_ATOMIC))
+		DRM_ERROR("Called for atomic driver, this is not what you want.\n");
+
 	drm_modeset_lock_all(dev);
 	__drm_helper_disable_unused_functions(dev);
 	drm_modeset_unlock_all(dev);
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 1/2] drm/atomic: Add struct drm_crtc_commit to track async updates
  2016-06-01 22:06 ` [PATCH 22/38] drm/atomic-helper: nonblocking commit support Daniel Vetter
@ 2016-06-02  9:56   ` Daniel Vetter
  2016-06-02  9:56     ` [PATCH 2/2] drm/atomic-helper: nonblocking commit support Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02  9:56 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Stone, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Daniel Vetter

Split out from my big nonblocking atomic commit helper code as prep
work. While add it, also add some neat asciiart to document how it's
supposed to be used.

Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Tomeu Vizoso <tomeu.vizoso@gmail.com>
Cc: Daniel Stone <daniels@collabora.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c |  22 +++++++
 drivers/gpu/drm/drm_crtc.c   |   3 +
 drivers/gpu/drm/drm_fops.c   |   6 ++
 include/drm/drmP.h           |   1 +
 include/drm/drm_atomic.h     |   6 ++
 include/drm/drm_crtc.h       | 146 +++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 178 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5e4b820a977c..d99ab2f6663f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@
 
 #include "drm_crtc_internal.h"
 
+static void crtc_commit_free(struct kref *kref)
+{
+	struct drm_crtc_commit *commit =
+		container_of(kref, struct drm_crtc_commit, ref);
+
+	kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+	kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 
 		crtc->funcs->atomic_destroy_state(crtc,
 						  state->crtcs[i].state);
+
+		if (state->crtcs[i].commit) {
+			kfree(state->crtcs[i].commit->event);
+			state->crtcs[i].commit->event = NULL;
+			drm_crtc_commit_put(state->crtcs[i].commit);
+		}
+
+		state->crtcs[i].commit = NULL;
 		state->crtcs[i].ptr = NULL;
 		state->crtcs[i].state = NULL;
 	}
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1cb3b471aadc..1f14c6565210 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -669,6 +669,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 	crtc->dev = dev;
 	crtc->funcs = funcs;
 
+	INIT_LIST_HEAD(&crtc->commit_list);
+	spin_lock_init(&crtc->commit_lock);
+
 	drm_modeset_lock_init(&crtc->mutex);
 	ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 	if (ret)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 4c4b30f7a9f2..5921b203503a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -686,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->completion) {
+		/* ->completion might disappear as soon as it signalled. */
+		complete_all(e->completion);
+		e->completion = NULL;
+	}
+
 	if (e->fence) {
 		fence_signal(e->fence);
 		fence_put(e->fence);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 51f751d1c8a4..781db4f562d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {
+	struct completion *completion;
 	struct drm_event *event;
 	struct fence *fence;
 	struct list_head link;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 465a1212f4f0..abec2a3f0225 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,12 @@
 
 #include <drm/drm_crtc.h>
 
+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
+static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+	kref_get(&commit->ref);
+}
+
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d5d5e343531e..cf4aad0929d9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -725,9 +725,6 @@ struct drm_crtc_funcs {
  * @gamma_store: gamma ramp values
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
- * @state: current atomic state for this CRTC
- * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
- * 	legacy IOCTLs
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -780,11 +777,37 @@ struct drm_crtc {
 
 	struct drm_object_properties properties;
 
+	/**
+	 * @state:
+	 *
+	 * Current atomic state for this CRTC.
+	 */
 	struct drm_crtc_state *state;
 
-	/*
-	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
-	 * acquire context.
+	/**
+	 * @commit_list:
+	 *
+	 * List of &drm_crtc_commit structures tracking pending commits.
+	 * Protected by @commit_lock. This list doesn't hold its own full
+	 * reference, but burrows it from the ongoing commit. Commit entries
+	 * must be removed from this list once the commit is fully completed,
+	 * but before it's correspoding &drm_atomic_state gets destroyed.
+	 */
+	struct list_head commit_list;
+
+	/**
+	 * @commit_lock:
+	 *
+	 * Spinlock to protect @commit_list.
+	 */
+	spinlock_t commit_lock;
+
+	/**
+	 * @acquire_ctx:
+	 *
+	 * Per-CRTC implicit acquire context used by atomic drivers for legacy
+	 * IOCTLs, so that atomic drivers can get at the locking acquire
+	 * context.
 	 */
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
@@ -1694,6 +1717,108 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+/**
+ * struct drm_crtc_commit - track modeset commits on a CRTC
+ *
+ * This structure is used to track pending modeset changes and atomic commit on
+ * a per-CRTC basis. Since updating the list should never block this structure
+ * is reference counted to allow waiters to safely wait on an event to complete,
+ * without holding any locks.
+ *
+ * It has 3 different events in total to allow a fine-grained synchronoization
+ * between outstanding updates::
+ *
+ *	atomic commit thread			hardware
+ *
+ * 	write new state into hardware	---->	...
+ * 	signal hw_done
+ * 						switch to new state on next
+ * 	...					v/hblank
+ *
+ *	wait for buffers to show up		...
+ *
+ *	...					send completion irq
+ *						irq handler signals flip_done
+ *	cleanup old buffers
+ *
+ * 	signal cleanup_done
+ *
+ * 	wait for flip_done		<----
+ * 	clean up atomic state
+ * 
+ * The important bit to know is that cleanup_done is the terminal event, but the
+ * ordering between flip_done and hw_done is entirely up to the specific driver
+ * and modeset state change.
+ */
+struct drm_crtc_commit {
+	/**
+	 * @crtc:
+	 *
+	 * DRM CRTC for this commit.
+	 */
+	struct drm_crtc *crtc;
+
+	/**
+	 * @ref:
+	 *
+	 * Reference count for this structure. Needed to allow blocking on
+	 * completions without the risk of the completion disappearing
+	 * meanwhile.
+	 */
+	struct kref ref;
+
+	/**
+	 * @flip_done:
+	 *
+	 * Will be signaled when the hardware has flipped to the new set of
+	 * buffers. Signals at the same time as when the drm event for this
+	 * commit is sent to userspace, or when an out-fence is singalled. Note
+	 * that for most hardware, in most cases this happens after @hw_done is
+	 * signalled.
+	 */
+	struct completion flip_done;
+
+	/**
+	 * @hw_done:
+	 *
+	 * Will be signalled when all hw register changes for this commit have
+	 * been written out. Especially when disabling a pipe this can be much
+	 * later than than @flip_done, since that can signal already when the
+	 * screen goes black, whereas to fully shut down a pipe more register
+	 * I/O is required.
+	 *
+	 * Note that this does not need to include separately reference-counted
+	 * resources like backing storage buffer pinning, or runtime pm
+	 * management.
+	 */
+	struct completion hw_done;
+
+	/**
+	 * cleanup_done:
+	 *
+	 * Will be signalled after old buffers have been cleaned up again by
+	 * calling drm_atomic_helper_cleanup_planes(). Since this can only
+	 * happen after a vblank wait completed it might be a bit later. This
+	 * completion is useful to throttle updates and avoid hardware updates
+	 * getting ahead of the buffer cleanup too much.
+	 */
+	struct completion cleanup_done;
+
+	/**
+	 * @commit_entry:
+	 *
+	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
+	 */
+	struct list_head commit_entry;
+
+	/**
+	 * @event:
+	 *
+	 * &drm_pending_vblank_event pointer to clean up private events.
+	 */
+	struct drm_pending_vblank_event *event;
+};
+
 struct __drm_planes_state {
 	struct drm_plane *ptr;
 	struct drm_plane_state *state;
@@ -1702,6 +1827,7 @@ struct __drm_planes_state {
 struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
+	struct drm_crtc_commit *commit;
 };
 
 struct __drm_connnectors_state {
@@ -1733,6 +1859,14 @@ struct drm_atomic_state {
 	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
+
+	/**
+	 * @commit_work:
+	 *
+	 * Work item which can be used by the driver or helpers to execute the
+	 * commit without blocking.
+	 */
+	struct work_struct commit_work;
 };
 
 
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 2/2] drm/atomic-helper: nonblocking commit support
  2016-06-02  9:56   ` [PATCH 1/2] drm/atomic: Add struct drm_crtc_commit to track async updates Daniel Vetter
@ 2016-06-02  9:56     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02  9:56 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Stone, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Daniel Vetter

Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

v7: Fixup the stalls in swap_state for real!!

v8:
- Fixup trailing whitespace, spotted by Maarten.
- Actually wait for flip_done in cleanup_done, like the comment says
  we should do. Thanks a lot for Tomeu for helping with debugging this
  on.

v9: Now with awesome kerneldoc!

v10: Split out drm_crtc_commit tracking infrastructure.

Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Tomeu Vizoso <tomeu.vizoso@gmail.com>
Cc: Daniel Stone <daniels@collabora.com>
Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic_helper.c      | 475 ++++++++++++++++++++++++++++---
 include/drm/drm_atomic_helper.h          |   8 +
 include/drm/drm_crtc.h                   |   6 +
 include/drm/drm_modeset_helper_vtables.h |  39 +++
 4 files changed, 489 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 65128f258f84..290318d6f5b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1116,22 +1116,17 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
 
 /**
- * drm_atomic_helper_commit - commit validated state object
- * @dev: DRM device
- * @state: the driver state object
- * @nonblocking: whether nonblocking behavior is requested.
+ * drm_atomic_helper_commit_tail - commit atomic update to hardware
+ * @state: new modeset state to be committed
  *
- * This function commits a with drm_atomic_helper_check() pre-validated state
- * object. This can still fail when e.g. the framebuffer reservation fails. For
- * now this doesn't implement nonblocking commits.
+ * This is the default implemenation for the ->atomic_commit_tail() hook of the
+ * &drm_mode_config_helper_funcs vtable.
  *
- * Note that right now this function does not support nonblocking commits, hence
- * driver writers must implement their own version for now. Also note that the
- * default ordering of how the various stages are called is to match the legacy
- * modeset helper library closest. One peculiarity of that is that it doesn't
- * mesh well with runtime PM at all.
+ * Note that the default ordering of how the various stages are called is to
+ * match the legacy modeset helper library closest. One peculiarity of that is
+ * that it doesn't mesh well with runtime PM at all.
  *
- * For drivers supporting runtime PM the recommended sequence is
+ * For drivers supporting runtime PM the recommended sequence is instead ::
  *
  *     drm_atomic_helper_commit_modeset_disables(dev, state);
  *
@@ -1139,7 +1134,73 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  *
  *     drm_atomic_helper_commit_planes(dev, state, true);
  *
- * See the kerneldoc entries for these three functions for more details.
+ * for committing the atomic update to hardware.  See the kerneldoc entries for
+ * these three functions for more details.
+ */
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, false);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_hw_done(state);
+
+	drm_atomic_helper_wait_for_vblanks(dev, state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+
+void commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config_helper_funcs *funcs;
+
+	funcs = dev->mode_config.helper_private;
+
+	drm_atomic_helper_wait_for_fences(dev, state);
+
+	drm_atomic_helper_wait_for_dependencies(state);
+
+	if (funcs && funcs->atomic_commit_tail)
+		funcs->atomic_commit_tail(state);
+	else
+		drm_atomic_helper_commit_tail(state);
+
+	drm_atomic_helper_commit_cleanup_done(state);
+
+	drm_atomic_state_free(state);
+}
+
+static void commit_work(struct work_struct *work)
+{
+	struct drm_atomic_state *state = container_of(work,
+						      struct drm_atomic_state,
+						      commit_work);
+	commit_tail(state);
+}
+
+/**
+ * drm_atomic_helper_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the driver state object
+ * @nonblock: whether nonblocking behavior is requested.
+ *
+ * This function commits a with drm_atomic_helper_check() pre-validated state
+ * object. This can still fail when e.g. the framebuffer reservation fails. This
+ * function implements nonblocking commits, using
+ * drm_atomic_helper_setup_commit() and related functions.
+ *
+ * Note that right now this function does not support nonblocking commits, hence
+ * driver writers must implement their own version for now.
+ *
+ * Committing the actual hardware state is done through the
+ * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable,
+ * or it's default implementation drm_atomic_helper_commit_tail().
  *
  * RETURNS
  * Zero for success or -errno.
@@ -1150,8 +1211,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&state->commit_work, commit_work);
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
@@ -1179,21 +1243,16 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * update. Which is important since compositors need to figure out the
 	 * composition of the next frame right after having submitted the
 	 * current layout.
+	 *
+	 * NOTE: Commit work has multiple phases, first hardware commit, then
+	 * cleanup. We want them to overlap, hence need system_unbound_wq to
+	 * make sure work items don't artifically stall on each another.
 	 */
 
-	drm_atomic_helper_wait_for_fences(dev, state);
-
-	drm_atomic_helper_commit_modeset_disables(dev, state);
-
-	drm_atomic_helper_commit_planes(dev, state, false);
-
-	drm_atomic_helper_commit_modeset_enables(dev, state);
-
-	drm_atomic_helper_wait_for_vblanks(dev, state);
-
-	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
+	if (nonblock)
+		queue_work(system_unbound_wq, &state->commit_work);
+	else
+		commit_tail(state);
 
 	return 0;
 }
@@ -1202,12 +1261,7 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
 /**
  * DOC: implementing nonblocking commit
  *
- * For now the atomic helpers don't support nonblocking commit directly. If
- * there is real need it could be added though, using the dma-buf fence
- * infrastructure for generic synchronization with outstanding rendering.
- *
- * For now drivers have to implement nonblocking commit themselves, with the
- * following sequence being the recommended one:
+ * Nonblocking atomic commits have to be implemented in the following sequence:
  *
  * 1. Run drm_atomic_helper_prepare_planes() first. This is the only function
  * which commit needs to call which can fail, so we want to run it first and
@@ -1219,10 +1273,14 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * cancelled updates. Note that it is important to ensure that the framebuffer
  * cleanup is still done when cancelling.
  *
- * For sufficient parallelism it is recommended to have a work item per crtc
- * (for updates which don't touch global state) and a global one. Then we only
- * need to synchronize with the crtc work items for changed crtcs and the global
- * work item, which allows nice concurrent updates on disjoint sets of crtcs.
+ * Asynchronous workers need to have sufficient parallelism to be able to run
+ * different atomic commits on different CRTCs in parallel. The simplest way to
+ * achive this is by running them on the &system_unbound_wq work queue. Note
+ * that drivers are not required to split up atomic commits and run an
+ * individual commit in parallel - userspace is supposed to do that if it cares.
+ * But it might be beneficial to do that for modesets, since those necessarily
+ * must be done as one global operation, and enabling or disabling a CRTC can
+ * take a long time. But even that is not required.
  *
  * 3. The software state is updated synchronously with
  * drm_atomic_helper_swap_state(). Doing this under the protection of all modeset
@@ -1235,7 +1293,309 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * commit helpers: a) pre-plane commit b) plane commit c) post-plane commit and
  * then cleaning up the framebuffers after the old framebuffer is no longer
  * being displayed.
+ *
+ * The above scheme is implemented in the atomic helper libraries in
+ * drm_atomic_helper_commit() using a bunch of helper functions. See
+ * drm_atomic_helper_setup_commit() for a starting point.
+ */
+
+static int stall_checks(struct drm_crtc *crtc, bool nonblock)
+{
+	struct drm_crtc_commit *commit, *stall_commit = NULL;
+	bool completed = true;
+	int i, ret = 0;
+
+	spin_lock(&crtc->commit_lock);
+	i = 0;
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		if (i == 0) {
+			completed = try_wait_for_completion(&commit->flip_done);
+			/* Userspace is not allowed to get ahead of the previous
+			 * commit with nonblocking ones. */
+			if (!completed && nonblock) {
+				spin_unlock(&crtc->commit_lock);
+				return -EBUSY;
+			}
+		} else if (i == 1) {
+			stall_commit = commit;
+			drm_crtc_commit_get(stall_commit);
+		} else
+			break;
+
+		i++;
+	}
+	spin_unlock(&crtc->commit_lock);
+
+	if (!stall_commit)
+		return 0;
+
+	/* We don't want to let commits get ahead of cleanup work too much,
+	 * stalling on 2nd previous commit means triple-buffer won't ever stall.
+	 */
+	ret = wait_for_completion_interruptible_timeout(&commit->cleanup_done,
+							10*HZ);
+	if (ret == 0)
+		DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
+			  crtc->base.id, crtc->name);
+
+	if (ret == -ERESTARTSYS)
+		ret = -EINTR;
+
+	drm_crtc_commit_put(stall_commit);
+
+	return ret;
+}
+
+/**
+ * drm_atomic_helper_setup_commit - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ * @nonblock: whether nonblocking behavior is requested.
+ *
+ * This function prepares @state to be used by the atomic helper's support for
+ * nonblocking commits. Drivers using the nonblocking commit infrastructure
+ * should always call this function from their ->atomic_commit hook.
+ *
+ * To be able to use this support drivers need to use a few more helper
+ * functions. drm_atomic_helper_wait_for_dependencies() must be called before
+ * actually committing the hardware state, and for nonblocking commits this call
+ * must be placed in the async worker. See also drm_atomic_helper_swap_state()
+ * and it's stall parameter, for when a driver's commit hooks look at the
+ * ->state pointers of struct &drm_crtc, &drm_plane or &drm_connector directly.
+ *
+ * Completion of the hardware commit step must be signalled using
+ * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed
+ * to read or change any permanent software or hardware modeset state. The only
+ * exception is state protected by other means than &drm_modeset_lock locks.
+ * Only the free standing @state with pointers to the old state structures can
+ * be inspected, e.g. to clean up old buffers using
+ * drm_atomic_helper_cleanup_planes().
+ *
+ * At the very end, before cleaning up @state drivers must call
+ * drm_atomic_helper_commit_cleanup_done().
+ *
+ * This is all implemented by in drm_atomic_helper_commit(), giving drivers a
+ * complete and esay-to-use default implementation of the atomic_commit() hook.
+ *
+ * The tracking of asynchronously executed and still pending commits is done
+ * using the core structure &drm_crtc_commit.
+ *
+ * Returns:
+ *
+ * 0 on success. -EBUSY when userspace schedules nonblocking commits too fast,
+ * -ENOMEM on allocation failures and -EINTR when a signal is pending.
+ */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i, ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+		if (!commit)
+			return -ENOMEM;
+
+		init_completion(&commit->flip_done);
+		init_completion(&commit->hw_done);
+		init_completion(&commit->cleanup_done);
+		INIT_LIST_HEAD(&commit->commit_entry);
+		kref_init(&commit->ref);
+		commit->crtc = crtc;
+
+		state->crtcs[i].commit = commit;
+
+		ret = stall_checks(crtc, nonblock);
+		if (ret)
+			return ret;
+
+		/* Drivers only send out events when at least either current or
+		 * new CRTC state is active. Complete right away if everything
+		 * stays off. */
+		if (!crtc->state->active && !crtc_state->active) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		/* Legacy cursor updates are fully unsynced. */
+		if (state->legacy_cursor_update) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		if (!crtc_state->event) {
+			commit->event = kzalloc(sizeof(*commit->event),
+						GFP_KERNEL);
+			if (!commit->event)
+				return -ENOMEM;
+
+			crtc_state->event = commit->event;
+		}
+
+		crtc_state->event->base.completion = &commit->flip_done;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
+
+
+static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_commit *commit;
+	int i = 0;
+
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		/* skip the first entry, that's the current commit */
+		if (i == 1)
+			return commit;
+		i++;
+	}
+
+	return NULL;
+}
+
+/**
+ * drm_atomic_helper_wait_for_dependencies - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This function waits for all preceeding commits that touch the same CRTC as
+ * @state to both be committed to the hardware (as signalled by
+ * drm_atomic_Helper_commit_hw_done) and executed by the hardware (as signalled
+ * by calling drm_crtc_vblank_send_event on the event member of
+ * &drm_crtc_state).
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		spin_lock(&crtc->commit_lock);
+		commit = preceeding_commit(crtc);
+		if (commit)
+			drm_crtc_commit_get(commit);
+		spin_unlock(&crtc->commit_lock);
+
+		if (!commit)
+			continue;
+
+		ret = wait_for_completion_timeout(&commit->hw_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		/* Currently no support for overwriting flips, hence
+		 * stall for previous one to execute completely. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		drm_crtc_commit_put(commit);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
+
+/**
+ * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This function is used to signal completion of the hardware commit step. After
+ * this step the driver is not allowed to read or change any permanent software
+ * or hardware modeset state. The only exception is state protected by other
+ * means than &drm_modeset_lock locks.
+ *
+ * Drivers should try to postpone any expensive or delayed cleanup work after
+ * this function is called.
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
  */
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+
+		/* backend must have consumed any event by now */
+		WARN_ON(crtc->state->event);
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->hw_done);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
+
+/**
+ * drm_atomic_helper_wait_for_dependencies - setup possible nonblocking commit
+ * @state: new modeset state to be committed
+ *
+ * This signals completion of the atomic update @state, including any cleanup
+ * work. If used, it must be called right before calling
+ * drm_atomic_state_free().
+ *
+ * This is part of the atomic helper support for nonblocking commits, see
+ * drm_atomic_helper_setup_commit() for an overview.
+ */
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (WARN_ON(!commit))
+			continue;
+
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->cleanup_done);
+		WARN_ON(!try_wait_for_completion(&commit->hw_done));
+
+		/* commit_list borrows our reference, need to remove before we
+		 * clean up our drm_atomic_state. But only after it actually
+		 * completed, otherwise subsequent commits won't stall properly. */
+		if (try_wait_for_completion(&commit->flip_done)) {
+			list_del(&commit->commit_entry);
+			spin_unlock(&crtc->commit_lock);
+			continue;
+		}
+
+		spin_unlock(&crtc->commit_lock);
+
+		/* We must wait for the vblank event to signal our completion
+		 * before releasing our reference, since the vblank work does
+		 * not hold a reference of its own. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		spin_lock(&crtc->commit_lock);
+		list_del(&commit->commit_entry);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
 
 /**
  * drm_atomic_helper_prepare_planes - prepare plane resources before commit
@@ -1556,17 +1916,45 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  *
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
+ *
+ * @stall must be set when nonblocking commits for this driver directly access
+ * the ->state pointer of &drm_plane, &drm_crtc or &drm_connector. With the
+ * current atomic helpers this is almost always the case, since the helpers
+ * don't pass the right state structures to the callbacks.
  */
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall)
 {
 	int i;
+	long ret;
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_plane *plane;
 	struct drm_plane_state *plane_state;
+	struct drm_crtc_commit *commit;
+
+	if (stall) {
+		for_each_crtc_in_state(state, crtc, crtc_state, i) {
+			spin_lock(&crtc->commit_lock);
+			commit = list_first_entry_or_null(&crtc->commit_list,
+					struct drm_crtc_commit, commit_entry);
+			if (commit)
+				drm_crtc_commit_get(commit);
+			spin_unlock(&crtc->commit_lock);
+
+			if (!commit)
+				continue;
+
+			ret = wait_for_completion_timeout(&commit->hw_done,
+							  10*HZ);
+			if (ret == 0)
+				DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+					  crtc->base.id, crtc->name);
+			drm_crtc_commit_put(commit);
+		}
+	}
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
@@ -1578,6 +1966,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 		crtc->state->state = state;
 		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
+
+		if (state->crtcs[i].commit) {
+			spin_lock(&crtc->commit_lock);
+			list_add(&state->crtcs[i].commit->commit_entry,
+				 &crtc->commit_list);
+			spin_unlock(&crtc->commit_lock);
+
+			state->crtcs[i].commit->event = NULL;
+		}
 	}
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 0276447225ed..5fb8c306e16b 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -38,6 +38,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
 			       struct drm_atomic_state *state);
 int drm_atomic_helper_check(struct drm_device *dev,
 			    struct drm_atomic_state *state);
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
 int drm_atomic_helper_commit(struct drm_device *dev,
 			     struct drm_atomic_state *state,
 			     bool nonblock);
@@ -74,6 +75,13 @@ void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall);
 
+/* nonblocking commit helpers */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock);
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
+
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
 				   struct drm_crtc *crtc,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index cf4aad0929d9..ac43b7127367 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1749,6 +1749,9 @@ struct drm_bridge {
  * The important bit to know is that cleanup_done is the terminal event, but the
  * ordering between flip_done and hw_done is entirely up to the specific driver
  * and modeset state change.
+ *
+ * For an implementation of how to use this look at
+ * drm_atomic_helper_setup_commit() from the atomic helper library.
  */
 struct drm_crtc_commit {
 	/**
@@ -2208,6 +2211,7 @@ struct drm_mode_config_funcs {
  * @async_page_flip: does this device support async flips on the primary plane?
  * @cursor_width: hint to userspace for max cursor width
  * @cursor_height: hint to userspace for max cursor height
+ * @helper_private: mid-layer private data
  *
  * Core mode resource tracking structure.  All CRTC, encoders, and connectors
  * enumerated by the driver are added here, as are global properties.  Some
@@ -2327,6 +2331,8 @@ struct drm_mode_config {
 
 	/* cursor size */
 	uint32_t cursor_width, cursor_height;
+
+	struct drm_mode_config_helper_funcs *helper_private;
 };
 
 /**
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index d4619dc2eecb..4723fb96bc1a 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -925,4 +925,43 @@ static inline void drm_plane_helper_add(struct drm_plane *plane,
 	plane->helper_private = funcs;
 }
 
+/**
+ * struct drm_mode_config_helper_funcs - global modeset helper operations
+ *
+ * These helper functions are used by the atomic helpers.
+ */
+struct drm_mode_config_helper_funcs {
+	/**
+	 * @atomic_commit_tail:
+	 *
+	 * This hook is used by the default atomic_commit() hook implemented in
+	 * drm_atomic_helper_commit() together with the nonblocking commit
+	 * helpers (see drm_atomic_helper_setup_commit() for a starting point)
+	 * to implement blocking and nonblocking commits easily. It is not used
+	 * by the atomic helpers
+	 *
+	 * This hook should first commit the given atomic state to the hardware.
+	 * But drivers can add more waiting calls at the start of their
+	 * implementation, e.g. to wait for driver-internal request for implicit
+	 * syncing, before starting to commit the update to the hardware.
+	 *
+	 * After the atomic update is committed to the hardware this hook needs
+	 * to call drm_atomic_helper_commit_hw_done(). Then wait for the upate
+	 * to be executed by the hardware, for example using
+	 * drm_atomic_helper_wait_for_vblanks(), and then clean up the old
+	 * framebuffers using drm_atomic_helper_cleanup_planes().
+	 *
+	 * When disabling a CRTC this hook _must_ stall for the commit to
+	 * complete. Vblank waits don't work on disabled CRTC, hence the core
+	 * can't take care of this. And it also can't rely on the vblank event,
+	 * since that can be signalled already when the screen shows black,
+	 * which can happen much earlier than the last hardware access needed to
+	 * shut off the display pipeline completely.
+	 *
+	 * This hook is optional, the default implementation is
+	 * drm_atomic_helper_commit_tail().
+	 */
+	void (*atomic_commit_tail)(struct drm_atomic_state *state);
+};
+
 #endif
-- 
2.8.1

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

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state
  2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
@ 2016-06-02 11:25   ` Maarten Lankhorst
  2016-06-02 13:40     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 11:25 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to encapsulate the drm_atomic_state internals.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 50ff90aea721..3e6d9ff8840a 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
>  				continue;
>  			}
>  
> -			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
> +			plane_state = to_intel_plane_state(
> +				drm_atomic_get_existing_plane_state(drm_state,
> +								    plane));
>  			scaler_id = &plane_state->scaler_id;
>  		}
>  
intel_plane_get_atomic_state(drm_state, intel_plane); ?

If fixed,

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more
  2016-06-01 22:06 ` [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
@ 2016-06-02 11:26   ` Maarten Lankhorst
  0 siblings, 0 replies; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 11:26 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> This avois leaking drm_atomic_state internals into the helpers. The
> only place where this still happens after this patch is drm_atomic_helper_swap_state().
> It's unavoidable there, and maybe a good indicator we should actually
> move that function into drm_atomic.c.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* ✗ Ro.CI.BAT: failure for nonblocking atomic commits for everyone!
  2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
                   ` (37 preceding siblings ...)
  2016-06-01 22:07 ` [PATCH 38/38] drm/crtc-helper: disable_unused_functions really isn't for atomic Daniel Vetter
@ 2016-06-02 13:10 ` Patchwork
  38 siblings, 0 replies; 77+ messages in thread
From: Patchwork @ 2016-06-02 13:10 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: nonblocking atomic commits for everyone!
URL   : https://patchwork.freedesktop.org/series/8119/
State : failure

== Summary ==

Applying: drm/atomic-helper: use for_each_*_in_state more
Applying: drm/i915: Use drm_atomic_get_existing_plane_state
Applying: drm/msm: Use for_each_*_in_state
Applying: drm/rcar-du: Use for_each_*_in_state
Applying: drm/vc4: Use for_each_plane_in_state
Applying: drm/omap: Use for_each_plane_in_state
Applying: drm/exynos: Use for_each_crtc_in_state
Applying: drm/atomic: Add __drm_atomic_get_current_plane_state
Applying: drm: Consolidate connector arrays in drm_atomic_state
Applying: drm: Consolidate plane arrays in drm_atomic_state
Applying: drm: Consolidate crtc arrays in drm_atomic_state
Applying: drm/fence: add fence to drm_pending_event
Applying: drm/atomic-helper: Massage swap_state signature somewhat
Applying: drm/arc: Nuke event_list
Applying: drm/arc: Actually bother with handling atomic events.
Applying: drm/hdlcd: Clean up crtc hooks
Applying: drm/hdlcd: Fix up crtc_state->event handling
Applying: drm/fsl-du: Implement some semblance of vblank event handling
Applying: drm/hisilicon: Implement some semblance of vblank event handling
Applying: drm/sun4i: Implement some semblance of vblank event handling
Applying: drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
Applying: drm/atomic-helper: nonblocking commit support
Applying: drm/hdlcd: Use helper support for nonblocking commits
Applying: drm/arc: Implement nonblocking commit correctly
Applying: drm/i915: Signal drm events for atomic
Applying: drm/i915: Roll out the helper nonblock tracking
Applying: drm/i915: nonblocking commit
Applying: drm/i915: Use atomic commits for legacy page_flips
Applying: drm/i915: Move fb_bits updating later in atomic_commit
Applying: drm/rockchip: Disarm vop->is_enabled
Applying: drm/rockchip: Fix crtc_state->event signalling
Applying: drm/rockchip: convert to helper nonblocking atomic commit
Applying: drm/rockchip: Nuke pending event handling in preclose
Applying: drm/virtio: Don't reinvent a flipping wheel
Applying: drm: Replace fb_helper->atomic with mode_config->atomic_commit
Applying: drm: Resurrect atomic rmfb code
Patch failed at 0036 drm: Resurrect atomic rmfb code
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 03/38] drm/msm: Use for_each_*_in_state
  2016-06-01 22:06 ` [PATCH 03/38] drm/msm: Use for_each_*_in_state Daniel Vetter
@ 2016-06-02 13:13   ` Maarten Lankhorst
  0 siblings, 0 replies; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:13 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_state internals
>
> Cc: Rob Clark <robdclark@gmail.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c    | 20 +++++++----------
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c    | 12 +++-------
>  drivers/gpu/drm/msm/msm_atomic.c           | 35 ++++++++++--------------------
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  1 +
>  4 files changed, 23 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> index 67442d50a6c2..f145d256e332 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
> @@ -106,31 +106,27 @@ out:
>  static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
>  {
>  	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> -	int i, ncrtcs = state->dev->mode_config.num_crtc;
> +	int i;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  
>  	mdp4_enable(mdp4_kms);
>  
>  	/* see 119ecb7fd */
> -	for (i = 0; i < ncrtcs; i++) {
> -		struct drm_crtc *crtc = state->crtcs[i];
> -		if (!crtc)
> -			continue;
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
>  		drm_crtc_vblank_get(crtc);
> -	}
>  }
>  
>  static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
>  {
>  	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> -	int i, ncrtcs = state->dev->mode_config.num_crtc;
> +	int i;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  
>  	/* see 119ecb7fd */
> -	for (i = 0; i < ncrtcs; i++) {
> -		struct drm_crtc *crtc = state->crtcs[i];
> -		if (!crtc)
> -			continue;
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
>  		drm_crtc_vblank_put(crtc);
> -	}
>  
>  	mdp4_disable(mdp4_kms);
>  }
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> index 484b4d15e71d..f0c285b1c027 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> @@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
>  {
>  	int i;
>  	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
> -	int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
> -
> -	for (i = 0; i < nplanes; i++) {
> -		struct drm_plane *plane = state->planes[i];
> -		struct drm_plane_state *plane_state = state->plane_states[i];
> -
> -		if (!plane)
> -			continue;
> +	struct drm_plane *plane;
> +	struct drm_plane_state *plane_state;
>  
> +	for_each_plane_in_state(state, plane, plane_state, i)
>  		mdp5_plane_complete_commit(plane, plane_state);
> -	}
>  
>  	mdp5_disable(mdp5_kms);
>  }
> diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
> index e3892c263f27..9c0e4261dbba 100644
> --- a/drivers/gpu/drm/msm/msm_atomic.c
> +++ b/drivers/gpu/drm/msm/msm_atomic.c
> @@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
>  		struct drm_atomic_state *old_state)
>  {
>  	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	struct msm_drm_private *priv = old_state->dev->dev_private;
>  	struct msm_kms *kms = priv->kms;
> -	int ncrtcs = old_state->dev->mode_config.num_crtc;
>  	int i;
>  
> -	for (i = 0; i < ncrtcs; i++) {
> -		crtc = old_state->crtcs[i];
> -
> -		if (!crtc)
> -			continue;
> -
> +	for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
>  		if (!crtc->state->enable)
>  			continue;
>  
> @@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
>  		struct drm_atomic_state *state, bool nonblock)
>  {
>  	struct msm_drm_private *priv = dev->dev_private;
> -	int nplanes = dev->mode_config.num_total_plane;
> -	int ncrtcs = dev->mode_config.num_crtc;
>  	struct msm_commit *c;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_plane *plane;
> +	struct drm_plane_state *plane_state;
>  	int i, ret;
>  
>  	ret = drm_atomic_helper_prepare_planes(dev, state);
> @@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
>  	/*
>  	 * Figure out what crtcs we have:
>  	 */
> -	for (i = 0; i < ncrtcs; i++) {
> -		struct drm_crtc *crtc = state->crtcs[i];
> -		if (!crtc)
> -			continue;
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
>  		c->crtc_mask |= (1 << drm_crtc_index(crtc));
Maybe also change this to use drm_crtc_mask(crtc); ?
> -	}
>  
>  	/*
>  	 * Figure out what fence to wait for:
>  	 */
> -	for (i = 0; i < nplanes; i++) {
> -		struct drm_plane *plane = state->planes[i];
> -		struct drm_plane_state *new_state = state->plane_states[i];
> -
> -		if (!plane)
> -			continue;
> -
> -		if ((plane->state->fb != new_state->fb) && new_state->fb) {
> -			struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0);
> +	for_each_plane_in_state(state, plane, plane_state, i) {
> +		if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
> +			struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
>  			struct msm_gem_object *msm_obj = to_msm_bo(obj);
>  
> -			new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
> +			plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 755cfdba61cd..03913b483506 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -197,6 +197,7 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_stat
>  	struct drm_crtc *crtc;
>  	int i, ret;
>  
> +
>  	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
>  		/* No one cares about the old state, so abuse it for tracking
>  		 * and store whether we hold a vblank reference (and should do a

What's this doing here?

With whitespace change removed.

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/38] drm/rcar-du: Use for_each_*_in_state
  2016-06-01 22:06 ` [PATCH 04/38] drm/rcar-du: " Daniel Vetter
@ 2016-06-02 13:14   ` Maarten Lankhorst
  2016-06-02 13:48     ` Daniel Vetter
  2016-06-02 21:08   ` Laurent Pinchart
  1 sibling, 1 reply; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:14 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_state internals better.
>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
>  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
>  2 files changed, 12 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index e70a4f33d970..f315c55c1f65 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
>  {
>  	struct rcar_du_device *rcdu = dev->dev_private;
>  	struct rcar_du_commit *commit;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	unsigned int i;
>  	int ret;
>  
> @@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
>  	/* Wait until all affected CRTCs have completed previous commits and
>  	 * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
Maybe also change this one to _mask,
either way.

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/38] drm/vc4: Use for_each_plane_in_state
  2016-06-01 22:06 ` [PATCH 05/38] drm/vc4: Use for_each_plane_in_state Daniel Vetter
@ 2016-06-02 13:15   ` Maarten Lankhorst
  0 siblings, 0 replies; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:15 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_stat internals a bit better.
>
> Cc: Eric Anholt <eric@anholt.net>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/38] drm/omap: Use for_each_plane_in_state
  2016-06-01 22:06 ` [PATCH 06/38] drm/omap: " Daniel Vetter
@ 2016-06-02 13:23   ` Maarten Lankhorst
  2016-06-02 13:50     ` Daniel Vetter
  2016-06-02 21:08   ` Laurent Pinchart
  1 sibling, 1 reply; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:23 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	Laurent Pinchart

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_stat internals a bit better.
>
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index d86f5479345b..4798ba43ff5b 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
>  {
>  	struct omap_drm_private *priv = dev->dev_private;
>  	struct omap_atomic_state_commit *commit;
> -	unsigned int i;
> -	int ret;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	int i, ret;
>  
>  	ret = drm_atomic_helper_prepare_planes(dev, state);
>  	if (ret)
> @@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
>  	/* Wait until all affected CRTCs have completed previous commits and
>  	 * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
>  	wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
>  

(again 1 << index -> crtc_mask)

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state
  2016-06-01 22:06 ` [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
@ 2016-06-02 13:23   ` Maarten Lankhorst
  0 siblings, 0 replies; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:23 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Inki Dae, Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> We want to hide drm_atomic_state internals better.
>
> Cc: Inki Dae <inki.dae@samsung.com>
> Acked-by: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 2dd820e23b0c..cabc5fd0246d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  {
>  	struct exynos_drm_private *priv = dev->dev_private;
>  	struct exynos_atomic_commit *commit;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	int i, ret;
>  
>  	commit = kzalloc(sizeof(*commit), GFP_KERNEL);
> @@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  	/* Wait until all affected CRTCs have completed previous commits and
>  	 * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
>  	wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
>  

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 16/38] drm/hdlcd: Clean up crtc hooks
  2016-06-01 22:06 ` [PATCH 16/38] drm/hdlcd: Clean up crtc hooks Daniel Vetter
@ 2016-06-02 13:33   ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 13:33 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau

On Thu, Jun 02, 2016 at 12:06:39AM +0200, Daniel Vetter wrote:
> Those are all no longer needed for a pure atomic driver.
> 
> Cc: Liviu Dudau <Liviu.Dudau@arm.com>
> Tested-by: Liviu Dudau <Liviu.Dudau@arm.com>
> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Applied this one to drm-misc, since Liviua already acked it. The other
prep patch is already in a -fixes pull request.
-Daniel

> ---
>  drivers/gpu/drm/arm/hdlcd_crtc.c | 19 -------------------
>  1 file changed, 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
> index fef1b04c2aab..b44f72722764 100644
> --- a/drivers/gpu/drm/arm/hdlcd_crtc.c
> +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
> @@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
>  	}
>  }
>  
> -static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
> -				    struct drm_crtc_state *state)
> -{
> -}
> -
> -static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
> -			const struct drm_display_mode *mode,
> -			struct drm_display_mode *adjusted_mode)
> -{
> -	return true;
> -}
> -
>  static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
> -	.mode_fixup	= hdlcd_crtc_mode_fixup,
> -	.mode_set	= drm_helper_crtc_mode_set,
> -	.mode_set_base	= drm_helper_crtc_mode_set_base,
> -	.mode_set_nofb	= hdlcd_crtc_mode_set_nofb,
>  	.enable		= hdlcd_crtc_enable,
>  	.disable	= hdlcd_crtc_disable,
> -	.prepare	= hdlcd_crtc_disable,
> -	.commit		= hdlcd_crtc_enable,
>  	.atomic_check	= hdlcd_crtc_atomic_check,
>  	.atomic_begin	= hdlcd_crtc_atomic_begin,
> -	.atomic_flush	= hdlcd_crtc_atomic_flush,
>  };
>  
>  static int hdlcd_plane_atomic_check(struct drm_plane *plane,
> -- 
> 2.8.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state
  2016-06-02 11:25   ` Maarten Lankhorst
@ 2016-06-02 13:40     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 13:40 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Thu, Jun 02, 2016 at 01:25:46PM +0200, Maarten Lankhorst wrote:
> Op 02-06-16 om 00:06 schreef Daniel Vetter:
> > We want to encapsulate the drm_atomic_state internals.
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> > index 50ff90aea721..3e6d9ff8840a 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
> >  				continue;
> >  			}
> >  
> > -			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
> > +			plane_state = to_intel_plane_state(
> > +				drm_atomic_get_existing_plane_state(drm_state,
> > +								    plane));
> >  			scaler_id = &plane_state->scaler_id;
> >  		}
> >  
> intel_plane_get_atomic_state(drm_state, intel_plane); ?
> 
> If fixed,
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Fixed&applied to drm-misc, thanks for the review.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-01 22:06 ` [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
@ 2016-06-02 13:41   ` Maarten Lankhorst
  2016-06-02 14:21   ` [PATCH] " Daniel Vetter
  1 sibling, 0 replies; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 13:41 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> ... and use it in msm&vc4. Again just want to encapsulate
> drm_atomic_state internals a bit.
>
> The const threading is a bit awkward in vc4 since C sucks, but I still
> think it's worth to enforce this. Eventually I want to make all the
> obj->state pointers const too, but that's a lot more work ...
>
Maybe instead of exposing such a dangerous function, wrap it in something like

drm_atomic_crtc_state_for_each_plane_state, which returns either get_current_plane_state or plane->state?

The only times this function is used is when iterating over all plane states a anyway, and it would be useful for i915 too.

~Maarten

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/38] drm/rcar-du: Use for_each_*_in_state
  2016-06-02 13:14   ` Maarten Lankhorst
@ 2016-06-02 13:48     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 13:48 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Thu, Jun 02, 2016 at 03:14:30PM +0200, Maarten Lankhorst wrote:
> Op 02-06-16 om 00:06 schreef Daniel Vetter:
> > We want to hide drm_atomic_state internals better.
> >
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
> >  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
> >  2 files changed, 12 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > index e70a4f33d970..f315c55c1f65 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > @@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
> >  {
> >  	struct rcar_du_device *rcdu = dev->dev_private;
> >  	struct rcar_du_commit *commit;
> > +	struct drm_crtc *crtc;
> > +	struct drm_crtc_state *crtc_state;
> >  	unsigned int i;
> >  	int ret;
> >  
> > @@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
> >  	/* Wait until all affected CRTCs have completed previous commits and
> >  	 * mark them as pending.
> >  	 */
> > -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> > -		if (state->crtcs[i])
> > -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> > -	}
> > +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> > +		commit->crtcs |= 1 << drm_crtc_index(crtc);
> >  
> Maybe also change this one to _mask,
> either way.
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Fixed up&applied, thanks for the review.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/38] drm/omap: Use for_each_plane_in_state
  2016-06-02 13:23   ` Maarten Lankhorst
@ 2016-06-02 13:50     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 13:50 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Tomi Valkeinen, Laurent Pinchart, Daniel Vetter

On Thu, Jun 02, 2016 at 03:23:18PM +0200, Maarten Lankhorst wrote:
> Op 02-06-16 om 00:06 schreef Daniel Vetter:
> > We want to hide drm_atomic_stat internals a bit better.
> >
> > Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++------
> >  1 file changed, 5 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> > index d86f5479345b..4798ba43ff5b 100644
> > --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> > +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> > @@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
> >  {
> >  	struct omap_drm_private *priv = dev->dev_private;
> >  	struct omap_atomic_state_commit *commit;
> > -	unsigned int i;
> > -	int ret;
> > +	struct drm_crtc *crtc;
> > +	struct drm_crtc_state *crtc_state;
> > +	int i, ret;
> >  
> >  	ret = drm_atomic_helper_prepare_planes(dev, state);
> >  	if (ret)
> > @@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
> >  	/* Wait until all affected CRTCs have completed previous commits and
> >  	 * mark them as pending.
> >  	 */
> > -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> > -		if (state->crtcs[i])
> > -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> > -	}
> > +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> > +		commit->crtcs |= 1 << drm_crtc_index(crtc);
> >  
> >  	wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
> >  
> 
> (again 1 << index -> crtc_mask)
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Again fixed up&applied, thanks for the review.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-01 22:06 ` [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
  2016-06-02 13:41   ` Maarten Lankhorst
@ 2016-06-02 14:21   ` Daniel Vetter
  2016-06-02 14:43     ` Maarten Lankhorst
  2016-06-02 14:47     ` Eric Engestrom
  1 sibling, 2 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 14:21 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

... and use it in msm&vc4. Again just want to encapsulate
drm_atomic_state internals a bit.

The const threading is a bit awkward in vc4 since C sucks, but I still
think it's worth to enforce this. Eventually I want to make all the
obj->state pointers const too, but that's a lot more work ...

v2: Provide safe macro to wrap up the unsafe helper better, suggested
by Maarten.

Cc: Eric Anholt <eric@anholt.net>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 ++-------
 drivers/gpu/drm/vc4/vc4_crtc.c           | 13 ++----------
 drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
 drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
 include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
 include/drm/drm_atomic_helper.h          | 24 +++++++++++++++++++--
 6 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 88fe256c1931..4e8ed739f558 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -374,6 +374,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct plane_state pstates[STAGE_MAX + 1];
 	const struct mdp5_cfg_hw *hw_cfg;
+	const struct drm_plane_state *pstate;
 	int cnt = 0, i;
 
 	DBG("%s: check", mdp5_crtc->name);
@@ -382,20 +383,13 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	 * and that we don't have conflicting mixer stages:
 	 */
 	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
-	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *pstate;
+	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
 		if (cnt >= (hw_cfg->lm.nb_stages)) {
 			dev_err(dev->dev, "too many planes!\n");
 			return -EINVAL;
 		}
 
-		pstate = state->state->plane_states[drm_plane_index(plane)];
 
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!pstate)
-			pstate = plane->state;
 		pstates[cnt].plane = plane;
 		pstates[cnt].state = to_mdp5_plane_state(pstate);
 
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 904d0754ad78..ba2e373ec901 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -395,6 +395,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct drm_plane *plane;
 	unsigned long flags;
+	const struct drm_plane_state *plane_state;
 	u32 dlist_count = 0;
 	int ret;
 
@@ -404,18 +405,8 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 	if (hweight32(state->connector_mask) > 1)
 		return -EINVAL;
 
-	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *plane_state =
-			state->state->plane_states[drm_plane_index(plane)];
-
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!plane_state)
-			plane_state = plane->state;
-
+	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state)
 		dlist_count += vc4_plane_dlist_size(plane_state);
-	}
 
 	dlist_count++; /* Account for SCALER_CTL0_END. */
 
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37cac59401d7..c799baabc008 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
 				 enum drm_plane_type type);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
-u32 vc4_plane_dlist_size(struct drm_plane_state *state);
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
 void vc4_plane_async_set_fb(struct drm_plane *plane,
 			    struct drm_framebuffer *fb);
 
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4037b52fde31..5d2c3d9fd17a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
 	return vc4_state->dlist_count;
 }
 
-u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
 {
-	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+	const struct vc4_plane_state *vc4_state =
+		container_of(state, typeof(*vc4_state), base);
 
 	return vc4_state->dlist_count;
 }
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92c84e9ab09a..4e97186293be 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 	return state->connector_states[index];
 }
 
+/**
+ * __drm_atomic_get_current_plane_state - get current plane state
+ * @state: global atomic state object
+ * @plane: plane to grab
+ *
+ * This function returns the plane state for the given plane, either from
+ * @state, or if the plane isn't part of the atomic state update, from @plane.
+ * This is useful in atomic check callbacks, when drivers need to peek at, but
+ * not change, state of other planes, since it avoids threading an error code
+ * back up the call chain.
+ *
+ * WARNING:
+ *
+ * Note that this function is in general unsafe since it doesn't check for the
+ * required locking for access state structures. Drivers must ensure that it is
+ * save to access the returned state structure through other means. One commone
+ * example is when planes are fixed to a single CRTC, and the driver knows that
+ * the CRTC locks is held already. In that case holding the CRTC locks gives a
+ * read-lock on all planes connected to that CRTC. But if planes can be
+ * reassigned things get more tricky. In that case it's better to use
+ * drm_atomic_get_plane_state and wire up full error handling.
+ *
+ * Returns:
+ *
+ * Read-only pointer to the current plane state.
+ */
+static inline const struct drm_plane_state *
+__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
+				     struct drm_plane *plane)
+{
+	if (state->plane_states[drm_plane_index(plane)])
+		return state->plane_states[drm_plane_index(plane)];
+
+	return plane->state;
+}
+
 int __must_check
 drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
 			     struct drm_display_mode *mode);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d473dcc91f54..b03bd83703b4 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -159,7 +159,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
  * This iterates over the current state, useful (for example) when applying
  * atomic state after it has been checked and swapped.  To iterate over the
  * planes which *will* be attached (for ->atomic_check()) see
- * drm_crtc_for_each_pending_plane()
+ * drm_crtc_for_each_pending_plane().
  */
 #define drm_atomic_crtc_for_each_plane(plane, crtc) \
 	drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask)
@@ -171,11 +171,31 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
  *
  * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
  * attached if the specified state is applied.  Useful during (for example)
- * ->atomic_check() operations, to validate the incoming state
+ * ->atomic_check() operations, to validate the incoming state.
  */
 #define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \
 	drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask)
 
+/**
+ * drm_crtc_atomic_state_for_each_plane_state - iterate over attached planes in new state
+ * @plane: the loop cursor
+ * @plane_state: loop cursor for the plane's state, must be const
+ * @crtc_state: the incoming crtc-state
+ *
+ * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
+ * attached if the specified state is applied.  Useful during (for example)
+ * ->atomic_check() operations, to validate the incoming state.
+ *
+ * Compared to just drm_atomic_crtc_state_for_each_plane() this also fills in a
+ * const plane_state. This is useful when a driver just wants to peek at other
+ * active planes on this crtc, but does not need to change it.
+ */
+#define drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) \
+	drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) \
+		for_each_if ((plane_state = \
+			      __drm_atomic_get_current_plane_state((crtc_state)->state, \
+								   plane)))
+
 /*
  * drm_atomic_plane_disabling - check whether a plane is being disabled
  * @plane: plane object
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/38] drm: Consolidate crtc arrays in drm_atomic_state
  2016-06-01 22:06 ` [PATCH 11/38] drm: Consolidate crtc " Daniel Vetter
@ 2016-06-02 14:42   ` Maarten Lankhorst
  2016-06-02 15:20     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 14:42 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 02-06-16 om 00:06 schreef Daniel Vetter:
> It's silly to have 2 mallocs when we could tie these two together.
>
> Also, Gustavo adds another one in his per-crtc out-fence patches. And
> I want to add more stuff here for nonblocking commit helpers.
>
> In the future we can use this to store a pointer to the preceeding
> state, making an atomic update entirely free-standing. This will be
> needed to be able to queue them up with a depth > 1.
Patch 9,10,11:

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-02 14:21   ` [PATCH] " Daniel Vetter
@ 2016-06-02 14:43     ` Maarten Lankhorst
  2016-06-02 14:59       ` Daniel Vetter
  2016-06-02 14:47     ` Eric Engestrom
  1 sibling, 1 reply; 77+ messages in thread
From: Maarten Lankhorst @ 2016-06-02 14:43 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Intel Graphics Development, Daniel Vetter

Op 02-06-16 om 16:21 schreef Daniel Vetter:
> ... and use it in msm&vc4. Again just want to encapsulate
> drm_atomic_state internals a bit.
>
> The const threading is a bit awkward in vc4 since C sucks, but I still
> think it's worth to enforce this. Eventually I want to make all the
> obj->state pointers const too, but that's a lot more work ...
>
> v2: Provide safe macro to wrap up the unsafe helper better, suggested
> by Maarten.
Much better, thanks!

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-02 14:21   ` [PATCH] " Daniel Vetter
  2016-06-02 14:43     ` Maarten Lankhorst
@ 2016-06-02 14:47     ` Eric Engestrom
  1 sibling, 0 replies; 77+ messages in thread
From: Eric Engestrom @ 2016-06-02 14:47 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Thu, Jun 02, 2016 at 04:21:44PM +0200, Daniel Vetter wrote:
> ... and use it in msm&vc4. Again just want to encapsulate
> drm_atomic_state internals a bit.
> 
> The const threading is a bit awkward in vc4 since C sucks, but I still
> think it's worth to enforce this. Eventually I want to make all the
> obj->state pointers const too, but that's a lot more work ...
> 
> v2: Provide safe macro to wrap up the unsafe helper better, suggested
> by Maarten.
> 
> Cc: Eric Anholt <eric@anholt.net>
> Cc: Rob Clark <robdclark@gmail.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 ++-------
>  drivers/gpu/drm/vc4/vc4_crtc.c           | 13 ++----------
>  drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
>  drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
>  include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
>  include/drm/drm_atomic_helper.h          | 24 +++++++++++++++++++--
>  6 files changed, 66 insertions(+), 24 deletions(-)

[...]

> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 92c84e9ab09a..4e97186293be 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
>  	return state->connector_states[index];
>  }
>  
> +/**
> + * __drm_atomic_get_current_plane_state - get current plane state
> + * @state: global atomic state object
> + * @plane: plane to grab
> + *
> + * This function returns the plane state for the given plane, either from
> + * @state, or if the plane isn't part of the atomic state update, from @plane.
> + * This is useful in atomic check callbacks, when drivers need to peek at, but
> + * not change, state of other planes, since it avoids threading an error code
> + * back up the call chain.
> + *
> + * WARNING:
> + *
> + * Note that this function is in general unsafe since it doesn't check for the
> + * required locking for access state structures. Drivers must ensure that it is
> + * save to access the returned state structure through other means. One commone

s/save/safe/
s/commone/common/

> + * example is when planes are fixed to a single CRTC, and the driver knows that
> + * the CRTC locks is held already. In that case holding the CRTC locks gives a
> + * read-lock on all planes connected to that CRTC. But if planes can be
> + * reassigned things get more tricky. In that case it's better to use
> + * drm_atomic_get_plane_state and wire up full error handling.
> + *
> + * Returns:
> + *
> + * Read-only pointer to the current plane state.
> + */
> +static inline const struct drm_plane_state *
> +__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
> +				     struct drm_plane *plane)
> +{
> +	if (state->plane_states[drm_plane_index(plane)])
> +		return state->plane_states[drm_plane_index(plane)];
> +
> +	return plane->state;
> +}
> +
>  int __must_check
>  drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
>  			     struct drm_display_mode *mode);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-06-02 14:43     ` Maarten Lankhorst
@ 2016-06-02 14:59       ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 14:59 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Thu, Jun 02, 2016 at 04:43:51PM +0200, Maarten Lankhorst wrote:
> Op 02-06-16 om 16:21 schreef Daniel Vetter:
> > ... and use it in msm&vc4. Again just want to encapsulate
> > drm_atomic_state internals a bit.
> >
> > The const threading is a bit awkward in vc4 since C sucks, but I still
> > think it's worth to enforce this. Eventually I want to make all the
> > obj->state pointers const too, but that's a lot more work ...
> >
> > v2: Provide safe macro to wrap up the unsafe helper better, suggested
> > by Maarten.
> Much better, thanks!
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Also fixed up the subject and the 2 typos eric spotted and applied it to
drm-misc. Thanks for thefeedback!
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 11/38] drm: Consolidate crtc arrays in drm_atomic_state
  2016-06-02 14:42   ` Maarten Lankhorst
@ 2016-06-02 15:20     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 15:20 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Thu, Jun 02, 2016 at 04:42:07PM +0200, Maarten Lankhorst wrote:
> Op 02-06-16 om 00:06 schreef Daniel Vetter:
> > It's silly to have 2 mallocs when we could tie these two together.
> >
> > Also, Gustavo adds another one in his per-crtc out-fence patches. And
> > I want to add more stuff here for nonblocking commit helpers.
> >
> > In the future we can use this to store a pointer to the preceeding
> > state, making an atomic update entirely free-standing. This will be
> > needed to be able to queue them up with a depth > 1.
> Patch 9,10,11:
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Thanks a lot for your review, applied everything up to this point to
drm-misc.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 12/38] drm/fence: add fence to drm_pending_event
  2016-06-01 22:06 ` [PATCH 12/38] drm/fence: add fence to drm_pending_event Daniel Vetter
@ 2016-06-02 18:49   ` Sean Paul
  2016-06-02 20:15     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Sean Paul @ 2016-06-02 18:49 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Intel Graphics Development, Gustavo Padovan, DRI Development

On Wed, Jun 1, 2016 at 6:06 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> Now a drm_pending_event can either send a real drm_event or signal a
> fence, or both. It allow us to signal via fences when the buffer is
> displayed on the screen. Which in turn means that the previous buffer
> is not in use anymore and can be freed or sent back to another driver
> for processing.
>
> v2: Comments from Daniel Vetter
>         - call fence_signal in drm_send_event_locked()
>         - remove unneeded !e->event check
>
> v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv
> is not set.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> (v2)
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>


I suppose one could argue that the s/destroy/kfree/ change might
warrant a separate change, but the patch is very readable as-is, so:

Reviewed-by: Sean Paul <seanpaul@chromium.org>

> ---
>  drivers/gpu/drm/drm_atomic.c                | 19 +++++++++++++------
>  drivers/gpu/drm/drm_fops.c                  | 16 +++++++++-------
>  drivers/gpu/drm/nouveau/nouveau_usif.c      |  1 -
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  2 +-
>  include/drm/drmP.h                          |  3 ++-
>  5 files changed, 25 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 5093d81f60f7..5e4b820a977c 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1413,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
>   */
>
>  static struct drm_pending_vblank_event *create_vblank_event(
> -               struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
> +               struct drm_device *dev, struct drm_file *file_priv,
> +               struct fence *fence, uint64_t user_data)
>  {
>         struct drm_pending_vblank_event *e = NULL;
>         int ret;
> @@ -1426,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
>         e->event.base.length = sizeof(e->event);
>         e->event.user_data = user_data;
>
> -       ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
> -       if (ret) {
> -               kfree(e);
> -               return NULL;
> +       if (file_priv) {
> +               ret = drm_event_reserve_init(dev, file_priv, &e->base,
> +                                            &e->event.base);
> +               if (ret) {
> +                       kfree(e);
> +                       return NULL;
> +               }
>         }
>
> +       e->base.fence = fence;
> +
>         return e;
>  }
>
> @@ -1671,7 +1677,8 @@ retry:
>                 for_each_crtc_in_state(state, crtc, crtc_state, i) {
>                         struct drm_pending_vblank_event *e;
>
> -                       e = create_vblank_event(dev, file_priv, arg->user_data);
> +                       e = create_vblank_event(dev, file_priv, NULL,
> +                                               arg->user_data);
>                         if (!e) {
>                                 ret = -ENOMEM;
>                                 goto out;
> diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
> index 868871068956..4c4b30f7a9f2 100644
> --- a/drivers/gpu/drm/drm_fops.c
> +++ b/drivers/gpu/drm/drm_fops.c
> @@ -294,7 +294,7 @@ static void drm_events_release(struct drm_file *file_priv)
>         /* Remove unconsumed events */
>         list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
>                 list_del(&e->link);
> -               e->destroy(e);
> +               kfree(e);
>         }
>
>         spin_unlock_irqrestore(&dev->event_lock, flags);
> @@ -525,7 +525,7 @@ put_back_event:
>                         }
>
>                         ret += length;
> -                       e->destroy(e);
> +                       kfree(e);
>                 }
>         }
>         mutex_unlock(&file_priv->event_read_lock);
> @@ -602,9 +602,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
>         list_add(&p->pending_link, &file_priv->pending_event_list);
>         p->file_priv = file_priv;
>
> -       /* we *could* pass this in as arg, but everyone uses kfree: */
> -       p->destroy = (void (*) (struct drm_pending_event *)) kfree;
> -
>         return 0;
>  }
>  EXPORT_SYMBOL(drm_event_reserve_init_locked);
> @@ -667,7 +664,7 @@ void drm_event_cancel_free(struct drm_device *dev,
>                 list_del(&p->pending_link);
>         }
>         spin_unlock_irqrestore(&dev->event_lock, flags);
> -       p->destroy(p);
> +       kfree(p);
>  }
>  EXPORT_SYMBOL(drm_event_cancel_free);
>
> @@ -689,8 +686,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
>  {
>         assert_spin_locked(&dev->event_lock);
>
> +       if (e->fence) {
> +               fence_signal(e->fence);
> +               fence_put(e->fence);
> +       }
> +
>         if (!e->file_priv) {
> -               e->destroy(e);
> +               kfree(e);
>                 return;
>         }
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
> index 675e9e077a95..08f9c6fa0f7f 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_usif.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
> @@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
>         ntfy->p->base.event = &ntfy->p->e.base;
>         ntfy->p->base.file_priv = f;
>         ntfy->p->base.pid = current->pid;
> -       ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
>         ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
>         ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 1c4d5b5a70a2..5567fb43e674 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
>         if (e && e->base.file_priv == file_priv) {
>                 vop->event = NULL;
>
> -               e->base.destroy(&e->base);
> +               kfree(&e->base);
>                 file_priv->event_space += sizeof(e->event);
>         }
>         spin_unlock_irqrestore(&drm->event_lock, flags);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index f51fa4328494..51f751d1c8a4 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -57,6 +57,7 @@
>  #include <linux/types.h>
>  #include <linux/vmalloc.h>
>  #include <linux/workqueue.h>
> +#include <linux/fence.h>
>
>  #include <asm/mman.h>
>  #include <asm/pgalloc.h>
> @@ -283,12 +284,12 @@ struct drm_ioctl_desc {
>  /* Event queued up for userspace to read */
>  struct drm_pending_event {
>         struct drm_event *event;
> +       struct fence *fence;
>         struct list_head link;
>         struct list_head pending_link;
>         struct drm_file *file_priv;
>         pid_t pid; /* pid of requester, no guarantee it's valid by the time
>                       we deliver the event, for tracing only */
> -       void (*destroy)(struct drm_pending_event *event);
>  };
>
>  /* initial implementaton using a linked list - todo hashtab */
> --
> 2.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 12/38] drm/fence: add fence to drm_pending_event
  2016-06-02 18:49   ` Sean Paul
@ 2016-06-02 20:15     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-02 20:15 UTC (permalink / raw)
  To: Sean Paul
  Cc: Daniel Vetter, Intel Graphics Development, Gustavo Padovan,
	DRI Development

On Thu, Jun 02, 2016 at 02:49:13PM -0400, Sean Paul wrote:
> On Wed, Jun 1, 2016 at 6:06 PM, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> >
> > Now a drm_pending_event can either send a real drm_event or signal a
> > fence, or both. It allow us to signal via fences when the buffer is
> > displayed on the screen. Which in turn means that the previous buffer
> > is not in use anymore and can be freed or sent back to another driver
> > for processing.
> >
> > v2: Comments from Daniel Vetter
> >         - call fence_signal in drm_send_event_locked()
> >         - remove unneeded !e->event check
> >
> > v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv
> > is not set.
> >
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> (v2)
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> 
> I suppose one could argue that the s/destroy/kfree/ change might
> warrant a separate change, but the patch is very readable as-is, so:
 
Yeah I got somewhat lazy with this one ;-)

> Reviewed-by: Sean Paul <seanpaul@chromium.org>

Thanks for the review, patch merged to drm-misc.
-Daniel

> 
> > ---
> >  drivers/gpu/drm/drm_atomic.c                | 19 +++++++++++++------
> >  drivers/gpu/drm/drm_fops.c                  | 16 +++++++++-------
> >  drivers/gpu/drm/nouveau/nouveau_usif.c      |  1 -
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  2 +-
> >  include/drm/drmP.h                          |  3 ++-
> >  5 files changed, 25 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 5093d81f60f7..5e4b820a977c 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -1413,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
> >   */
> >
> >  static struct drm_pending_vblank_event *create_vblank_event(
> > -               struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
> > +               struct drm_device *dev, struct drm_file *file_priv,
> > +               struct fence *fence, uint64_t user_data)
> >  {
> >         struct drm_pending_vblank_event *e = NULL;
> >         int ret;
> > @@ -1426,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
> >         e->event.base.length = sizeof(e->event);
> >         e->event.user_data = user_data;
> >
> > -       ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
> > -       if (ret) {
> > -               kfree(e);
> > -               return NULL;
> > +       if (file_priv) {
> > +               ret = drm_event_reserve_init(dev, file_priv, &e->base,
> > +                                            &e->event.base);
> > +               if (ret) {
> > +                       kfree(e);
> > +                       return NULL;
> > +               }
> >         }
> >
> > +       e->base.fence = fence;
> > +
> >         return e;
> >  }
> >
> > @@ -1671,7 +1677,8 @@ retry:
> >                 for_each_crtc_in_state(state, crtc, crtc_state, i) {
> >                         struct drm_pending_vblank_event *e;
> >
> > -                       e = create_vblank_event(dev, file_priv, arg->user_data);
> > +                       e = create_vblank_event(dev, file_priv, NULL,
> > +                                               arg->user_data);
> >                         if (!e) {
> >                                 ret = -ENOMEM;
> >                                 goto out;
> > diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
> > index 868871068956..4c4b30f7a9f2 100644
> > --- a/drivers/gpu/drm/drm_fops.c
> > +++ b/drivers/gpu/drm/drm_fops.c
> > @@ -294,7 +294,7 @@ static void drm_events_release(struct drm_file *file_priv)
> >         /* Remove unconsumed events */
> >         list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
> >                 list_del(&e->link);
> > -               e->destroy(e);
> > +               kfree(e);
> >         }
> >
> >         spin_unlock_irqrestore(&dev->event_lock, flags);
> > @@ -525,7 +525,7 @@ put_back_event:
> >                         }
> >
> >                         ret += length;
> > -                       e->destroy(e);
> > +                       kfree(e);
> >                 }
> >         }
> >         mutex_unlock(&file_priv->event_read_lock);
> > @@ -602,9 +602,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
> >         list_add(&p->pending_link, &file_priv->pending_event_list);
> >         p->file_priv = file_priv;
> >
> > -       /* we *could* pass this in as arg, but everyone uses kfree: */
> > -       p->destroy = (void (*) (struct drm_pending_event *)) kfree;
> > -
> >         return 0;
> >  }
> >  EXPORT_SYMBOL(drm_event_reserve_init_locked);
> > @@ -667,7 +664,7 @@ void drm_event_cancel_free(struct drm_device *dev,
> >                 list_del(&p->pending_link);
> >         }
> >         spin_unlock_irqrestore(&dev->event_lock, flags);
> > -       p->destroy(p);
> > +       kfree(p);
> >  }
> >  EXPORT_SYMBOL(drm_event_cancel_free);
> >
> > @@ -689,8 +686,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
> >  {
> >         assert_spin_locked(&dev->event_lock);
> >
> > +       if (e->fence) {
> > +               fence_signal(e->fence);
> > +               fence_put(e->fence);
> > +       }
> > +
> >         if (!e->file_priv) {
> > -               e->destroy(e);
> > +               kfree(e);
> >                 return;
> >         }
> >
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
> > index 675e9e077a95..08f9c6fa0f7f 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_usif.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
> > @@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
> >         ntfy->p->base.event = &ntfy->p->e.base;
> >         ntfy->p->base.file_priv = f;
> >         ntfy->p->base.pid = current->pid;
> > -       ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
> >         ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
> >         ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
> >
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > index 1c4d5b5a70a2..5567fb43e674 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > @@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
> >         if (e && e->base.file_priv == file_priv) {
> >                 vop->event = NULL;
> >
> > -               e->base.destroy(&e->base);
> > +               kfree(&e->base);
> >                 file_priv->event_space += sizeof(e->event);
> >         }
> >         spin_unlock_irqrestore(&drm->event_lock, flags);
> > diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> > index f51fa4328494..51f751d1c8a4 100644
> > --- a/include/drm/drmP.h
> > +++ b/include/drm/drmP.h
> > @@ -57,6 +57,7 @@
> >  #include <linux/types.h>
> >  #include <linux/vmalloc.h>
> >  #include <linux/workqueue.h>
> > +#include <linux/fence.h>
> >
> >  #include <asm/mman.h>
> >  #include <asm/pgalloc.h>
> > @@ -283,12 +284,12 @@ struct drm_ioctl_desc {
> >  /* Event queued up for userspace to read */
> >  struct drm_pending_event {
> >         struct drm_event *event;
> > +       struct fence *fence;
> >         struct list_head link;
> >         struct list_head pending_link;
> >         struct drm_file *file_priv;
> >         pid_t pid; /* pid of requester, no guarantee it's valid by the time
> >                       we deliver the event, for tracing only */
> > -       void (*destroy)(struct drm_pending_event *event);
> >  };
> >
> >  /* initial implementaton using a linked list - todo hashtab */
> > --
> > 2.8.1
> >
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/38] drm/rcar-du: Use for_each_*_in_state
  2016-06-01 22:06 ` [PATCH 04/38] drm/rcar-du: " Daniel Vetter
  2016-06-02 13:14   ` Maarten Lankhorst
@ 2016-06-02 21:08   ` Laurent Pinchart
  1 sibling, 0 replies; 77+ messages in thread
From: Laurent Pinchart @ 2016-06-02 21:08 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

On Thursday 02 Jun 2016 00:06:27 Daniel Vetter wrote:
> We want to hide drm_atomic_state internals better.
> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
>  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
>  2 files changed, 12 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index e70a4f33d970..f315c55c1f65
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
> {
>  	struct rcar_du_device *rcdu = dev->dev_private;
>  	struct rcar_du_commit *commit;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	unsigned int i;
>  	int ret;
> 
> @@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device
> *dev, /* Wait until all affected CRTCs have completed previous commits and
> * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
> 
>  	spin_lock(&rcdu->commit.wait.lock);
>  	ret = wait_event_interruptible_locked(rcdu->commit.wait,
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index d445e67f78e1..bfe31ca870cc
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> @@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device
> *dev, bool needs_realloc = false;
>  	unsigned int groups = 0;
>  	unsigned int i;
> +	struct drm_plane *drm_plane;
> +	struct drm_plane_state *drm_plane_state;
> 
>  	/* Check if hardware planes need to be reallocated. */
> -	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
> +	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
>  		struct rcar_du_plane_state *plane_state;
>  		struct rcar_du_plane *plane;
>  		unsigned int index;
> 
> -		if (!state->planes[i])
> -			continue;
> -
> -		plane = to_rcar_plane(state->planes[i]);
> -		plane_state = to_rcar_plane_state(state->plane_states[i]);
> +		plane = to_rcar_plane(drm_plane);
> +		plane_state = to_rcar_plane_state(drm_plane_state);
> 
>  		dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
>  			plane->group->index, plane - plane->group->planes);
> @@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device
> *dev, }
> 
>  	/* Reallocate hardware planes for each plane that needs it. */
> -	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
> +	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
>  		struct rcar_du_plane_state *plane_state;
>  		struct rcar_du_plane *plane;
>  		unsigned int crtc_planes;
>  		unsigned int free;
>  		int idx;
> 
> -		if (!state->planes[i])
> -			continue;
> -
> -		plane = to_rcar_plane(state->planes[i]);
> -		plane_state = to_rcar_plane_state(state->plane_states[i]);
> +		plane = to_rcar_plane(drm_plane);
> +		plane_state = to_rcar_plane_state(drm_plane_state);
> 
>  		dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
>  			plane->group->index, plane - plane->group->planes);

-- 
Regards,

Laurent Pinchart

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 06/38] drm/omap: Use for_each_plane_in_state
  2016-06-01 22:06 ` [PATCH 06/38] drm/omap: " Daniel Vetter
  2016-06-02 13:23   ` Maarten Lankhorst
@ 2016-06-02 21:08   ` Laurent Pinchart
  1 sibling, 0 replies; 77+ messages in thread
From: Laurent Pinchart @ 2016-06-02 21:08 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Tomi Valkeinen,
	DRI Development

Hi Daniel,

Thank you for the patch.

On Thursday 02 Jun 2016 00:06:29 Daniel Vetter wrote:
> We want to hide drm_atomic_stat internals a bit better.
> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c
> b/drivers/gpu/drm/omapdrm/omap_drv.c index d86f5479345b..4798ba43ff5b
> 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
>  {
>  	struct omap_drm_private *priv = dev->dev_private;
>  	struct omap_atomic_state_commit *commit;
> -	unsigned int i;
> -	int ret;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	int i, ret;
> 
>  	ret = drm_atomic_helper_prepare_planes(dev, state);
>  	if (ret)
> @@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
>  	/* Wait until all affected CRTCs have completed previous commits and
>  	 * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
> 
>  	wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));

-- 
Regards,

Laurent Pinchart

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

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling
  2016-06-01 22:06 ` [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
@ 2016-06-03 17:43   ` Stefan Agner
  0 siblings, 0 replies; 77+ messages in thread
From: Stefan Agner @ 2016-06-03 17:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On 2016-06-01 15:06, Daniel Vetter wrote:
> No idea how exactly fsl-du commits hw state changes, but here in flush
> is probably the safest place.

The writes to the DCU_UPDATE_MODE register (DCU_UPDATE_MODE_READREG)
commit state changes. There are several callbacks causing a commit, it
seems to me that the current code does not what atomic is asking for,
checking that is on my 2do...

I tested this patch individually, using modesetting driver. Things seem
to work as they did before.
Acked-by: Stefan Agner <stefan@agner.ch>

But I guess to test the non-blocking commit, I would have to apply the
whole patchset...? Do you have it somewhere in a git tree?

--
Stefan

> 
> While at it nuke the dummy functions.
> 
> v2: Be more robust and either arm, when the CRTC is on, or just send
> the event out right away.
> 
> Cc: Stefan Agner <stefan@agner.ch>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 23 +++++++++++------------
>  1 file changed, 11 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
> b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
> index 89c0084c2814..706de3278f1c 100644
> --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
> +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
> @@ -22,20 +22,21 @@
>  #include "fsl_dcu_drm_drv.h"
>  #include "fsl_dcu_drm_plane.h"
>  
> -static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc,
> +static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
>  					  struct drm_crtc_state *old_crtc_state)
>  {
> -}
> +	struct drm_pending_vblank_event *event = crtc->state->event;
>  
> -static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
> -					 struct drm_crtc_state *state)
> -{
> -	return 0;
> -}
> +	if (event) {
> +		crtc->state->event = NULL;
>  
> -static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
> -					  struct drm_crtc_state *old_crtc_state)
> -{
> +		spin_lock_irq(&crtc->dev->event_lock);
> +		if (drm_crtc_vblank_get(crtc) == 0)
> +			drm_crtc_arm_vblank_event(crtc, event);
> +		else
> +			drm_crtc_send_vblank_event(crtc, event);
> +		spin_unlock_irq(&crtc->dev->event_lock);
> +	}
>  }
>  
>  static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
> @@ -117,8 +118,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct
> drm_crtc *crtc)
>  }
>  
>  static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
> -	.atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
> -	.atomic_check = fsl_dcu_drm_crtc_atomic_check,
>  	.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
>  	.disable = fsl_dcu_drm_disable_crtc,
>  	.enable = fsl_dcu_drm_crtc_enable,
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-01 22:06 ` [PATCH 19/38] drm/hisilicon: " Daniel Vetter
@ 2016-06-17  2:09   ` Xinliang Liu
  2016-06-17  7:23     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Xinliang Liu @ 2016-06-17  2:09 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Xinwei Kong,
	DRI Development, Archit Taneja

Hi Daniel,

I have tested your David's drm-next branch[1] which including this patch.
In most time it is ok. But when switching modes or disable/re-enable
mode, it will encounter bellow error msg:
--
[  357.940728] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
[CRTC:24:crtc-0] flip_done timed out
[  368.004962] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
[CRTC:24:crtc-0] flip_done timed out
[  396.064871] INFO: rcu_preempt detected stalls on CPUs/tasks:
[  396.070548]  0-...: (3 GPs behind) idle=f4f/1/0 softirq=4253/4253 fqs=19
[  396.077335]  7-...: (1 GPs behind) idle=71f/140000000000000/0
softirq=2444/2451 fqs=19
[  396.085332]  (detected by 1, t=6028 jiffies, g=3924, c=3923, q=246)
[  396.091600] Task dump for CPU 0:
[  396.094821] swapper/0       R  running task        0     0      0 0x00000002
[  396.101872] Call trace:
[  396.104323] [<ffff000008085bec>] __switch_to+0xa4/0xd4
[  396.109460] [<ffff000008c85000>] __boot_cpu_mode+0x0/0x80
[  396.114852] Task dump for CPU 7:
[  396.118072] Xorg            R  running task        0  1658   1646 0x00000002
[  396.125121] Call trace:
[  396.127562] [<ffff000008085c10>] __switch_to+0xc8/0xd4
[  396.132695] [<ffff800035567110>] 0xffff800035567110
[  396.137569] rcu_preempt kthread starved for 1000 jiffies! g3924
c3923 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
[  396.147130] rcu_preempt     S ffff000008085c10     0     7      2 0x00000000
[  396.154180] Call trace:
[  396.156620] [<ffff000008085c10>] __switch_to+0xc8/0xd4
[  396.161758] [<ffff000008810490>] __schedule+0x188/0x590
[  396.166978] [<ffff0000088108d4>] schedule+0x3c/0xa0
[  396.171851] [<ffff00000881368c>] schedule_timeout+0x104/0x1a4
[  396.177595] [<ffff00000810549c>] rcu_gp_kthread+0x54c/0x814
[  396.183164] [<ffff0000080d3e5c>] kthread+0xd4/0xe8
[  396.187951] [<ffff000008084e10>] ret_from_fork+0x10/0x40
--

Then the console stuck. Any tips for addressing this issue?
I am running a debian system.

[1] git://people.freedesktop.org/~airlied/linux drm-next

Thanks,
-xinliang

On 2 June 2016 at 06:06, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> atomic_flush seems to be the right place, but I'm not entirely sure
> whether this will catch them all. It could be that when disabling the
> crtc we'll miss the vblank.
>
> While at it nuke the dummy functions.
>
> v2: Be more robust and either arm, when the CRTC is on, or just send
> the event out right away.
>
> Cc: Xinliang Liu <xinliang.liu@linaro.org>
> Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> Cc: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Acked-by: Xinliang Liu <xinliang.liu@linaro.org>

> ---
>  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> index fba6372d060e..ed76baad525f 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> @@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
>         acrtc->enable = false;
>  }
>
> -static int ade_crtc_atomic_check(struct drm_crtc *crtc,
> -                                struct drm_crtc_state *state)
> -{
> -       /* do nothing */
> -       return 0;
> -}
> -
>  static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
>  {
>         struct ade_crtc *acrtc = to_ade_crtc(crtc);
> @@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>  {
>         struct ade_crtc *acrtc = to_ade_crtc(crtc);
>         struct ade_hw_ctx *ctx = acrtc->ctx;
> +       struct drm_pending_vblank_event *event = crtc->state->event;
>         void __iomem *base = ctx->base;
>
>         /* only crtc is enabled regs take effect */
> @@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>                 /* flush ade registers */
>                 writel(ADE_ENABLE, base + ADE_EN);
>         }
> +
> +       if (event) {
> +               crtc->state->event = NULL;
> +
> +               spin_lock_irq(&crtc->dev->event_lock);
> +               if (drm_crtc_vblank_get(crtc) == 0)
> +                       drm_crtc_arm_vblank_event(crtc, event);
> +               else
> +                       drm_crtc_send_vblank_event(crtc, event);
> +               spin_unlock_irq(&crtc->dev->event_lock);
> +       }
>  }
>
>  static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
>         .enable         = ade_crtc_enable,
>         .disable        = ade_crtc_disable,
> -       .atomic_check   = ade_crtc_atomic_check,
>         .mode_set_nofb  = ade_crtc_mode_set_nofb,
>         .atomic_begin   = ade_crtc_atomic_begin,
>         .atomic_flush   = ade_crtc_atomic_flush,
> --
> 2.8.1
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-17  2:09   ` Xinliang Liu
@ 2016-06-17  7:23     ` Daniel Vetter
  2016-06-17  8:38       ` Xinliang Liu
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-17  7:23 UTC (permalink / raw)
  To: Xinliang Liu
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Fri, Jun 17, 2016 at 10:09:50AM +0800, Xinliang Liu wrote:
> Hi Daniel,
> 
> I have tested your David's drm-next branch[1] which including this patch.
> In most time it is ok. But when switching modes or disable/re-enable
> mode, it will encounter bellow error msg:
> --
> [  357.940728] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
> [CRTC:24:crtc-0] flip_done timed out
> [  368.004962] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
> [CRTC:24:crtc-0] flip_done timed out
> [  396.064871] INFO: rcu_preempt detected stalls on CPUs/tasks:
> [  396.070548]  0-...: (3 GPs behind) idle=f4f/1/0 softirq=4253/4253 fqs=19
> [  396.077335]  7-...: (1 GPs behind) idle=71f/140000000000000/0
> softirq=2444/2451 fqs=19
> [  396.085332]  (detected by 1, t=6028 jiffies, g=3924, c=3923, q=246)
> [  396.091600] Task dump for CPU 0:
> [  396.094821] swapper/0       R  running task        0     0      0 0x00000002
> [  396.101872] Call trace:
> [  396.104323] [<ffff000008085bec>] __switch_to+0xa4/0xd4
> [  396.109460] [<ffff000008c85000>] __boot_cpu_mode+0x0/0x80
> [  396.114852] Task dump for CPU 7:
> [  396.118072] Xorg            R  running task        0  1658   1646 0x00000002
> [  396.125121] Call trace:
> [  396.127562] [<ffff000008085c10>] __switch_to+0xc8/0xd4
> [  396.132695] [<ffff800035567110>] 0xffff800035567110
> [  396.137569] rcu_preempt kthread starved for 1000 jiffies! g3924
> c3923 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
> [  396.147130] rcu_preempt     S ffff000008085c10     0     7      2 0x00000000
> [  396.154180] Call trace:
> [  396.156620] [<ffff000008085c10>] __switch_to+0xc8/0xd4
> [  396.161758] [<ffff000008810490>] __schedule+0x188/0x590
> [  396.166978] [<ffff0000088108d4>] schedule+0x3c/0xa0
> [  396.171851] [<ffff00000881368c>] schedule_timeout+0x104/0x1a4
> [  396.177595] [<ffff00000810549c>] rcu_gp_kthread+0x54c/0x814
> [  396.183164] [<ffff0000080d3e5c>] kthread+0xd4/0xe8
> [  396.187951] [<ffff000008084e10>] ret_from_fork+0x10/0x40
> --
> 
> Then the console stuck. Any tips for addressing this issue?
> I am running a debian system.
> 
> [1] git://people.freedesktop.org/~airlied/linux drm-next

hisilicon doesn't handle crtc_state->event correctly. Most likely when
shutting down a CRTC if fails to send out that flip event, which means the
waiting for flip_done times out. My patch tried to fix that (it's not
correct, but it did work on other drivers).

From a quick look what's wrong with hisilicon vblank handling:
- You don't call drm_crtc_vblank_on/off, which means the core thinks
  vblanks will keep working even when the CRTC is off. That throws off the
  hack in my patch. You need to put a call to drm_crtc_vblank_off into
  crtc->disable hook, and drm_crtc_vblank_on into crtc->enable.

- While at it please review that the event sending is placed correctly and
  can't race with the new buffers showing up on the screen. The event
  should be signalled at exactly the time the buffers start to get scanned
  out. The important bit is to make sure that even if something races or
  gets delayed that it still happens together.

Cheers, Daniel
> 
> Thanks,
> -xinliang
> 
> On 2 June 2016 at 06:06, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > atomic_flush seems to be the right place, but I'm not entirely sure
> > whether this will catch them all. It could be that when disabling the
> > crtc we'll miss the vblank.
> >
> > While at it nuke the dummy functions.
> >
> > v2: Be more robust and either arm, when the CRTC is on, or just send
> > the event out right away.
> >
> > Cc: Xinliang Liu <xinliang.liu@linaro.org>
> > Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> > Cc: Archit Taneja <architt@codeaurora.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> 
> Acked-by: Xinliang Liu <xinliang.liu@linaro.org>
> 
> > ---
> >  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
> >  1 file changed, 12 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> > index fba6372d060e..ed76baad525f 100644
> > --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> > +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> > @@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
> >         acrtc->enable = false;
> >  }
> >
> > -static int ade_crtc_atomic_check(struct drm_crtc *crtc,
> > -                                struct drm_crtc_state *state)
> > -{
> > -       /* do nothing */
> > -       return 0;
> > -}
> > -
> >  static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
> >  {
> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
> > @@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
> >  {
> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
> >         struct ade_hw_ctx *ctx = acrtc->ctx;
> > +       struct drm_pending_vblank_event *event = crtc->state->event;
> >         void __iomem *base = ctx->base;
> >
> >         /* only crtc is enabled regs take effect */
> > @@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
> >                 /* flush ade registers */
> >                 writel(ADE_ENABLE, base + ADE_EN);
> >         }
> > +
> > +       if (event) {
> > +               crtc->state->event = NULL;
> > +
> > +               spin_lock_irq(&crtc->dev->event_lock);
> > +               if (drm_crtc_vblank_get(crtc) == 0)
> > +                       drm_crtc_arm_vblank_event(crtc, event);
> > +               else
> > +                       drm_crtc_send_vblank_event(crtc, event);
> > +               spin_unlock_irq(&crtc->dev->event_lock);
> > +       }
> >  }
> >
> >  static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
> >         .enable         = ade_crtc_enable,
> >         .disable        = ade_crtc_disable,
> > -       .atomic_check   = ade_crtc_atomic_check,
> >         .mode_set_nofb  = ade_crtc_mode_set_nofb,
> >         .atomic_begin   = ade_crtc_atomic_begin,
> >         .atomic_flush   = ade_crtc_atomic_flush,
> > --
> > 2.8.1
> >

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-17  7:23     ` Daniel Vetter
@ 2016-06-17  8:38       ` Xinliang Liu
  2016-06-17 12:24         ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Xinliang Liu @ 2016-06-17  8:38 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

Hi,

On 17 June 2016 at 15:23, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Jun 17, 2016 at 10:09:50AM +0800, Xinliang Liu wrote:
>> Hi Daniel,
>>
>> I have tested your David's drm-next branch[1] which including this patch.
>> In most time it is ok. But when switching modes or disable/re-enable
>> mode, it will encounter bellow error msg:
>> --
>> [  357.940728] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
>> [CRTC:24:crtc-0] flip_done timed out
>> [  368.004962] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
>> [CRTC:24:crtc-0] flip_done timed out
>> [  396.064871] INFO: rcu_preempt detected stalls on CPUs/tasks:
>> [  396.070548]  0-...: (3 GPs behind) idle=f4f/1/0 softirq=4253/4253 fqs=19
>> [  396.077335]  7-...: (1 GPs behind) idle=71f/140000000000000/0
>> softirq=2444/2451 fqs=19
>> [  396.085332]  (detected by 1, t=6028 jiffies, g=3924, c=3923, q=246)
>> [  396.091600] Task dump for CPU 0:
>> [  396.094821] swapper/0       R  running task        0     0      0 0x00000002
>> [  396.101872] Call trace:
>> [  396.104323] [<ffff000008085bec>] __switch_to+0xa4/0xd4
>> [  396.109460] [<ffff000008c85000>] __boot_cpu_mode+0x0/0x80
>> [  396.114852] Task dump for CPU 7:
>> [  396.118072] Xorg            R  running task        0  1658   1646 0x00000002
>> [  396.125121] Call trace:
>> [  396.127562] [<ffff000008085c10>] __switch_to+0xc8/0xd4
>> [  396.132695] [<ffff800035567110>] 0xffff800035567110
>> [  396.137569] rcu_preempt kthread starved for 1000 jiffies! g3924
>> c3923 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
>> [  396.147130] rcu_preempt     S ffff000008085c10     0     7      2 0x00000000
>> [  396.154180] Call trace:
>> [  396.156620] [<ffff000008085c10>] __switch_to+0xc8/0xd4
>> [  396.161758] [<ffff000008810490>] __schedule+0x188/0x590
>> [  396.166978] [<ffff0000088108d4>] schedule+0x3c/0xa0
>> [  396.171851] [<ffff00000881368c>] schedule_timeout+0x104/0x1a4
>> [  396.177595] [<ffff00000810549c>] rcu_gp_kthread+0x54c/0x814
>> [  396.183164] [<ffff0000080d3e5c>] kthread+0xd4/0xe8
>> [  396.187951] [<ffff000008084e10>] ret_from_fork+0x10/0x40
>> --
>>
>> Then the console stuck. Any tips for addressing this issue?
>> I am running a debian system.
>>
>> [1] git://people.freedesktop.org/~airlied/linux drm-next
>
> hisilicon doesn't handle crtc_state->event correctly. Most likely when
> shutting down a CRTC if fails to send out that flip event, which means the
> waiting for flip_done times out. My patch tried to fix that (it's not
> correct, but it did work on other drivers).
>
> From a quick look what's wrong with hisilicon vblank handling:
> - You don't call drm_crtc_vblank_on/off, which means the core thinks
>   vblanks will keep working even when the CRTC is off. That throws off the
>   hack in my patch. You need to put a call to drm_crtc_vblank_off into
>   crtc->disable hook, and drm_crtc_vblank_on into crtc->enable.

Yes, this is really a problem. I will add drm_crtc_vblank_on/off into
 crtc->disable/enable hook.
And try.

>
> - While at it please review that the event sending is placed correctly and
>   can't race with the new buffers showing up on the screen. The event
>   should be signalled at exactly the time the buffers start to get scanned
>   out. The important bit is to make sure that even if something races or
>   gets delayed that it still happens together.

Our display controller has a interrupt to indicate that  one
commit/flip is taken effect in hardware.
Should I put the sending event in this interrupt handler?

Thanks,
-xinliang

>
> Cheers, Daniel
>>
>> Thanks,
>> -xinliang
>>
>> On 2 June 2016 at 06:06, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>> > atomic_flush seems to be the right place, but I'm not entirely sure
>> > whether this will catch them all. It could be that when disabling the
>> > crtc we'll miss the vblank.
>> >
>> > While at it nuke the dummy functions.
>> >
>> > v2: Be more robust and either arm, when the CRTC is on, or just send
>> > the event out right away.
>> >
>> > Cc: Xinliang Liu <xinliang.liu@linaro.org>
>> > Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
>> > Cc: Archit Taneja <architt@codeaurora.org>
>> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>
>> Acked-by: Xinliang Liu <xinliang.liu@linaro.org>
>>
>> > ---
>> >  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
>> >  1 file changed, 12 insertions(+), 8 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> > index fba6372d060e..ed76baad525f 100644
>> > --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> > +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> > @@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
>> >         acrtc->enable = false;
>> >  }
>> >
>> > -static int ade_crtc_atomic_check(struct drm_crtc *crtc,
>> > -                                struct drm_crtc_state *state)
>> > -{
>> > -       /* do nothing */
>> > -       return 0;
>> > -}
>> > -
>> >  static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
>> >  {
>> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
>> > @@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>> >  {
>> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
>> >         struct ade_hw_ctx *ctx = acrtc->ctx;
>> > +       struct drm_pending_vblank_event *event = crtc->state->event;
>> >         void __iomem *base = ctx->base;
>> >
>> >         /* only crtc is enabled regs take effect */
>> > @@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>> >                 /* flush ade registers */
>> >                 writel(ADE_ENABLE, base + ADE_EN);
>> >         }
>> > +
>> > +       if (event) {
>> > +               crtc->state->event = NULL;
>> > +
>> > +               spin_lock_irq(&crtc->dev->event_lock);
>> > +               if (drm_crtc_vblank_get(crtc) == 0)
>> > +                       drm_crtc_arm_vblank_event(crtc, event);
>> > +               else
>> > +                       drm_crtc_send_vblank_event(crtc, event);
>> > +               spin_unlock_irq(&crtc->dev->event_lock);
>> > +       }
>> >  }
>> >
>> >  static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
>> >         .enable         = ade_crtc_enable,
>> >         .disable        = ade_crtc_disable,
>> > -       .atomic_check   = ade_crtc_atomic_check,
>> >         .mode_set_nofb  = ade_crtc_mode_set_nofb,
>> >         .atomic_begin   = ade_crtc_atomic_begin,
>> >         .atomic_flush   = ade_crtc_atomic_flush,
>> > --
>> > 2.8.1
>> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions
  2016-06-01 22:07 ` [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions Daniel Vetter
@ 2016-06-17 10:04   ` Benjamin Gaignard
  2016-06-17 12:27     ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Benjamin Gaignard @ 2016-06-17 10:04 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development, DRI Development

Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>

2016-06-02 0:07 GMT+02:00 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Atomic drivers are supposed to do hw/sw state reset with the
> drm_mode_config_reset() call right above it.
>
> Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/sti/sti_drv.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index dd2c400c4a46..26aa85d4b872 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -279,7 +279,6 @@ static int sti_load(struct drm_device *dev, unsigned long flags)
>
>         drm_mode_config_reset(dev);
>
> -       drm_helper_disable_unused_functions(dev);
>         drm_fbdev_cma_init(dev, 32,
>                            dev->mode_config.num_crtc,
>                            dev->mode_config.num_connector);
> --
> 2.8.1
>



-- 
Benjamin Gaignard

Graphic Working Group

Linaro.org │ Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-17  8:38       ` Xinliang Liu
@ 2016-06-17 12:24         ` Daniel Vetter
  2016-06-21  1:32           ` Xinliang Liu
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:24 UTC (permalink / raw)
  To: Xinliang Liu
  Cc: Archit Taneja, Daniel Vetter, Intel Graphics Development,
	DRI Development, Xinwei Kong, Daniel Vetter

On Fri, Jun 17, 2016 at 04:38:06PM +0800, Xinliang Liu wrote:
> Hi,
> 
> On 17 June 2016 at 15:23, Daniel Vetter <daniel@ffwll.ch> wrote:
> > On Fri, Jun 17, 2016 at 10:09:50AM +0800, Xinliang Liu wrote:
> >> Hi Daniel,
> >>
> >> I have tested your David's drm-next branch[1] which including this patch.
> >> In most time it is ok. But when switching modes or disable/re-enable
> >> mode, it will encounter bellow error msg:
> >> --
> >> [  357.940728] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
> >> [CRTC:24:crtc-0] flip_done timed out
> >> [  368.004962] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
> >> [CRTC:24:crtc-0] flip_done timed out
> >> [  396.064871] INFO: rcu_preempt detected stalls on CPUs/tasks:
> >> [  396.070548]  0-...: (3 GPs behind) idle=f4f/1/0 softirq=4253/4253 fqs=19
> >> [  396.077335]  7-...: (1 GPs behind) idle=71f/140000000000000/0
> >> softirq=2444/2451 fqs=19
> >> [  396.085332]  (detected by 1, t=6028 jiffies, g=3924, c=3923, q=246)
> >> [  396.091600] Task dump for CPU 0:
> >> [  396.094821] swapper/0       R  running task        0     0      0 0x00000002
> >> [  396.101872] Call trace:
> >> [  396.104323] [<ffff000008085bec>] __switch_to+0xa4/0xd4
> >> [  396.109460] [<ffff000008c85000>] __boot_cpu_mode+0x0/0x80
> >> [  396.114852] Task dump for CPU 7:
> >> [  396.118072] Xorg            R  running task        0  1658   1646 0x00000002
> >> [  396.125121] Call trace:
> >> [  396.127562] [<ffff000008085c10>] __switch_to+0xc8/0xd4
> >> [  396.132695] [<ffff800035567110>] 0xffff800035567110
> >> [  396.137569] rcu_preempt kthread starved for 1000 jiffies! g3924
> >> c3923 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
> >> [  396.147130] rcu_preempt     S ffff000008085c10     0     7      2 0x00000000
> >> [  396.154180] Call trace:
> >> [  396.156620] [<ffff000008085c10>] __switch_to+0xc8/0xd4
> >> [  396.161758] [<ffff000008810490>] __schedule+0x188/0x590
> >> [  396.166978] [<ffff0000088108d4>] schedule+0x3c/0xa0
> >> [  396.171851] [<ffff00000881368c>] schedule_timeout+0x104/0x1a4
> >> [  396.177595] [<ffff00000810549c>] rcu_gp_kthread+0x54c/0x814
> >> [  396.183164] [<ffff0000080d3e5c>] kthread+0xd4/0xe8
> >> [  396.187951] [<ffff000008084e10>] ret_from_fork+0x10/0x40
> >> --
> >>
> >> Then the console stuck. Any tips for addressing this issue?
> >> I am running a debian system.
> >>
> >> [1] git://people.freedesktop.org/~airlied/linux drm-next
> >
> > hisilicon doesn't handle crtc_state->event correctly. Most likely when
> > shutting down a CRTC if fails to send out that flip event, which means the
> > waiting for flip_done times out. My patch tried to fix that (it's not
> > correct, but it did work on other drivers).
> >
> > From a quick look what's wrong with hisilicon vblank handling:
> > - You don't call drm_crtc_vblank_on/off, which means the core thinks
> >   vblanks will keep working even when the CRTC is off. That throws off the
> >   hack in my patch. You need to put a call to drm_crtc_vblank_off into
> >   crtc->disable hook, and drm_crtc_vblank_on into crtc->enable.
> 
> Yes, this is really a problem. I will add drm_crtc_vblank_on/off into
>  crtc->disable/enable hook.
> And try.
> 
> >
> > - While at it please review that the event sending is placed correctly and
> >   can't race with the new buffers showing up on the screen. The event
> >   should be signalled at exactly the time the buffers start to get scanned
> >   out. The important bit is to make sure that even if something races or
> >   gets delayed that it still happens together.
> 
> Our display controller has a interrupt to indicate that  one
> commit/flip is taken effect in hardware.
> Should I put the sending event in this interrupt handler?

Yes, that would be perfect. So instead of the drm_crtc_arm_vblank_event
you put the event into a driver-private slot where the irq handler can
pick it up and send it out using drm_crtc_send_vblank_event.

Two important details:
- You need to arm the event this way before the hw can fire this special
  interrupt, so probably somewhere in atomic_begin.
- the drm_crtc_send_vblank_event must be called after
  drm_crtc_handle_vblank, because otherwise the vblank timestamp isn't
  properly updated.

Cheers, Daniel

> 
> Thanks,
> -xinliang
> 
> >
> > Cheers, Daniel
> >>
> >> Thanks,
> >> -xinliang
> >>
> >> On 2 June 2016 at 06:06, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> >> > atomic_flush seems to be the right place, but I'm not entirely sure
> >> > whether this will catch them all. It could be that when disabling the
> >> > crtc we'll miss the vblank.
> >> >
> >> > While at it nuke the dummy functions.
> >> >
> >> > v2: Be more robust and either arm, when the CRTC is on, or just send
> >> > the event out right away.
> >> >
> >> > Cc: Xinliang Liu <xinliang.liu@linaro.org>
> >> > Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> >> > Cc: Archit Taneja <architt@codeaurora.org>
> >> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>
> >> Acked-by: Xinliang Liu <xinliang.liu@linaro.org>
> >>
> >> > ---
> >> >  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
> >> >  1 file changed, 12 insertions(+), 8 deletions(-)
> >> >
> >> > diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> >> > index fba6372d060e..ed76baad525f 100644
> >> > --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> >> > +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
> >> > @@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
> >> >         acrtc->enable = false;
> >> >  }
> >> >
> >> > -static int ade_crtc_atomic_check(struct drm_crtc *crtc,
> >> > -                                struct drm_crtc_state *state)
> >> > -{
> >> > -       /* do nothing */
> >> > -       return 0;
> >> > -}
> >> > -
> >> >  static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
> >> >  {
> >> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
> >> > @@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
> >> >  {
> >> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
> >> >         struct ade_hw_ctx *ctx = acrtc->ctx;
> >> > +       struct drm_pending_vblank_event *event = crtc->state->event;
> >> >         void __iomem *base = ctx->base;
> >> >
> >> >         /* only crtc is enabled regs take effect */
> >> > @@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
> >> >                 /* flush ade registers */
> >> >                 writel(ADE_ENABLE, base + ADE_EN);
> >> >         }
> >> > +
> >> > +       if (event) {
> >> > +               crtc->state->event = NULL;
> >> > +
> >> > +               spin_lock_irq(&crtc->dev->event_lock);
> >> > +               if (drm_crtc_vblank_get(crtc) == 0)
> >> > +                       drm_crtc_arm_vblank_event(crtc, event);
> >> > +               else
> >> > +                       drm_crtc_send_vblank_event(crtc, event);
> >> > +               spin_unlock_irq(&crtc->dev->event_lock);
> >> > +       }
> >> >  }
> >> >
> >> >  static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
> >> >         .enable         = ade_crtc_enable,
> >> >         .disable        = ade_crtc_disable,
> >> > -       .atomic_check   = ade_crtc_atomic_check,
> >> >         .mode_set_nofb  = ade_crtc_mode_set_nofb,
> >> >         .atomic_begin   = ade_crtc_atomic_begin,
> >> >         .atomic_flush   = ade_crtc_atomic_flush,
> >> > --
> >> > 2.8.1
> >> >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions
  2016-06-17 10:04   ` Benjamin Gaignard
@ 2016-06-17 12:27     ` Daniel Vetter
  0 siblings, 0 replies; 77+ messages in thread
From: Daniel Vetter @ 2016-06-17 12:27 UTC (permalink / raw)
  To: Benjamin Gaignard
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Fri, Jun 17, 2016 at 12:04:16PM +0200, Benjamin Gaignard wrote:
> Acked-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>

Applied to drm-misc.
-Daniel

> 
> 2016-06-02 0:07 GMT+02:00 Daniel Vetter <daniel.vetter@ffwll.ch>:
> > Atomic drivers are supposed to do hw/sw state reset with the
> > drm_mode_config_reset() call right above it.
> >
> > Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/sti/sti_drv.c | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> > index dd2c400c4a46..26aa85d4b872 100644
> > --- a/drivers/gpu/drm/sti/sti_drv.c
> > +++ b/drivers/gpu/drm/sti/sti_drv.c
> > @@ -279,7 +279,6 @@ static int sti_load(struct drm_device *dev, unsigned long flags)
> >
> >         drm_mode_config_reset(dev);
> >
> > -       drm_helper_disable_unused_functions(dev);
> >         drm_fbdev_cma_init(dev, 32,
> >                            dev->mode_config.num_crtc,
> >                            dev->mode_config.num_connector);
> > --
> > 2.8.1
> >
> 
> 
> 
> -- 
> Benjamin Gaignard
> 
> Graphic Working Group
> 
> Linaro.org │ Open source software for ARM SoCs
> 
> Follow Linaro: Facebook | Twitter | Blog

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-17 12:24         ` Daniel Vetter
@ 2016-06-21  1:32           ` Xinliang Liu
  2016-06-21  7:19             ` Daniel Vetter
  0 siblings, 1 reply; 77+ messages in thread
From: Xinliang Liu @ 2016-06-21  1:32 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Archit Taneja, Daniel Vetter, Intel Graphics Development,
	DRI Development, Xinwei Kong, Daniel Vetter

On 17 June 2016 at 20:24, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Fri, Jun 17, 2016 at 04:38:06PM +0800, Xinliang Liu wrote:
>> Hi,
>>
>> On 17 June 2016 at 15:23, Daniel Vetter <daniel@ffwll.ch> wrote:
>> > On Fri, Jun 17, 2016 at 10:09:50AM +0800, Xinliang Liu wrote:
>> >> Hi Daniel,
>> >>
>> >> I have tested your David's drm-next branch[1] which including this patch.
>> >> In most time it is ok. But when switching modes or disable/re-enable
>> >> mode, it will encounter bellow error msg:
>> >> --
>> >> [  357.940728] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
>> >> [CRTC:24:crtc-0] flip_done timed out
>> >> [  368.004962] [drm:drm_atomic_helper_commit_cleanup_done] *ERROR*
>> >> [CRTC:24:crtc-0] flip_done timed out
>> >> [  396.064871] INFO: rcu_preempt detected stalls on CPUs/tasks:
>> >> [  396.070548]  0-...: (3 GPs behind) idle=f4f/1/0 softirq=4253/4253 fqs=19
>> >> [  396.077335]  7-...: (1 GPs behind) idle=71f/140000000000000/0
>> >> softirq=2444/2451 fqs=19
>> >> [  396.085332]  (detected by 1, t=6028 jiffies, g=3924, c=3923, q=246)
>> >> [  396.091600] Task dump for CPU 0:
>> >> [  396.094821] swapper/0       R  running task        0     0      0 0x00000002
>> >> [  396.101872] Call trace:
>> >> [  396.104323] [<ffff000008085bec>] __switch_to+0xa4/0xd4
>> >> [  396.109460] [<ffff000008c85000>] __boot_cpu_mode+0x0/0x80
>> >> [  396.114852] Task dump for CPU 7:
>> >> [  396.118072] Xorg            R  running task        0  1658   1646 0x00000002
>> >> [  396.125121] Call trace:
>> >> [  396.127562] [<ffff000008085c10>] __switch_to+0xc8/0xd4
>> >> [  396.132695] [<ffff800035567110>] 0xffff800035567110
>> >> [  396.137569] rcu_preempt kthread starved for 1000 jiffies! g3924
>> >> c3923 f0x0 RCU_GP_WAIT_FQS(3) ->state=0x1
>> >> [  396.147130] rcu_preempt     S ffff000008085c10     0     7      2 0x00000000
>> >> [  396.154180] Call trace:
>> >> [  396.156620] [<ffff000008085c10>] __switch_to+0xc8/0xd4
>> >> [  396.161758] [<ffff000008810490>] __schedule+0x188/0x590
>> >> [  396.166978] [<ffff0000088108d4>] schedule+0x3c/0xa0
>> >> [  396.171851] [<ffff00000881368c>] schedule_timeout+0x104/0x1a4
>> >> [  396.177595] [<ffff00000810549c>] rcu_gp_kthread+0x54c/0x814
>> >> [  396.183164] [<ffff0000080d3e5c>] kthread+0xd4/0xe8
>> >> [  396.187951] [<ffff000008084e10>] ret_from_fork+0x10/0x40
>> >> --
>> >>
>> >> Then the console stuck. Any tips for addressing this issue?
>> >> I am running a debian system.
>> >>
>> >> [1] git://people.freedesktop.org/~airlied/linux drm-next
>> >
>> > hisilicon doesn't handle crtc_state->event correctly. Most likely when
>> > shutting down a CRTC if fails to send out that flip event, which means the
>> > waiting for flip_done times out. My patch tried to fix that (it's not
>> > correct, but it did work on other drivers).
>> >
>> > From a quick look what's wrong with hisilicon vblank handling:
>> > - You don't call drm_crtc_vblank_on/off, which means the core thinks
>> >   vblanks will keep working even when the CRTC is off. That throws off the
>> >   hack in my patch. You need to put a call to drm_crtc_vblank_off into
>> >   crtc->disable hook, and drm_crtc_vblank_on into crtc->enable.
>>
>> Yes, this is really a problem. I will add drm_crtc_vblank_on/off into
>>  crtc->disable/enable hook.
>> And try.
>>
>> >
>> > - While at it please review that the event sending is placed correctly and
>> >   can't race with the new buffers showing up on the screen. The event
>> >   should be signalled at exactly the time the buffers start to get scanned
>> >   out. The important bit is to make sure that even if something races or
>> >   gets delayed that it still happens together.
>>
>> Our display controller has a interrupt to indicate that  one
>> commit/flip is taken effect in hardware.
>> Should I put the sending event in this interrupt handler?
>
> Yes, that would be perfect. So instead of the drm_crtc_arm_vblank_event
> you put the event into a driver-private slot where the irq handler can
> pick it up and send it out using drm_crtc_send_vblank_event.
>
> Two important details:
> - You need to arm the event this way before the hw can fire this special
>   interrupt, so probably somewhere in atomic_begin.
> - the drm_crtc_send_vblank_event must be called after
>   drm_crtc_handle_vblank, because otherwise the vblank timestamp isn't
>   properly updated.

When adding drm_crtc_vblank_on/off into crtc->disable/enable hook,
The "flip_done timed out" error msg has gone. It seems that
drm_crtc_vblank_off will send out all the pending event.
I will send out this patch for review soon.

My understanding is that drm_crtc_arm_vblank_event work together with
drm_crtc_handle_vblank (called in vblank interrupt).
Arm the event first in somewhere(like atomic_begin/flush) and then
send it out throuth drm_crtc_handle_vblank in vblank interrupt.
In the other way, drm_crtc_send_vblank_event work together with flip
interrupt. That's means event will be sent in flip interrupt
immediately.
Is this right?

Best,
-xinliang

>
> Cheers, Daniel
>
>>
>> Thanks,
>> -xinliang
>>
>> >
>> > Cheers, Daniel
>> >>
>> >> Thanks,
>> >> -xinliang
>> >>
>> >> On 2 June 2016 at 06:06, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
>> >> > atomic_flush seems to be the right place, but I'm not entirely sure
>> >> > whether this will catch them all. It could be that when disabling the
>> >> > crtc we'll miss the vblank.
>> >> >
>> >> > While at it nuke the dummy functions.
>> >> >
>> >> > v2: Be more robust and either arm, when the CRTC is on, or just send
>> >> > the event out right away.
>> >> >
>> >> > Cc: Xinliang Liu <xinliang.liu@linaro.org>
>> >> > Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
>> >> > Cc: Archit Taneja <architt@codeaurora.org>
>> >> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>> >>
>> >> Acked-by: Xinliang Liu <xinliang.liu@linaro.org>
>> >>
>> >> > ---
>> >> >  drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
>> >> >  1 file changed, 12 insertions(+), 8 deletions(-)
>> >> >
>> >> > diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> >> > index fba6372d060e..ed76baad525f 100644
>> >> > --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> >> > +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
>> >> > @@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
>> >> >         acrtc->enable = false;
>> >> >  }
>> >> >
>> >> > -static int ade_crtc_atomic_check(struct drm_crtc *crtc,
>> >> > -                                struct drm_crtc_state *state)
>> >> > -{
>> >> > -       /* do nothing */
>> >> > -       return 0;
>> >> > -}
>> >> > -
>> >> >  static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
>> >> >  {
>> >> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
>> >> > @@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>> >> >  {
>> >> >         struct ade_crtc *acrtc = to_ade_crtc(crtc);
>> >> >         struct ade_hw_ctx *ctx = acrtc->ctx;
>> >> > +       struct drm_pending_vblank_event *event = crtc->state->event;
>> >> >         void __iomem *base = ctx->base;
>> >> >
>> >> >         /* only crtc is enabled regs take effect */
>> >> > @@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
>> >> >                 /* flush ade registers */
>> >> >                 writel(ADE_ENABLE, base + ADE_EN);
>> >> >         }
>> >> > +
>> >> > +       if (event) {
>> >> > +               crtc->state->event = NULL;
>> >> > +
>> >> > +               spin_lock_irq(&crtc->dev->event_lock);
>> >> > +               if (drm_crtc_vblank_get(crtc) == 0)
>> >> > +                       drm_crtc_arm_vblank_event(crtc, event);
>> >> > +               else
>> >> > +                       drm_crtc_send_vblank_event(crtc, event);
>> >> > +               spin_unlock_irq(&crtc->dev->event_lock);
>> >> > +       }
>> >> >  }
>> >> >
>> >> >  static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
>> >> >         .enable         = ade_crtc_enable,
>> >> >         .disable        = ade_crtc_disable,
>> >> > -       .atomic_check   = ade_crtc_atomic_check,
>> >> >         .mode_set_nofb  = ade_crtc_mode_set_nofb,
>> >> >         .atomic_begin   = ade_crtc_atomic_begin,
>> >> >         .atomic_flush   = ade_crtc_atomic_flush,
>> >> > --
>> >> > 2.8.1
>> >> >
>> >
>> > --
>> > Daniel Vetter
>> > Software Engineer, Intel Corporation
>> > http://blog.ffwll.ch
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-21  1:32           ` Xinliang Liu
@ 2016-06-21  7:19             ` Daniel Vetter
  2016-06-22  2:50               ` Xinliang Liu
  0 siblings, 1 reply; 77+ messages in thread
From: Daniel Vetter @ 2016-06-21  7:19 UTC (permalink / raw)
  To: Xinliang Liu; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, Jun 21, 2016 at 3:32 AM, Xinliang Liu <xinliang.liu@linaro.org> wrote:
> My understanding is that drm_crtc_arm_vblank_event work together with
> drm_crtc_handle_vblank (called in vblank interrupt).
> Arm the event first in somewhere(like atomic_begin/flush) and then
> send it out throuth drm_crtc_handle_vblank in vblank interrupt.
> In the other way, drm_crtc_send_vblank_event work together with flip
> interrupt. That's means event will be sent in flip interrupt
> immediately.
> Is this right?

First part is right. Second part about drm_crtc_send_vblank event just
sends out the vblank directly (using the last recorded vblank). The
vblank subsystem doesn't itself interact with any interrupt.

Note that there's kerneldoc for all of this. Please make sure it does
describe things sufficiently well, and if not please send in patches
to improve them.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 19/38] drm/hisilicon: Implement some semblance of vblank event handling
  2016-06-21  7:19             ` Daniel Vetter
@ 2016-06-22  2:50               ` Xinliang Liu
  0 siblings, 0 replies; 77+ messages in thread
From: Xinliang Liu @ 2016-06-22  2:50 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Xinwei Kong,
	DRI Development, Archit Taneja

On 21 June 2016 at 15:19, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Jun 21, 2016 at 3:32 AM, Xinliang Liu <xinliang.liu@linaro.org> wrote:
>> My understanding is that drm_crtc_arm_vblank_event work together with
>> drm_crtc_handle_vblank (called in vblank interrupt).
>> Arm the event first in somewhere(like atomic_begin/flush) and then
>> send it out throuth drm_crtc_handle_vblank in vblank interrupt.
>> In the other way, drm_crtc_send_vblank_event work together with flip
>> interrupt. That's means event will be sent in flip interrupt
>> immediately.
>> Is this right?
>
> First part is right. Second part about drm_crtc_send_vblank event just
> sends out the vblank directly (using the last recorded vblank). The
> vblank subsystem doesn't itself interact with any interrupt.
>
> Note that there's kerneldoc for all of this. Please make sure it does
> describe things sufficiently well, and if not please send in patches
> to improve them.

Ok, I will take a look at the doc.

Thanks,
-xinliang

> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2016-06-22  2:50 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-01 22:06 [PATCH 00/38] nonblocking atomic commits for everyone! Daniel Vetter
2016-06-01 22:06 ` [PATCH 01/38] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
2016-06-02 11:26   ` Maarten Lankhorst
2016-06-01 22:06 ` [PATCH 02/38] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
2016-06-02 11:25   ` Maarten Lankhorst
2016-06-02 13:40     ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 03/38] drm/msm: Use for_each_*_in_state Daniel Vetter
2016-06-02 13:13   ` Maarten Lankhorst
2016-06-01 22:06 ` [PATCH 04/38] drm/rcar-du: " Daniel Vetter
2016-06-02 13:14   ` Maarten Lankhorst
2016-06-02 13:48     ` Daniel Vetter
2016-06-02 21:08   ` Laurent Pinchart
2016-06-01 22:06 ` [PATCH 05/38] drm/vc4: Use for_each_plane_in_state Daniel Vetter
2016-06-02 13:15   ` Maarten Lankhorst
2016-06-01 22:06 ` [PATCH 06/38] drm/omap: " Daniel Vetter
2016-06-02 13:23   ` Maarten Lankhorst
2016-06-02 13:50     ` Daniel Vetter
2016-06-02 21:08   ` Laurent Pinchart
2016-06-01 22:06 ` [PATCH 07/38] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
2016-06-02 13:23   ` Maarten Lankhorst
2016-06-01 22:06 ` [PATCH 08/38] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
2016-06-02 13:41   ` Maarten Lankhorst
2016-06-02 14:21   ` [PATCH] " Daniel Vetter
2016-06-02 14:43     ` Maarten Lankhorst
2016-06-02 14:59       ` Daniel Vetter
2016-06-02 14:47     ` Eric Engestrom
2016-06-01 22:06 ` [PATCH 09/38] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
2016-06-01 22:06 ` [PATCH 10/38] drm: Consolidate plane " Daniel Vetter
2016-06-01 22:06 ` [PATCH 11/38] drm: Consolidate crtc " Daniel Vetter
2016-06-02 14:42   ` Maarten Lankhorst
2016-06-02 15:20     ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 12/38] drm/fence: add fence to drm_pending_event Daniel Vetter
2016-06-02 18:49   ` Sean Paul
2016-06-02 20:15     ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 13/38] drm/atomic-helper: Massage swap_state signature somewhat Daniel Vetter
2016-06-01 22:06 ` [PATCH 14/38] drm/arc: Nuke event_list Daniel Vetter
2016-06-01 22:06   ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 15/38] drm/arc: Actually bother with handling atomic events Daniel Vetter
2016-06-01 22:06   ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 16/38] drm/hdlcd: Clean up crtc hooks Daniel Vetter
2016-06-02 13:33   ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 17/38] drm/hdlcd: Fix up crtc_state->event handling Daniel Vetter
2016-06-01 22:06 ` [PATCH 18/38] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
2016-06-03 17:43   ` Stefan Agner
2016-06-01 22:06 ` [PATCH 19/38] drm/hisilicon: " Daniel Vetter
2016-06-17  2:09   ` Xinliang Liu
2016-06-17  7:23     ` Daniel Vetter
2016-06-17  8:38       ` Xinliang Liu
2016-06-17 12:24         ` Daniel Vetter
2016-06-21  1:32           ` Xinliang Liu
2016-06-21  7:19             ` Daniel Vetter
2016-06-22  2:50               ` Xinliang Liu
2016-06-01 22:06 ` [PATCH 20/38] drm/sun4i: " Daniel Vetter
2016-06-01 22:06 ` [PATCH 21/38] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
2016-06-01 22:06 ` [PATCH 22/38] drm/atomic-helper: nonblocking commit support Daniel Vetter
2016-06-02  9:56   ` [PATCH 1/2] drm/atomic: Add struct drm_crtc_commit to track async updates Daniel Vetter
2016-06-02  9:56     ` [PATCH 2/2] drm/atomic-helper: nonblocking commit support Daniel Vetter
2016-06-01 22:06 ` [PATCH 23/38] drm/hdlcd: Use helper support for nonblocking commits Daniel Vetter
2016-06-01 22:06 ` [PATCH 24/38] drm/arc: Implement nonblocking commit correctly Daniel Vetter
2016-06-01 22:06   ` Daniel Vetter
2016-06-01 22:06 ` [PATCH 25/38] drm/i915: Signal drm events for atomic Daniel Vetter
2016-06-01 22:06 ` [PATCH 26/38] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
2016-06-01 22:06 ` [PATCH 27/38] drm/i915: nonblocking commit Daniel Vetter
2016-06-01 22:06 ` [PATCH 28/38] drm/i915: Use atomic commits for legacy page_flips Daniel Vetter
2016-06-01 22:06 ` [PATCH 29/38] drm/i915: Move fb_bits updating later in atomic_commit Daniel Vetter
2016-06-01 22:06 ` [PATCH 30/38] drm/rockchip: Disarm vop->is_enabled Daniel Vetter
2016-06-01 22:06 ` [PATCH 31/38] drm/rockchip: Fix crtc_state->event signalling Daniel Vetter
2016-06-01 22:06 ` [PATCH 32/38] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
2016-06-01 22:06 ` [PATCH 33/38] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
2016-06-01 22:06 ` [PATCH 34/38] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
2016-06-01 22:06 ` [PATCH 35/38] drm: Replace fb_helper->atomic with mode_config->atomic_commit Daniel Vetter
2016-06-01 22:06 ` [PATCH 36/38] drm: Resurrect atomic rmfb code Daniel Vetter
2016-06-01 22:07 ` [PATCH 37/38] drm/sti: Don't call drm_helper_disable_unused_functions Daniel Vetter
2016-06-17 10:04   ` Benjamin Gaignard
2016-06-17 12:27     ` Daniel Vetter
2016-06-01 22:07 ` [PATCH 38/38] drm/crtc-helper: disable_unused_functions really isn't for atomic Daniel Vetter
2016-06-02 13:10 ` ✗ Ro.CI.BAT: failure for nonblocking atomic commits for everyone! Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.