[01/19] drm: Add atomic driver interface definitions for objects
diff mbox

Message ID 1406497308-30733-2-git-send-email-daniel.vetter@ffwll.ch
State New, archived
Headers show

Commit Message

Daniel Vetter July 27, 2014, 9:41 p.m. UTC
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@ffwll.ch>
---
 drivers/gpu/drm/drm_crtc.c |   5 ++
 include/drm/drm_crtc.h     | 149 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+)

Patch
diff mbox

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