|
@@ -728,9 +728,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.
|
|
@@ -787,11 +784,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;
|
|
|
};
|
|
@@ -1733,6 +1756,111 @@ 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 synchronization
|
|
|
+ * 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.
|
|
|
+ *
|
|
|
+ * For an implementation of how to use this look at
|
|
|
+ * drm_atomic_helper_setup_commit() from the atomic helper library.
|
|
|
+ */
|
|
|
+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 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;
|
|
@@ -1741,6 +1869,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 {
|
|
@@ -1771,6 +1900,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;
|
|
|
};
|
|
|
|
|
|
|