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@xxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel