[PATCH 01/19] drm: Add atomic driver interface definitions for objects
Daniel Vetter
daniel.vetter at ffwll.ch
Sun Jul 27 14:41:30 PDT 2014
Heavily based upon Rob Clark's atomic series.
- Dropped the connctor state from the crtc state, instead opting for a
full-blown connector state. The only thing it has is the desired
crtc, but drivers which have connector properties have now a
data-structure to subclass.
- Rename create_state to duplicate_state. Especially for legacy ioctls
we want updates on top of existing state, so we need a way to get at
the current state. We need to be careful to clear the backpointers
correctly though. We need to be careful though with the ->state
backpointer we need while constructing the atomic state.
- Drop property values. Drivers with properties simply need to
subclass the datastructures and track the decoded values in there. I
also think that common properties (like rotation) should be decoded
and stored in the core structures.
- Create a new set of ->atomic_set_prop functions, for smoother
transitions from legacy to atomic operations.
- Pass the ->atomic_set_prop ioctl the right structure to avoid
chasing pointers in drivers.
- Drop temporary boolean state for now until we resurrect them with
the helper functions.
- Drop invert_dimensions. For now we don't need any checking since
that's done by the higher-level legacy ioctls. But even then we
should also add rotation/flip tracking to the core drm_crtc_state,
not just whether the dimensions are inverted.
- Track crtc state with an enable/disable. That's equivalent to
mode_valid, but a bit clearer that it means the entire crtc.
The global interface will follow in subsequent patches.
v2: We need to allow drivers to somehow set up the initial state and
clear it on resume. So add a plane->reset callback for that. Helpers
will be provided with default behaviour for all these.
Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
drivers/gpu/drm/drm_crtc.c | 5 ++
include/drm/drm_crtc.h | 149 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 154 insertions(+)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 805240b11229..0f934a58702d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -4623,9 +4623,14 @@ out:
void drm_mode_config_reset(struct drm_device *dev)
{
struct drm_crtc *crtc;
+ struct drm_crtc *plane;
struct drm_encoder *encoder;
struct drm_connector *connector;
+ list_for_each_entry(plane, &dev->mode_config.plane_list, head)
+ if (plane->funcs->reset)
+ plane->funcs->reset(plane);
+
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
if (crtc->funcs->reset)
crtc->funcs->reset(crtc);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index f1105d0da059..a1a8c694e765 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -228,6 +228,25 @@ struct drm_encoder;
struct drm_pending_vblank_event;
struct drm_plane;
struct drm_bridge;
+struct drm_atomic_state;
+
+/**
+ * drm_crtc_state - mutable crtc state
+ * @mode_valid: a valid mode has been set
+ * @set_config: needs modeset (crtc->set_config())
+ * @connectors_change: the connector-ids array has changed
+ * @mode: current mode timings
+ * @event: pending pageflip event
+ */
+struct drm_crtc_state {
+ bool enable : 1;
+
+ struct drm_display_mode mode;
+
+ struct drm_pending_vblank_event *event;
+
+ struct drm_atomic_state *state;
+};
/**
* drm_crtc_funcs - control CRTCs for a given device
@@ -291,6 +310,15 @@ struct drm_crtc_funcs {
int (*set_property)(struct drm_crtc *crtc,
struct drm_property *property, uint64_t val);
+
+ /* atomic update handling */
+ struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc);
+ void (*atomic_destroy_state)(struct drm_crtc *crtc,
+ struct drm_crtc_state *cstate);
+ int (*atomic_set_property)(struct drm_crtc *crtc,
+ struct drm_crtc_state *state,
+ struct drm_property *property,
+ uint64_t val);
};
/**
@@ -375,8 +403,38 @@ struct drm_crtc {
void *helper_private;
struct drm_object_properties properties;
+
+ struct drm_crtc_state *state;
};
+static inline struct drm_crtc_state *
+drm_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+ if (crtc->funcs->atomic_duplicate_state)
+ return crtc->funcs->atomic_duplicate_state(crtc);
+ return kmemdup(crtc->state, sizeof(struct drm_crtc_state), GFP_KERNEL);
+}
+
+static inline void
+drm_crtc_destroy_state(struct drm_crtc *crtc,
+ struct drm_crtc_state *cstate)
+{
+ if (crtc->funcs->atomic_destroy_state)
+ crtc->funcs->atomic_destroy_state(crtc, cstate);
+ else
+ kfree(cstate);
+}
+
+
+/**
+ * drm_connector_state - mutable connector state
+ * @crtc: crtc to connect connector to, NULL if disabled
+ */
+struct drm_connector_state {
+ struct drm_crtc *crtc;
+
+ struct drm_atomic_state *state;
+};
/**
* drm_connector_funcs - control connectors on a given device
@@ -413,6 +471,15 @@ struct drm_connector_funcs {
uint64_t val);
void (*destroy)(struct drm_connector *connector);
void (*force)(struct drm_connector *connector);
+
+ /* atomic update handling */
+ struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
+ void (*atomic_destroy_state)(struct drm_connector *connector,
+ struct drm_connector_state *cstate);
+ int (*atomic_set_property)(struct drm_connector *connector,
+ struct drm_connector_state *state,
+ struct drm_property *property,
+ uint64_t val);
};
/**
@@ -564,8 +631,59 @@ struct drm_connector {
unsigned bad_edid_counter;
struct dentry *debugfs_entry;
+
+ struct drm_connector_state *state;
};
+static inline struct drm_connector_state *
+drm_connector_duplicate_state(struct drm_connector *connector)
+{
+ if (connector->funcs->atomic_duplicate_state)
+ return connector->funcs->atomic_duplicate_state(connector);
+ return kmemdup(connector->state,
+ sizeof(struct drm_connector_state), GFP_KERNEL);
+}
+
+static inline void
+drm_connector_destroy_state(struct drm_connector *connector,
+ struct drm_connector_state *cstate)
+{
+ if (connector->funcs->atomic_destroy_state)
+ connector->funcs->atomic_destroy_state(connector, cstate);
+ else
+ kfree(cstate);
+}
+
+/**
+ * drm_plane_state - mutable plane state
+ * @crtc: currently bound CRTC
+ * @fb: currently bound fb
+ * @crtc_x: left position of visible portion of plane on crtc
+ * @crtc_y: upper position of visible portion of plane on crtc
+ * @crtc_w: width of visible portion of plane on crtc
+ * @crtc_h: height of visible portion of plane on crtc
+ * @src_x: left position of visible portion of plane within
+ * plane (in 16.16)
+ * @src_y: upper position of visible portion of plane within
+ * plane (in 16.16)
+ * @src_w: width of visible portion of plane (in 16.16)
+ * @src_h: height of visible portion of plane (in 16.16)
+ */
+struct drm_plane_state {
+ struct drm_crtc *crtc;
+ struct drm_framebuffer *fb;
+
+ /* Signed dest location allows it to be partially off screen */
+ int32_t crtc_x, crtc_y;
+ uint32_t crtc_w, crtc_h;
+
+ /* Source values are 16.16 fixed point */
+ uint32_t src_x, src_y;
+ uint32_t src_h, src_w;
+ struct drm_atomic_state *state;
+};
+
+
/**
* drm_plane_funcs - driver plane control functions
* @update_plane: update the plane configuration
@@ -582,9 +700,19 @@ struct drm_plane_funcs {
uint32_t src_w, uint32_t src_h);
int (*disable_plane)(struct drm_plane *plane);
void (*destroy)(struct drm_plane *plane);
+ void (*reset)(struct drm_plane *plane);
int (*set_property)(struct drm_plane *plane,
struct drm_property *property, uint64_t val);
+
+ /* atomic update handling */
+ struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane);
+ void (*atomic_destroy_state)(struct drm_plane *plane,
+ struct drm_plane_state *cstate);
+ int (*atomic_set_property)(struct drm_plane *plane,
+ struct drm_plane_state *state,
+ struct drm_property *property,
+ uint64_t val);
};
enum drm_plane_type {
@@ -625,8 +753,29 @@ struct drm_plane {
struct drm_object_properties properties;
enum drm_plane_type type;
+
+ struct drm_plane_state *state;
};
+static inline struct drm_plane_state *
+drm_plane_duplicate_state(struct drm_plane *plane)
+{
+ if (plane->funcs->atomic_duplicate_state)
+ return plane->funcs->atomic_duplicate_state(plane);
+ return kmemdup(plane->state, sizeof(struct drm_plane_state), GFP_KERNEL);
+}
+
+static inline void
+drm_plane_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *cstate)
+{
+ if (plane->funcs->atomic_destroy_state)
+ plane->funcs->atomic_destroy_state(plane, cstate);
+ else
+ kfree(cstate);
+}
+
+
/**
* drm_bridge_funcs - drm_bridge control functions
* @mode_fixup: Try to fixup (or reject entirely) proposed mode for this bridge
--
2.0.1
More information about the dri-devel
mailing list