[PATCH 24/33] heh
Chris Wilson
chris at chris-wilson.co.uk
Thu Sep 15 15:26:29 UTC 2016
---
drivers/gpu/drm/drm_atomic.c | 29 ++++++++++++++++++-----------
drivers/gpu/drm/drm_atomic_helper.c | 31 +++++++++++++------------------
drivers/gpu/drm/drm_crtc.c | 2 --
drivers/gpu/drm/drm_plane_helper.c | 8 ++++++--
drivers/gpu/drm/i915/intel_display.c | 22 +++++++++++++++-------
drivers/gpu/drm/i915/intel_drv.h | 4 +++-
drivers/gpu/drm/i915/intel_sprite.c | 10 +++++-----
include/drm/drm_atomic_helper.h | 3 ++-
include/drm/drm_crtc.h | 16 +++++++---------
include/drm/drm_modeset_helper_vtables.h | 2 ++
10 files changed, 71 insertions(+), 56 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5dd70540219c..4580d35dff62 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -158,6 +158,7 @@ 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].ptr;
+ struct drm_pending_vblank_event *event;
if (!crtc)
continue;
@@ -166,12 +167,16 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
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;
+ }
+
+ event = state->crtcs[i].event;
+ if (event) {
+ drm_event_cancel_free(dev, &event->base);
+ state->crtcs[i].event = NULL;
}
- state->crtcs[i].commit = NULL;
state->crtcs[i].ptr = NULL;
state->crtcs[i].state = NULL;
}
@@ -541,7 +546,6 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
/**
* drm_atomic_crtc_check - check crtc state
- * @crtc: crtc to check
* @state: crtc state to check
*
* Provides core sanity checks for crtc state.
@@ -549,9 +553,11 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
* RETURNS:
* Zero on success, error code on failure
*/
-static int drm_atomic_crtc_check(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
+static int drm_atomic_crtc_check(struct drm_crtc_state *state,
+ struct drm_pending_vblank_event *event)
{
+ struct drm_crtc *crtc = state->crtc;
+
/* NOTE: we explicitly don't enforce constraints such as primary
* layer covering entire screen, since that is something we want
* to allow (on hw that supports it). For hw that does not, it
@@ -593,7 +599,7 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
* and legacy page_flip IOCTL which also reject service on a disabled
* pipe.
*/
- if (state->event && !state->active && !crtc->state->active) {
+ if (event && !state->active && !crtc->state->active) {
DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n",
crtc->base.id);
return -EINVAL;
@@ -1368,7 +1374,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
}
for_each_crtc_in_state(state, crtc, crtc_state, i) {
- ret = drm_atomic_crtc_check(crtc, crtc_state);
+ ret = drm_atomic_crtc_check(crtc_state, state->crtcs[i].event);
if (ret) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
crtc->base.id, crtc->name);
@@ -1731,7 +1737,7 @@ retry:
goto out;
}
- crtc_state->event = e;
+ state->crtcs[i].event = e;
}
}
@@ -1758,10 +1764,11 @@ out:
*/
for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (!crtc_state->event)
+ if (!state->crtcs[i].event)
continue;
- drm_event_cancel_free(dev, &crtc_state->event->base);
+ drm_event_cancel_free(dev,
+ &state->crtcs[i].event->base);
}
}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index d1ec053d36d5..35a6f841c385 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1467,16 +1467,15 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
continue;
}
- if (!crtc_state->event) {
- commit->event = kzalloc(sizeof(*commit->event),
- GFP_KERNEL);
- if (!commit->event)
+ if (!state->crtcs[i].event) {
+ state->crtcs[i].event =
+ kzalloc(sizeof(*state->crtcs[i].event),
+ GFP_KERNEL);
+ if (!state->crtcs[i].event)
return -ENOMEM;
-
- crtc_state->event = commit->event;
}
- crtc_state->event->base.completion = &commit->flip_done;
+ state->crtcs[i].event->base.completion = &commit->flip_done;
}
return 0;
@@ -1577,7 +1576,6 @@ void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
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);
@@ -1763,7 +1761,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (active_only && !crtc->state->active)
continue;
- funcs->atomic_begin(crtc, old_crtc_state);
+ funcs->atomic_begin(crtc, old_state, old_crtc_state);
}
for_each_plane_in_state(old_state, plane, old_plane_state, i) {
@@ -1820,7 +1818,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (active_only && !crtc->state->active)
continue;
- funcs->atomic_flush(crtc, old_crtc_state);
+ funcs->atomic_flush(crtc, old_state, old_crtc_state);
}
}
EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
@@ -1856,7 +1854,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
crtc_funcs = crtc->helper_private;
if (crtc_funcs && crtc_funcs->atomic_begin)
- crtc_funcs->atomic_begin(crtc, old_crtc_state);
+ crtc_funcs->atomic_begin(crtc, old_state, old_crtc_state);
drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
struct drm_plane_state *old_plane_state =
@@ -1879,7 +1877,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
}
if (crtc_funcs && crtc_funcs->atomic_flush)
- crtc_funcs->atomic_flush(crtc, old_crtc_state);
+ crtc_funcs->atomic_flush(crtc, old_state, old_crtc_state);
}
EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
@@ -1909,7 +1907,7 @@ drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
struct drm_plane *plane;
if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
- crtc_funcs->atomic_begin(crtc, NULL);
+ crtc_funcs->atomic_begin(crtc, NULL, NULL);
drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
const struct drm_plane_helper_funcs *plane_funcs =
@@ -1924,7 +1922,7 @@ drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
}
if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
- crtc_funcs->atomic_flush(crtc, NULL);
+ crtc_funcs->atomic_flush(crtc, NULL, NULL);
}
EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
@@ -2041,8 +2039,6 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
list_add(&state->crtcs[i].commit->commit_entry,
&crtc->commit_list);
spin_unlock(&crtc->commit_lock);
-
- state->crtcs[i].commit->event = NULL;
}
}
@@ -2772,7 +2768,7 @@ retry:
ret = PTR_ERR(crtc_state);
goto fail;
}
- crtc_state->event = event;
+ state->crtcs[drm_crtc_index(crtc)].event = event;
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
@@ -2978,7 +2974,6 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
state->connectors_changed = false;
state->color_mgmt_changed = false;
state->zpos_changed = false;
- state->event = NULL;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index d84a0ead8100..4af6a7525587 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2036,8 +2036,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
else
ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
if (ret) {
- if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT)
- drm_event_cancel_free(dev, &e->base);
/* Keep the old fb, don't unref it. */
crtc->primary->old_fb = NULL;
} else {
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 7899fc1dcdb0..64d8622dc50a 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -465,7 +465,9 @@ int drm_plane_helper_commit(struct drm_plane *plane,
for (i = 0; i < 2; i++) {
if (crtc_funcs[i] && crtc_funcs[i]->atomic_begin)
- crtc_funcs[i]->atomic_begin(crtc[i], crtc[i]->state);
+ crtc_funcs[i]->atomic_begin(crtc[i],
+ plane_state->state,
+ crtc[i]->state);
}
/*
@@ -480,7 +482,9 @@ int drm_plane_helper_commit(struct drm_plane *plane,
for (i = 0; i < 2; i++) {
if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush)
- crtc_funcs[i]->atomic_flush(crtc[i], crtc[i]->state);
+ crtc_funcs[i]->atomic_flush(crtc[i],
+ plane_state->state,
+ crtc[i]->state);
}
/*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9f4fdbfe7476..a3f3a5a6bca6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -113,8 +113,12 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config);
static void chv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config);
-static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
-static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *);
+static void intel_begin_crtc_commit(struct drm_crtc *,
+ struct drm_atomic_state *,
+ struct drm_crtc_state *);
+static void intel_finish_crtc_commit(struct drm_crtc *,
+ struct drm_atomic_state *,
+ struct drm_crtc_state *);
static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state);
static void skylake_pfit_enable(struct intel_crtc *crtc);
@@ -12002,7 +12006,7 @@ static void intel_mmio_flip_work_func(struct work_struct *w)
/* use_mmio_flip() retricts MMIO flips to ilk+ */
ilk_do_mmio_flip(crtc, work);
- intel_pipe_update_end(crtc, work);
+ intel_pipe_update_end(crtc, work, NULL);
}
static int intel_default_queue_flip(struct drm_device *dev,
@@ -14440,12 +14444,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
bool modeset = needs_modeset(crtc->state);
/* Complete events for now disable pipes here. */
- if (modeset && !crtc->state->active && crtc->state->event) {
+ if (modeset && !crtc->state->active && state->crtcs[i].event) {
spin_lock_irq(&dev->event_lock);
- drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ drm_crtc_send_vblank_event(crtc, state->crtcs[i].event);
spin_unlock_irq(&dev->event_lock);
- crtc->state->event = NULL;
+ state->crtcs[i].event = NULL;
}
}
@@ -14776,6 +14780,7 @@ intel_check_primary_plane(struct drm_plane *plane,
}
static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+ struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->dev;
@@ -14808,11 +14813,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
}
static void intel_finish_crtc_commit(struct drm_crtc *crtc,
+ struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_pending_vblank_event *event;
- intel_pipe_update_end(intel_crtc, NULL);
+ event = fetch_and_zero(&state->crtcs[drm_crtc_index(crtc)].event);
+ intel_pipe_update_end(intel_crtc, NULL, event);
}
/**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ebb2e7d4afa7..d9599f960e2d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1778,7 +1778,9 @@ int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void intel_pipe_update_start(struct intel_crtc *crtc);
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work);
+void intel_pipe_update_end(struct intel_crtc *crtc,
+ struct intel_flip_work *work,
+ struct drm_pending_vblank_event *event);
/* intel_tv.c */
void intel_tv_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index e1297da47a2c..44da0287c260 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -152,7 +152,9 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
* re-enables interrupts and verifies the update was actually completed
* before a vblank using the value of @start_vbl_count.
*/
-void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
+void intel_pipe_update_end(struct intel_crtc *crtc,
+ struct intel_flip_work *work,
+ struct drm_pending_vblank_event *event)
{
enum pipe pipe = crtc->pipe;
int scanline_end = intel_get_crtc_scanline(crtc);
@@ -171,14 +173,12 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
* 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) {
+ if (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);
+ drm_crtc_arm_vblank_event(&crtc->base, event);
spin_unlock(&crtc->base.dev->event_lock);
-
- crtc->base.state->event = NULL;
}
local_irq_enable();
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 7ff92b09fd9c..902130bed541 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -75,7 +75,8 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
uint32_t flags);
void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
struct drm_atomic_state *old_state);
-void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
+void
+drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state);
void
drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
bool atomic);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index b6e1853d2355..9ed4c5dadc74 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -169,8 +169,6 @@ struct drm_crtc_state {
struct drm_property_blob *ctm;
struct drm_property_blob *gamma_lut;
- struct drm_pending_vblank_event *event;
-
struct drm_atomic_state *state;
};
@@ -1282,13 +1280,6 @@ struct drm_crtc_commit {
* 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 {
@@ -1300,6 +1291,13 @@ struct __drm_crtcs_state {
struct drm_crtc *ptr;
struct drm_crtc_state *state;
struct drm_crtc_commit *commit;
+
+ /**
+ * @event:
+ *
+ * &drm_pending_vblank_event pointer to clean up private events.
+ */
+ struct drm_pending_vblank_event *event;
};
struct __drm_connnectors_state {
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 10e449c86dbd..01923a672059 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -368,6 +368,7 @@ struct drm_crtc_helper_funcs {
* transitional plane helpers, but it is optional.
*/
void (*atomic_begin)(struct drm_crtc *crtc,
+ struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state);
/**
* @atomic_flush:
@@ -392,6 +393,7 @@ struct drm_crtc_helper_funcs {
* transitional plane helpers, but it is optional.
*/
void (*atomic_flush)(struct drm_crtc *crtc,
+ struct drm_atomic_state *state,
struct drm_crtc_state *old_crtc_state);
/**
--
2.9.3
More information about the Intel-gfx-trybot
mailing list