aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@bootlin.com>2018-07-03 03:50:19 -0400
committerBoris Brezillon <boris.brezillon@bootlin.com>2018-07-07 01:53:09 -0400
commitb25c60af7a8773694a505cdb0d2e67807243217d (patch)
tree0d0cddb6694d71108605e11633689a21917d766f
parent184d3cf4f73896267340cf06acfa751fad4f8dd2 (diff)
drm/crtc: Add a generic infrastructure to fake VBLANK events
In some cases CRTCs are active but are not able to generating events, at least not at every frame at it's expected to. This is typically the case when the CRTC is feeding a writeback connector that has no job queued. In this situation the CRTC is usually stopped until a new job is queued, and this can lead to timeouts when part of the pipeline is updated but no new jobs are queued to the active writeback connector. In order to solve that, we add a ->no_vblank flag to drm_crtc_state and ask the CRTC drivers to set it to true when they know they're not able to generate VBLANK events. The core drm_atomic_helper_fake_vblank() helper can then be used to fake VBLANKs at commit time. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20180703075022.15138-6-boris.brezillon@bootlin.com
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c39
-rw-r--r--include/drm/drm_atomic_helper.h1
-rw-r--r--include/drm/drm_crtc.h23
3 files changed, 63 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index bab8051690bb..c31f670b1283 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2054,6 +2054,45 @@ void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
2054EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); 2054EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
2055 2055
2056/** 2056/**
2057 * drm_atomic_helper_fake_vblank - fake VBLANK events if needed
2058 * @old_state: atomic state object with old state structures
2059 *
2060 * This function walks all CRTCs and fake VBLANK events on those with
2061 * &drm_crtc_state.no_vblank set to true and &drm_crtc_state.event != NULL.
2062 * The primary use of this function is writeback connectors working in oneshot
2063 * mode and faking VBLANK events. In this case they only fake the VBLANK event
2064 * when a job is queued, and any change to the pipeline that does not touch the
2065 * connector is leading to timeouts when calling
2066 * drm_atomic_helper_wait_for_vblanks() or
2067 * drm_atomic_helper_wait_for_flip_done().
2068 *
2069 * This is part of the atomic helper support for nonblocking commits, see
2070 * drm_atomic_helper_setup_commit() for an overview.
2071 */
2072void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
2073{
2074 struct drm_crtc_state *new_crtc_state;
2075 struct drm_crtc *crtc;
2076 int i;
2077
2078 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
2079 unsigned long flags;
2080
2081 if (!new_crtc_state->no_vblank)
2082 continue;
2083
2084 spin_lock_irqsave(&old_state->dev->event_lock, flags);
2085 if (new_crtc_state->event) {
2086 drm_crtc_send_vblank_event(crtc,
2087 new_crtc_state->event);
2088 new_crtc_state->event = NULL;
2089 }
2090 spin_unlock_irqrestore(&old_state->dev->event_lock, flags);
2091 }
2092}
2093EXPORT_SYMBOL(drm_atomic_helper_fake_vblank);
2094
2095/**
2057 * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit 2096 * drm_atomic_helper_commit_hw_done - setup possible nonblocking commit
2058 * @old_state: atomic state object with old state structures 2097 * @old_state: atomic state object with old state structures
2059 * 2098 *
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 26aaba58d6ce..99e2a5297c69 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -100,6 +100,7 @@ int __must_check drm_atomic_helper_swap_state(struct drm_atomic_state *state,
100int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, 100int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
101 bool nonblock); 101 bool nonblock);
102void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state); 102void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
103void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state);
103void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state); 104void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
104void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state); 105void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
105 106
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 23eddbccab10..17f4f93340b8 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -119,6 +119,29 @@ struct drm_crtc_state {
119 bool zpos_changed : 1; 119 bool zpos_changed : 1;
120 bool color_mgmt_changed : 1; 120 bool color_mgmt_changed : 1;
121 121
122 /**
123 * @no_vblank:
124 *
125 * Reflects the ability of a CRTC to send VBLANK events. This state
126 * usually depends on the pipeline configuration, and the main usuage
127 * is CRTCs feeding a writeback connector operating in oneshot mode.
128 * In this case the VBLANK event is only generated when a job is queued
129 * to the writeback connector, and we want the core to fake VBLANK
130 * events when this part of the pipeline hasn't changed but others had
131 * or when the CRTC and connectors are being disabled.
132 *
133 * __drm_atomic_helper_crtc_duplicate_state() will not reset the value
134 * from the current state, the CRTC driver is then responsible for
135 * updating this field when needed.
136 *
137 * Note that the combination of &drm_crtc_state.event == NULL and
138 * &drm_crtc_state.no_blank == true is valid and usually used when the
139 * writeback connector attached to the CRTC has a new job queued. In
140 * this case the driver will send the VBLANK event on its own when the
141 * writeback job is complete.
142 */
143 bool no_vblank : 1;
144
122 /* attached planes bitmask: 145 /* attached planes bitmask:
123 * WARNING: transitional helpers do not maintain plane_mask so 146 * WARNING: transitional helpers do not maintain plane_mask so
124 * drivers not converted over to atomic helpers should not rely 147 * drivers not converted over to atomic helpers should not rely