On Mon, Oct 14, 2013 at 01:26:45PM -0400, Rob Clark wrote:
Break the mutable state of a plane out into a separate structure and use atomic properties mechanism to set plane attributes. This makes it easier to have some helpers for plane->set_property() and for checking for invalid params. The idea is that individual drivers can wrap the state struct in their own struct which adds driver specific parameters, for easy build-up of state across multiple set_property() calls and for easy atomic commit or roll- back.
The same should be done for CRTC, encoder, and connector, but this patch only includes the first part (plane).
drivers/gpu/drm/drm_atomic_helper.c | 137 +++++++++- drivers/gpu/drm/drm_crtc.c | 399 +++++++++++++++++++--------- drivers/gpu/drm/drm_fb_helper.c | 17 +- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 6 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 13 +- drivers/gpu/drm/i915/intel_sprite.c | 19 +- drivers/gpu/drm/msm/mdp4/mdp4_crtc.c | 2 +- drivers/gpu/drm/msm/mdp4/mdp4_plane.c | 18 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 +- drivers/gpu/drm/omapdrm/omap_drv.c | 2 +- drivers/gpu/drm/omapdrm/omap_plane.c | 30 ++- drivers/gpu/drm/rcar-du/rcar_du_plane.c | 5 +- drivers/gpu/drm/shmobile/shmob_drm_crtc.c | 2 +- drivers/gpu/drm/shmobile/shmob_drm_plane.c | 6 +- drivers/gpu/host1x/drm/dc.c | 16 +- include/drm/drm_atomic_helper.h | 37 ++- include/drm/drm_crtc.h | 88 +++++- 18 files changed, 615 insertions(+), 190 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 46c67b8..0618113 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -39,10 +39,12 @@ void *drm_atomic_helper_begin(struct drm_device *dev, uint32_t flags) { struct drm_atomic_helper_state *state;
int nplanes = dev->mode_config.num_plane; int sz; void *ptr;
sz = sizeof(*state);
sz += (sizeof(state->planes) + sizeof(state->pstates)) * nplanes;
ptr = kzalloc(sz, GFP_KERNEL);
@@ -52,6 +54,13 @@ void *drm_atomic_helper_begin(struct drm_device *dev, uint32_t flags) kref_init(&state->refcount); state->dev = dev; state->flags = flags;
- state->planes = ptr;
- ptr = &state->planes[nplanes];
- state->pstates = ptr;
- ptr = &state->pstates[nplanes];
- return state;
} EXPORT_SYMBOL(drm_atomic_helper_begin); @@ -87,7 +96,19 @@ EXPORT_SYMBOL(drm_atomic_helper_set_event); */ int drm_atomic_helper_check(struct drm_device *dev, void *state) {
- return 0; /* for now */
- struct drm_atomic_helper_state *a = state;
- int nplanes = dev->mode_config.num_plane;
- int i, ret = 0;
- for (i = 0; i < nplanes; i++) {
if (a->planes[i]) {
ret = drm_atomic_check_plane_state(a->planes[i], a->pstates[i]);
if (ret)
break;
}
- }
- return ret;
} EXPORT_SYMBOL(drm_atomic_helper_check);
@@ -104,7 +125,19 @@ EXPORT_SYMBOL(drm_atomic_helper_check); */ int drm_atomic_helper_commit(struct drm_device *dev, void *state) {
- return 0; /* for now */
- struct drm_atomic_helper_state *a = state;
- int nplanes = dev->mode_config.num_plane;
- int i, ret = 0;
- for (i = 0; i < nplanes; i++) {
if (a->planes[i]) {
ret = drm_atomic_commit_plane_state(a->planes[i], a->pstates[i]);
if (ret)
break;
}
- }
- return ret;
} EXPORT_SYMBOL(drm_atomic_helper_commit);
@@ -125,11 +158,111 @@ void _drm_atomic_helper_state_free(struct kref *kref) { struct drm_atomic_helper_state *state = container_of(kref, struct drm_atomic_helper_state, refcount);
- struct drm_device *dev = state->dev;
- int nplanes = dev->mode_config.num_plane;
- int i;
- for (i = 0; i < nplanes; i++) {
if (state->pstates[i]) {
state->planes[i]->state->state = NULL;
kfree(state->pstates[i]);
}
- }
- kfree(state);
} EXPORT_SYMBOL(_drm_atomic_helper_state_free);
+int drm_atomic_helper_plane_set_property(struct drm_plane *plane, void *state,
struct drm_property *property, uint64_t val, void *blob_data)
+{
- return drm_plane_set_property(plane,
drm_atomic_get_plane_state(plane, state),
property, val, blob_data);
+} +EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
+void drm_atomic_helper_init_plane_state(struct drm_plane *plane,
struct drm_plane_state *pstate, void *state)
+{
- /* snapshot current state: */
- *pstate = *plane->state;
- pstate->state = state;
+} +EXPORT_SYMBOL(drm_atomic_helper_init_plane_state);
+static struct drm_plane_state * +drm_atomic_helper_get_plane_state(struct drm_plane *plane, void *state) +{
- struct drm_atomic_helper_state *a = state;
- struct drm_plane_state *pstate = a->pstates[plane->id];
- if (!pstate) {
pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
drm_atomic_helper_init_plane_state(plane, pstate, state);
a->planes[plane->id] = plane;
a->pstates[plane->id] = pstate;
- }
- return pstate;
+}
+static void +swap_plane_state(struct drm_plane *plane, struct drm_atomic_helper_state *a) +{
- swap(plane->state, a->pstates[plane->id]);
- plane->base.propvals = &plane->state->propvals;
+}
+static int +drm_atomic_helper_commit_plane_state(struct drm_plane *plane,
struct drm_plane_state *pstate)
+{
- struct drm_device *dev = plane->dev;
- struct drm_framebuffer *old_fb = NULL, *fb = NULL;
- int ret = 0;
- /* probably more fine grain locking would be ok of old crtc
* and new crtc were same..
*/
- drm_modeset_lock_all(dev);
- fb = pstate->fb;
- if (pstate->crtc && fb) {
ret = plane->funcs->update_plane(plane, pstate->crtc, pstate->fb,
pstate->crtc_x, pstate->crtc_y, pstate->crtc_w, pstate->crtc_h,
pstate->src_x, pstate->src_y, pstate->src_w, pstate->src_h);
if (!ret) {
/* on success, update state and fb refcnting: */
/* NOTE: if we ensure no driver sets plane->state->fb = NULL
* on disable, we can move this up a level and not duplicate
* nearly the same thing for both update_plane and disable_plane
* cases.. I leave it like this for now to be paranoid due to
* the slightly different ordering in the two cases in the
* original code.
*/
old_fb = plane->state->fb;
swap_plane_state(plane, pstate->state);
fb = NULL;
}
- } else {
old_fb = plane->state->fb;
plane->funcs->disable_plane(plane);
swap_plane_state(plane, pstate->state);
- }
- drm_modeset_unlock_all(dev);
- if (fb)
drm_framebuffer_unreference(fb);
- if (old_fb)
drm_framebuffer_unreference(old_fb);
- return ret;
+}
const struct drm_atomic_helper_funcs drm_atomic_helper_funcs = {
.get_plane_state = drm_atomic_helper_get_plane_state,
.check_plane_state = drm_plane_check_state,
.commit_plane_state = drm_atomic_helper_commit_plane_state,
}; EXPORT_SYMBOL(drm_atomic_helper_funcs); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 9f46f3b..3cf235e 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -595,7 +595,20 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) * in this manner. */ if (atomic_read(&fb->refcount.refcount) > 1) {
void *state;
state = dev->driver->atomic_begin(dev, 0);
if (IS_ERR(state)) {
DRM_ERROR("failed to disable crtc and/or plane when fb was deleted\n");
return;
}
/* TODO once CRTC is converted to state/properties, we can push the
* locking down into drm_atomic_helper_commit(), since that is where
* the actual changes take place..
drm_modeset_lock_all(dev);*/
- /* remove from any CRTC */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (crtc->fb == fb) {
@@ -610,9 +623,18 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) }
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
if (plane->fb == fb)
drm_plane_force_disable(plane);
if (plane->state->fb == fb)
}drm_plane_force_disable(plane, state);
/* just disabling stuff shouldn't fail, hopefully: */
if(dev->driver->atomic_check(dev, state))
DRM_ERROR("failed to disable crtc and/or plane when fb was deleted\n");
else
dev->driver->atomic_commit(dev, state);
dev->driver->atomic_end(dev, state);
- drm_modeset_unlock_all(dev); }
@@ -904,8 +926,12 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, const uint32_t *formats, uint32_t format_count, bool priv) {
struct drm_mode_config *config = &dev->mode_config; int ret;
if (!plane->state)
plane->state = kzalloc(sizeof(plane->state), GFP_KERNEL);
drm_modeset_lock_all(dev);
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
@@ -913,7 +939,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, goto out;
plane->base.properties = &plane->properties;
- plane->base.propvals = &plane->propvals;
- plane->base.propvals = &plane->state->propvals; plane->dev = dev; plane->funcs = funcs; plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
@@ -935,11 +961,23 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, */ if (!priv) { list_add_tail(&plane->head, &dev->mode_config.plane_list);
plane->id = dev->mode_config.num_plane;
dev->mode_config.num_plane++; } else { INIT_LIST_HEAD(&plane->head); }
drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
drm_object_attach_property(&plane->base, config->prop_src_x, 0);
drm_object_attach_property(&plane->base, config->prop_src_y, 0);
drm_object_attach_property(&plane->base, config->prop_src_w, 0);
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
out: drm_modeset_unlock_all(dev);
@@ -971,6 +1009,111 @@ void drm_plane_cleanup(struct drm_plane *plane) } EXPORT_SYMBOL(drm_plane_cleanup);
+int drm_plane_check_state(struct drm_plane *plane,
struct drm_plane_state *state)
+{
- unsigned int fb_width, fb_height;
- struct drm_framebuffer *fb = state->fb;
- int i;
- /* disabling the plane is allowed: */
- if (!fb)
return 0;
- fb_width = fb->width << 16;
- fb_height = fb->height << 16;
- /* Check whether this plane supports the fb pixel format. */
- for (i = 0; i < plane->format_count; i++)
if (fb->pixel_format == plane->format_types[i])
break;
- if (i == plane->format_count) {
DRM_DEBUG_KMS("Invalid pixel format 0x%08x\n", fb->pixel_format);
return -EINVAL;
- }
- /* Make sure source coordinates are inside the fb. */
- if (state->src_w > fb_width ||
state->src_x > fb_width - state->src_w ||
state->src_h > fb_height ||
state->src_y > fb_height - state->src_h) {
DRM_DEBUG_KMS("Invalid source coordinates "
"%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
state->src_w >> 16,
((state->src_w & 0xffff) * 15625) >> 10,
state->src_h >> 16,
((state->src_h & 0xffff) * 15625) >> 10,
state->src_x >> 16,
((state->src_x & 0xffff) * 15625) >> 10,
state->src_y >> 16,
((state->src_y & 0xffff) * 15625) >> 10);
return -ENOSPC;
- }
- /* Give drivers some help against integer overflows */
- if (state->crtc_w > INT_MAX ||
state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
state->crtc_h > INT_MAX ||
state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
state->crtc_w, state->crtc_h,
state->crtc_x, state->crtc_y);
return -ERANGE;
- }
- return 0;
+} +EXPORT_SYMBOL(drm_plane_check_state);
+void drm_plane_commit_state(struct drm_plane *plane,
struct drm_plane_state *state)
+{
- plane->state = state;
- plane->base.propvals = &state->propvals;
+} +EXPORT_SYMBOL(drm_plane_commit_state);
+int drm_plane_set_property(struct drm_plane *plane,
struct drm_plane_state *state,
struct drm_property *property,
uint64_t value, void *blob_data)
+{
- struct drm_device *dev = plane->dev;
- struct drm_mode_config *config = &dev->mode_config;
- drm_object_property_set_value(&plane->base,
&state->propvals, property, value, blob_data);
- if (property == config->prop_fb_id) {
state->new_fb = true;
state->fb = drm_framebuffer_lookup(dev, value);
- } else if (property == config->prop_crtc_id) {
struct drm_mode_object *obj = drm_property_get_obj(property, value);
state->crtc = obj ? obj_to_crtc(obj) : NULL;
- } else if (property == config->prop_crtc_x) {
state->crtc_x = U642I64(value);
- } else if (property == config->prop_crtc_y) {
state->crtc_y = U642I64(value);
- } else if (property == config->prop_crtc_w) {
state->crtc_w = value;
- } else if (property == config->prop_crtc_h) {
state->crtc_h = value;
- } else if (property == config->prop_src_x) {
state->src_x = value;
- } else if (property == config->prop_src_y) {
state->src_y = value;
- } else if (property == config->prop_src_w) {
state->src_w = value;
- } else if (property == config->prop_src_h) {
state->src_h = value;
- } else {
return -EINVAL;
- }
- return 0;
+} +EXPORT_SYMBOL(drm_plane_set_property);
/**
- drm_plane_force_disable - Forcibly disable a plane
- @plane: plane to disable
@@ -980,20 +1123,15 @@ EXPORT_SYMBOL(drm_plane_cleanup);
- Used when the plane's current framebuffer is destroyed,
- and when restoring fbdev mode.
*/ -void drm_plane_force_disable(struct drm_plane *plane) +void drm_plane_force_disable(struct drm_plane *plane, void *state) {
- int ret;
- struct drm_mode_config *config = &plane->dev->mode_config;
- if (!plane->fb)
return;
- ret = plane->funcs->disable_plane(plane);
- if (ret)
DRM_ERROR("failed to disable plane with busy fb\n");
- /* disconnect the plane from the fb and crtc: */
- __drm_framebuffer_unreference(plane->fb);
- plane->fb = NULL;
- plane->crtc = NULL;
- /* should turn off the crtc */
- drm_mode_plane_set_obj_prop(plane, state,
config->prop_crtc_id, 0, NULL);
- drm_mode_plane_set_obj_prop(plane, state,
config->prop_fb_id, 0, NULL);
} EXPORT_SYMBOL(drm_plane_force_disable);
@@ -1043,21 +1181,89 @@ EXPORT_SYMBOL(drm_mode_destroy);
static int drm_mode_create_standard_connector_properties(struct drm_device *dev) {
- struct drm_property *edid;
- struct drm_property *dpms;
struct drm_property *prop;
/*
- Standard properties (apply to all connectors)
*/
- edid = drm_property_create(dev, DRM_MODE_PROP_BLOB |
- prop = drm_property_create(dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE, "EDID", 0);
- dev->mode_config.edid_property = edid;
- if (!prop)
return -ENOMEM;
- dev->mode_config.edid_property = prop;
- dpms = drm_property_create_enum(dev, 0,
- prop = drm_property_create_enum(dev, 0, "DPMS", drm_dpms_enum_list, ARRAY_SIZE(drm_dpms_enum_list));
- dev->mode_config.dpms_property = dpms;
if (!prop)
return -ENOMEM;
dev->mode_config.dpms_property = prop;
/* TODO we need the driver to control which of these are dynamic
* and which are not.. or maybe we should just set all to zero
* and let the individual drivers frob the prop->flags for the
* properties they can support dynamic changes on..
*/
prop = drm_property_create_range(dev, DRM_MODE_PROP_DYNAMIC,
"SRC_X", 0, UINT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_src_x = prop;
prop = drm_property_create_range(dev, DRM_MODE_PROP_DYNAMIC,
"SRC_Y", 0, UINT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_src_y = prop;
prop = drm_property_create_range(dev, 0, "SRC_W", 0, UINT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_src_w = prop;
prop = drm_property_create_range(dev, 0, "SRC_H", 0, UINT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_src_h = prop;
prop = drm_property_create_range(dev,
DRM_MODE_PROP_DYNAMIC | DRM_MODE_PROP_SIGNED,
"CRTC_X", I642U64(INT_MIN), I642U64(INT_MAX));
if (!prop)
return -ENOMEM;
dev->mode_config.prop_crtc_x = prop;
prop = drm_property_create_range(dev,
DRM_MODE_PROP_DYNAMIC | DRM_MODE_PROP_SIGNED,
"CRTC_Y", I642U64(INT_MIN), I642U64(INT_MAX));
if (!prop)
return -ENOMEM;
dev->mode_config.prop_crtc_y = prop;
prop = drm_property_create_range(dev, 0, "CRTC_W", 0, INT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_crtc_w = prop;
prop = drm_property_create_range(dev, 0, "CRTC_H", 0, INT_MAX);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_crtc_h = prop;
prop = drm_property_create_object(dev, DRM_MODE_PROP_DYNAMIC,
"FB_ID", DRM_MODE_OBJECT_FB);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_fb_id = prop;
prop = drm_property_create_object(dev, 0,
"CRTC_ID", DRM_MODE_OBJECT_CRTC);
if (!prop)
return -ENOMEM;
dev->mode_config.prop_crtc_id = prop;
return 0;
} @@ -1842,13 +2048,13 @@ int drm_mode_getplane(struct drm_device *dev, void *data, } plane = obj_to_plane(obj);
- if (plane->crtc)
plane_resp->crtc_id = plane->crtc->base.id;
- if (plane->state->crtc)
else plane_resp->crtc_id = 0;plane_resp->crtc_id = plane->state->crtc->base.id;
- if (plane->fb)
plane_resp->fb_id = plane->fb->base.id;
- if (plane->state->fb)
else plane_resp->fb_id = 0;plane_resp->fb_id = plane->state->fb->base.id;
@@ -1890,21 +2096,18 @@ int drm_mode_setplane(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_mode_set_plane *plane_req = data;
- struct drm_mode_config *config = &dev->mode_config; struct drm_mode_object *obj;
- struct drm_plane *plane;
- struct drm_crtc *crtc;
- struct drm_framebuffer *fb = NULL, *old_fb = NULL;
- void *state; int ret = 0;
unsigned int fb_width, fb_height;
int i;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL;
/*
* First, find the plane, crtc, and fb objects. If not available,
* we don't bother to call the driver.
*/
- state = dev->driver->atomic_begin(dev, 0);
- if (IS_ERR(state))
return PTR_ERR(state);
- obj = drm_mode_object_find(dev, plane_req->plane_id, DRM_MODE_OBJECT_PLANE); if (!obj) {
@@ -1912,102 +2115,36 @@ int drm_mode_setplane(struct drm_device *dev, void *data, plane_req->plane_id); return -ENOENT; }
plane = obj_to_plane(obj);
/* No fb means shut it down */
if (!plane_req->fb_id) {
drm_modeset_lock_all(dev);
old_fb = plane->fb;
plane->funcs->disable_plane(plane);
plane->crtc = NULL;
plane->fb = NULL;
drm_modeset_unlock_all(dev);
goto out;
}
obj = drm_mode_object_find(dev, plane_req->crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown crtc ID %d\n",
plane_req->crtc_id);
ret = -ENOENT;
goto out;
}
crtc = obj_to_crtc(obj);
fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
plane_req->fb_id);
ret = -ENOENT;
goto out;
}
/* Check whether this plane supports the fb pixel format. */
for (i = 0; i < plane->format_count; i++)
if (fb->pixel_format == plane->format_types[i])
break;
if (i == plane->format_count) {
DRM_DEBUG_KMS("Invalid pixel format %s\n",
drm_get_format_name(fb->pixel_format));
ret = -EINVAL;
goto out;
}
fb_width = fb->width << 16;
fb_height = fb->height << 16;
/* Make sure source coordinates are inside the fb. */
if (plane_req->src_w > fb_width ||
plane_req->src_x > fb_width - plane_req->src_w ||
plane_req->src_h > fb_height ||
plane_req->src_y > fb_height - plane_req->src_h) {
DRM_DEBUG_KMS("Invalid source coordinates "
"%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
plane_req->src_w >> 16,
((plane_req->src_w & 0xffff) * 15625) >> 10,
plane_req->src_h >> 16,
((plane_req->src_h & 0xffff) * 15625) >> 10,
plane_req->src_x >> 16,
((plane_req->src_x & 0xffff) * 15625) >> 10,
plane_req->src_y >> 16,
((plane_req->src_y & 0xffff) * 15625) >> 10);
ret = -ENOSPC;
goto out;
}
/* Give drivers some help against integer overflows */
if (plane_req->crtc_w > INT_MAX ||
plane_req->crtc_x > INT_MAX - (int32_t) plane_req->crtc_w ||
plane_req->crtc_h > INT_MAX ||
plane_req->crtc_y > INT_MAX - (int32_t) plane_req->crtc_h) {
DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
plane_req->crtc_w, plane_req->crtc_h,
plane_req->crtc_x, plane_req->crtc_y);
ret = -ERANGE;
- ret =
drm_mode_set_obj_prop(obj, state,
config->prop_crtc_id, plane_req->crtc_id, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_fb_id, plane_req->fb_id, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_crtc_x, I642U64(plane_req->crtc_x), NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_crtc_y, I642U64(plane_req->crtc_y), NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_crtc_w, plane_req->crtc_w, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_crtc_h, plane_req->crtc_h, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_src_w, plane_req->src_w, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_src_h, plane_req->src_h, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_src_x, plane_req->src_x, NULL) ||
drm_mode_set_obj_prop(obj, state,
config->prop_src_y, plane_req->src_y, NULL) ||
dev->driver->atomic_check(dev, state);
- if (ret) goto out;
}
drm_modeset_lock_all(dev);
ret = plane->funcs->update_plane(plane, crtc, fb,
plane_req->crtc_x, plane_req->crtc_y,
plane_req->crtc_w, plane_req->crtc_h,
plane_req->src_x, plane_req->src_y,
plane_req->src_w, plane_req->src_h);
if (!ret) {
old_fb = plane->fb;
plane->crtc = crtc;
plane->fb = fb;
fb = NULL;
}
drm_modeset_unlock_all(dev);
- ret = dev->driver->atomic_commit(dev, state);
out:
- if (fb)
drm_framebuffer_unreference(fb);
- if (old_fb)
drm_framebuffer_unreference(old_fb);
- dev->driver->atomic_end(dev, state); return ret;
}
@@ -3296,7 +3433,7 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv); }
-static int drm_mode_connector_set_obj_prop(struct drm_connector *connector, +int drm_mode_connector_set_obj_prop(struct drm_connector *connector, void *state, struct drm_property *property, uint64_t value, void *blob_data) { @@ -3319,8 +3456,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_connector *connector,
return ret; } +EXPORT_SYMBOL(drm_mode_connector_set_obj_prop);
-static int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc, +int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc, void *state, struct drm_property *property, uint64_t value, void *blob_data) { @@ -3335,8 +3473,9 @@ static int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc,
return ret; } +EXPORT_SYMBOL(drm_mode_crtc_set_obj_prop);
-static int drm_mode_plane_set_obj_prop(struct drm_plane *plane, +int drm_mode_plane_set_obj_prop(struct drm_plane *plane, void *state, struct drm_property *property, uint64_t value, void *blob_data) { @@ -3345,12 +3484,10 @@ static int drm_mode_plane_set_obj_prop(struct drm_plane *plane, if (plane->funcs->set_property) ret = plane->funcs->set_property(plane, state, property, value, blob_data);
if (!ret)
drm_object_property_set_value(&plane->base, &plane->propvals,
property, value, NULL);
return ret;
} +EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
static int drm_mode_set_obj_prop(struct drm_mode_object *obj, void *state, struct drm_property *property, diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 24898dc..f1fc605 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -290,12 +290,27 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) struct drm_device *dev = fb_helper->dev; struct drm_plane *plane; bool error = false;
void *state; int i;
drm_warn_on_modeset_not_all_locked(dev);
state = dev->driver->atomic_begin(dev, 0);
if (IS_ERR(state)) {
DRM_ERROR("failed to restore fbdev mode\n");
return true;
}
list_for_each_entry(plane, &dev->mode_config.plane_list, head)
drm_plane_force_disable(plane);
drm_plane_force_disable(plane, state);
- /* just disabling stuff shouldn't fail, hopefully: */
- if(dev->driver->atomic_check(dev, state))
DRM_ERROR("failed to restore fbdev mode\n");
- else
dev->driver->atomic_commit(dev, state);
I'm seeing some deadlocks here on i915 when we trigger the lastclose handler. We're already holding mode_config.mutex when we enter this function, but drm_atomic_helper_commit_plane_state does another drm_modeset_lock_all() call.
Matt
dev->driver->atomic_end(dev, state);
for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 82a9fca..4ae55b8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -124,8 +124,8 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, if (ret) return ret;
- plane->crtc = crtc;
- plane->fb = crtc->fb;
plane->state->crtc = crtc;
plane->state->fb = crtc->fb;
exynos_drm_fn_encoder(crtc, &pipe, exynos_drm_encoder_crtc_pipe);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 06f1b2a..dbe2e19 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -127,7 +127,7 @@ static void disable_plane_to_crtc(struct drm_device *dev, * (encoder->crtc) */ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
if (plane->crtc == old_crtc) {
if (plane->state->crtc == old_crtc) { /* * do not change below call order. *
@@ -138,7 +138,7 @@ static void disable_plane_to_crtc(struct drm_device *dev, * have new_crtc because new_crtc was set to * encoder->crtc in advance. */
plane->crtc = new_crtc;
} }plane->state->crtc = new_crtc; plane->funcs->disable_plane(plane);
@@ -247,7 +247,7 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
/* all planes connected to this encoder should be also disabled. */ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
if (plane->crtc == encoder->crtc)
}if (plane->state->crtc == encoder->crtc) plane->funcs->disable_plane(plane);
} diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 2e31fb8..45d0fa3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -10,6 +10,7 @@ */
#include <drm/drmP.h> +#include <drm/drm_atomic_helper.h>
#include <drm/exynos_drm.h> #include "exynos_drm_drv.h" @@ -149,7 +150,7 @@ void exynos_plane_commit(struct drm_plane *plane) struct exynos_plane *exynos_plane = to_exynos_plane(plane); struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
- exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
- exynos_drm_fn_encoder(plane->state->crtc, &overlay->zpos, exynos_drm_encoder_plane_commit);
}
@@ -162,7 +163,7 @@ void exynos_plane_dpms(struct drm_plane *plane, int mode) if (exynos_plane->enabled) return;
exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
exynos_drm_fn_encoder(plane->state->crtc, &overlay->zpos, exynos_drm_encoder_plane_enable);
exynos_plane->enabled = true;
@@ -170,7 +171,7 @@ void exynos_plane_dpms(struct drm_plane *plane, int mode) if (!exynos_plane->enabled) return;
exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
exynos_drm_fn_encoder(plane->state->crtc, &overlay->zpos, exynos_drm_encoder_plane_disable);
exynos_plane->enabled = false;
@@ -192,7 +193,7 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (ret < 0) return ret;
- plane->crtc = crtc;
plane->state->crtc = crtc;
exynos_plane_commit(plane); exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
@@ -229,6 +230,10 @@ static int exynos_plane_set_property(struct drm_plane *plane, if (property == dev_priv->plane_zpos_property) { exynos_plane->overlay.zpos = val; return 0;
} else {
return drm_plane_set_property(plane,
drm_atomic_get_plane_state(plane, state),
property, val, blob_data);
}
return -EINVAL;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index ad6ec4b..d8c2869 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -868,16 +868,17 @@ intel_disable_plane(struct drm_plane *plane) { struct drm_device *dev = plane->dev; struct intel_plane *intel_plane = to_intel_plane(plane);
- struct drm_plane_state *state = plane->state; int ret = 0;
- if (!plane->fb)
- if (!state->fb) return 0;
- if (WARN_ON(!plane->crtc))
- if (WARN_ON(!state->crtc)) return -EINVAL;
- intel_enable_primary(plane->crtc);
- intel_plane->disable_plane(plane, plane->crtc);
intel_enable_primary(state->crtc);
intel_plane->disable_plane(plane, state->crtc);
if (!intel_plane->obj) goto out;
@@ -966,11 +967,12 @@ out_unlock: void intel_plane_restore(struct drm_plane *plane) { struct intel_plane *intel_plane = to_intel_plane(plane);
- struct drm_plane_state *state = plane->state;
- if (!plane->crtc || !plane->fb)
- if (!state->crtc || !state->fb) return;
- intel_update_plane(plane, plane->crtc, plane->fb,
- intel_update_plane(plane, state->crtc, state->fb, intel_plane->crtc_x, intel_plane->crtc_y, intel_plane->crtc_w, intel_plane->crtc_h, intel_plane->src_x, intel_plane->src_y,
@@ -979,7 +981,9 @@ void intel_plane_restore(struct drm_plane *plane)
void intel_plane_disable(struct drm_plane *plane) {
- if (!plane->crtc || !plane->fb)
struct drm_plane_state *state = plane->state;
if (!state->crtc || !state->fb) return;
intel_disable_plane(plane);
@@ -989,6 +993,7 @@ static const struct drm_plane_funcs intel_plane_funcs = { .update_plane = intel_update_plane, .disable_plane = intel_disable_plane, .destroy = intel_destroy_plane,
- .set_property = drm_atomic_helper_plane_set_property,
};
static uint32_t ilk_plane_formats[] = { diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c index d3fd7ca..1d6a6ee 100644 --- a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c @@ -243,7 +243,7 @@ static void blend_setup(struct drm_crtc *crtc) int idx = idxs[pipe_id]; if (idx > 0) { const struct mdp4_format *format =
to_mdp4_format(msm_framebuffer_format(plane->fb));
to_mdp4_format(msm_framebuffer_format(plane->state->fb)); alpha[idx-1] = format->alpha_enable; } mixer_cfg |= mixercfg(mdp4_crtc->mixer, pipe_id, stages[idx]);
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c index 880e96d..8338b1a 100644 --- a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c @@ -45,11 +45,14 @@ static int mdp4_plane_update(struct drm_plane *plane, uint32_t src_w, uint32_t src_h) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
struct drm_plane_state *state = plane->state;
mdp4_plane->enabled = true;
- if (plane->fb)
drm_framebuffer_unreference(plane->fb);
if (state->fb) {
drm_framebuffer_unreference(state->fb);
state->fb = NULL;
}
drm_framebuffer_reference(fb);
@@ -62,8 +65,8 @@ static int mdp4_plane_disable(struct drm_plane *plane) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); DBG("%s: disable", mdp4_plane->name);
- if (plane->crtc)
mdp4_crtc_detach(plane->crtc, plane);
- if (plane->state->crtc)
return 0;mdp4_crtc_detach(plane->state->crtc, plane);
}
@@ -87,8 +90,9 @@ void mdp4_plane_install_properties(struct drm_plane *plane, int mdp4_plane_set_property(struct drm_plane *plane, void *state, struct drm_property *property, uint64_t val, void *blob_data) {
- // XXX
- return -EINVAL;
- return drm_plane_set_property(plane,
drm_atomic_get_plane_state(plane, state),
property, val, blob_data);
}
static const struct drm_plane_funcs mdp4_plane_funcs = { @@ -117,7 +121,7 @@ void mdp4_plane_set_scanout(struct drm_plane *plane, msm_gem_get_iova(msm_framebuffer_bo(fb, 0), mdp4_kms->id, &iova); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova);
- plane->fb = fb;
- plane->state->fb = fb;
}
#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 5dd22ab..d53a689 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -210,7 +210,7 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode) /* and any attached overlay planes: */ for (i = 0; i < priv->num_planes; i++) { struct drm_plane *plane = priv->planes[i];
if (plane->crtc == crtc)
} }if (plane->state->crtc == crtc) WARN_ON(omap_plane_dpms(plane, mode));
@@ -651,7 +651,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
omap_crtc->channel = channel; omap_crtc->plane = plane;
- omap_crtc->plane->crtc = crtc;
- omap_crtc->plane->state->crtc = crtc; omap_crtc->name = channel_names[channel]; omap_crtc->pipe = id;
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 225d0e9..0e15e2c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -559,7 +559,7 @@ static void dev_lastclose(struct drm_device *dev)
for (i = 0; i < priv->num_planes; i++) { drm_object_property_set_value(&priv->planes[i]->base,
&priv->planes[i]->propvals,
} }&priv->planes[i]->state->propvals, priv->rotation_prop, 0, NULL);
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index fe32f1b..d11a879 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -116,9 +116,10 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply) container_of(apply, struct omap_plane, apply); struct omap_drm_window *win = &omap_plane->win; struct drm_plane *plane = &omap_plane->base;
- struct drm_plane_state *state = plane->state; struct drm_device *dev = plane->dev; struct omap_overlay_info *info = &omap_plane->info;
- struct drm_crtc *crtc = plane->crtc;
- struct drm_crtc *crtc = state->crtc; enum omap_channel channel; bool enabled = omap_plane->enabled && crtc; bool ilace, replication;
@@ -127,7 +128,7 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply) DBG("%s, enabled=%d", omap_plane->name, enabled);
/* if fb has changed, pin new fb: */
- update_pin(plane, enabled ? plane->fb : NULL);
update_pin(plane, enabled ? state->fb : NULL);
if (!enabled) { dispc_ovl_enable(omap_plane->id, false);
@@ -137,7 +138,7 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply) channel = omap_crtc_channel(crtc);
/* update scanout: */
- omap_framebuffer_update_scanout(plane->fb, win, info);
omap_framebuffer_update_scanout(state->fb, win, info);
DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, info->out_height,
@@ -179,16 +180,18 @@ static void omap_plane_post_apply(struct omap_drm_apply *apply) cb.fxn(cb.arg);
if (omap_plane->enabled) {
omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y,
omap_framebuffer_flush(plane->state->fb,
}info->pos_x, info->pos_y, info->out_width, info->out_height);
}
static int apply(struct drm_plane *plane) {
- if (plane->crtc) {
- struct drm_plane_state *state = plane->state;
- if (state->crtc) { struct omap_plane *omap_plane = to_omap_plane(plane);
return omap_crtc_apply(plane->crtc, &omap_plane->apply);
} return 0;return omap_crtc_apply(state->crtc, &omap_plane->apply);
} @@ -203,6 +206,7 @@ int omap_plane_mode_set(struct drm_plane *plane, { struct omap_plane *omap_plane = to_omap_plane(plane); struct omap_drm_window *win = &omap_plane->win;
struct drm_plane_state *state = plane->state;
win->crtc_x = crtc_x; win->crtc_y = crtc_y;
@@ -225,8 +229,8 @@ int omap_plane_mode_set(struct drm_plane *plane, omap_plane->apply_done_cb.arg = arg; }
- plane->fb = fb;
- plane->crtc = crtc;
state->fb = fb;
state->crtc = crtc;
return apply(plane);
} @@ -239,10 +243,12 @@ static int omap_plane_update(struct drm_plane *plane, uint32_t src_w, uint32_t src_h) { struct omap_plane *omap_plane = to_omap_plane(plane);
- struct drm_plane_state *state = plane->state;
- omap_plane->enabled = true;
- if (plane->fb)
drm_framebuffer_unreference(plane->fb);
if (state->fb)
drm_framebuffer_unreference(state->fb);
drm_framebuffer_reference(fb);
@@ -342,6 +348,10 @@ int omap_plane_set_property(struct drm_plane *plane, void *state, DBG("%s: zorder: %02x", omap_plane->name, (uint32_t)val); omap_plane->info.zorder = val; ret = apply(plane);
} else {
ret = drm_plane_set_property(plane,
drm_atomic_get_plane_state(plane, state),
property, val, blob_data);
}
return ret;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 5691743..909e241 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -14,6 +14,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
@@ -411,7 +412,9 @@ static int rcar_du_plane_set_property(struct drm_plane *plane, else if (property == rgrp->planes.zpos) rcar_du_plane_set_zpos(rplane, value); else
return -EINVAL;
return drm_plane_set_property(plane,
drm_atomic_get_plane_state(plane, state),
property, value, blob_data);
return 0;
} diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c index 035bd67..e62b0f2 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c @@ -238,7 +238,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc)
/* Setup planes. */ list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
if (plane->crtc == crtc)
}if (plane->state->crtc == crtc) shmob_drm_plane_setup(plane);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/shmobile/shmob_drm_plane.c index 060ae03..22da5c1 100644 --- a/drivers/gpu/drm/shmobile/shmob_drm_plane.c +++ b/drivers/gpu/drm/shmobile/shmob_drm_plane.c @@ -14,6 +14,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h>
@@ -166,10 +167,10 @@ void shmob_drm_plane_setup(struct drm_plane *plane) { struct shmob_drm_plane *splane = to_shmob_plane(plane);
- if (plane->fb == NULL)
- if (plane->state->fb == NULL) return;
- __shmob_drm_plane_setup(splane, plane->fb);
- __shmob_drm_plane_setup(splane, plane->state->fb);
}
static int @@ -228,6 +229,7 @@ static void shmob_drm_plane_destroy(struct drm_plane *plane) static const struct drm_plane_funcs shmob_drm_plane_funcs = { .update_plane = shmob_drm_plane_update, .disable_plane = shmob_drm_plane_disable,
- .set_property = drm_atomic_helper_plane_set_property, .destroy = shmob_drm_plane_destroy,
};
diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c index b1a05ad..5766010 100644 --- a/drivers/gpu/host1x/drm/dc.c +++ b/drivers/gpu/host1x/drm/dc.c @@ -75,11 +75,11 @@ static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
static int tegra_plane_disable(struct drm_plane *plane) {
- struct tegra_dc *dc = to_tegra_dc(plane->crtc);
- struct tegra_dc *dc = to_tegra_dc(plane->state->crtc); struct tegra_plane *p = to_tegra_plane(plane); unsigned long value;
- if (!plane->crtc)
if (!plane->state->crtc) return 0;
value = WINDOW_A_SELECT << p->index;
@@ -104,6 +104,7 @@ static void tegra_plane_destroy(struct drm_plane *plane) static const struct drm_plane_funcs tegra_plane_funcs = { .update_plane = tegra_plane_update, .disable_plane = tegra_plane_disable,
- .set_property = drm_atomic_helper_plane_set_property, .destroy = tegra_plane_destroy,
};
@@ -267,13 +268,14 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) struct drm_plane *plane;
list_for_each_entry(plane, &drm->mode_config.plane_list, head) {
if (plane->crtc == crtc) {
struct drm_plane_state *state = plane->state;
if (state->crtc == crtc) { tegra_plane_disable(plane);
plane->crtc = NULL;
state->crtc = NULL;
if (plane->fb) {
drm_framebuffer_unreference(plane->fb);
plane->fb = NULL;
if (state->fb) {
drm_framebuffer_unreference(state->fb);
} }state->fb = NULL; }
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index e70cd7b..d0d29e1 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -62,7 +62,9 @@
- struct drm_atomic_helper_funcs - helper funcs used by the atomic helpers
*/ struct drm_atomic_helper_funcs {
- int dummy; /* for now */
- struct drm_plane_state *(*get_plane_state)(struct drm_plane *plane, void *state);
- int (*check_plane_state)(struct drm_plane *plane, struct drm_plane_state *pstate);
- int (*commit_plane_state)(struct drm_plane *plane, struct drm_plane_state *pstate);
};
const extern struct drm_atomic_helper_funcs drm_atomic_helper_funcs; @@ -75,6 +77,37 @@ int drm_atomic_helper_check(struct drm_device *dev, void *state); int drm_atomic_helper_commit(struct drm_device *dev, void *state); void drm_atomic_helper_end(struct drm_device *dev, void *state);
+int drm_atomic_helper_plane_set_property(struct drm_plane *plane, void *state,
struct drm_property *property, uint64_t val, void *blob_data);
+void drm_atomic_helper_init_plane_state(struct drm_plane *plane,
struct drm_plane_state *pstate, void *state);
+static inline struct drm_plane_state * +drm_atomic_get_plane_state(struct drm_plane *plane, void *state) +{
- const struct drm_atomic_helper_funcs *funcs =
plane->dev->driver->atomic_helpers;
- return funcs->get_plane_state(plane, state);
+}
+static inline int +drm_atomic_check_plane_state(struct drm_plane *plane,
struct drm_plane_state *pstate)
+{
- const struct drm_atomic_helper_funcs *funcs =
plane->dev->driver->atomic_helpers;
- return funcs->check_plane_state(plane, pstate);
+}
+static inline int +drm_atomic_commit_plane_state(struct drm_plane *plane,
struct drm_plane_state *pstate)
+{
- const struct drm_atomic_helper_funcs *funcs =
plane->dev->driver->atomic_helpers;
- return funcs->commit_plane_state(plane, pstate);
+}
/**
- struct drm_atomic_helper_state - the state object used by atomic helpers
*/ @@ -82,6 +115,8 @@ struct drm_atomic_helper_state { struct kref refcount; struct drm_device *dev; uint32_t flags;
- struct drm_plane **planes;
- struct drm_plane_state **pstates;
};
static inline void diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 8831562..ee46a6a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -675,6 +675,45 @@ struct drm_plane_funcs { };
/**
- drm_plane_state - mutable plane state
- @new_fb: has the fb been changed
- @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)
- @propvals: property values
- @state: current global/toplevel state object (for atomic) while an
- update is in progress, NULL otherwise.
- */
+struct drm_plane_state {
- bool new_fb : 1;
- 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;
- bool enabled;
- struct drm_object_property_values propvals;
- void *state;
+};
+/**
- drm_plane - central DRM plane control structure
- @dev: DRM device this plane belongs to
- @head: for list management
@@ -682,8 +721,8 @@ struct drm_plane_funcs {
- @possible_crtcs: pipes this plane can be bound to
- @format_types: array of formats supported by this plane
- @format_count: number of formats supported
- @crtc: currently bound CRTC
- @fb: currently bound fb
- @id: plane number, 0..n
*/
- @state: the mutable state
- @funcs: helper functions
- @properties: property tracking for this plane
@@ -697,13 +736,17 @@ struct drm_plane { uint32_t *format_types; uint32_t format_count;
- struct drm_crtc *crtc;
- struct drm_framebuffer *fb;
int id;
/*
* State that can be updated from userspace, and atomically
* commited or rolled back:
*/
struct drm_plane_state *state;
const struct drm_plane_funcs *funcs;
struct drm_object_properties properties;
- struct drm_object_property_values propvals;
};
/** @@ -884,8 +927,20 @@ struct drm_mode_config { bool poll_running; struct delayed_work output_poll_work;
- /* pointers to standard properties */
- /* just so blob properties can always be in a list: */ struct list_head property_blob_list;
- /* pointers to standard properties */
- struct drm_property *prop_src_x;
- struct drm_property *prop_src_y;
- struct drm_property *prop_src_w;
- struct drm_property *prop_src_h;
- struct drm_property *prop_crtc_x;
- struct drm_property *prop_crtc_y;
- struct drm_property *prop_crtc_w;
- struct drm_property *prop_crtc_h;
- struct drm_property *prop_fb_id;
- struct drm_property *prop_crtc_id; struct drm_property *edid_property; struct drm_property *dpms_property;
@@ -969,7 +1024,15 @@ extern int drm_plane_init(struct drm_device *dev, const uint32_t *formats, uint32_t format_count, bool priv); extern void drm_plane_cleanup(struct drm_plane *plane); -extern void drm_plane_force_disable(struct drm_plane *plane); +extern void drm_plane_force_disable(struct drm_plane *plane, void *state); +extern int drm_plane_check_state(struct drm_plane *plane,
struct drm_plane_state *state);
+extern void drm_plane_commit_state(struct drm_plane *plane,
struct drm_plane_state *state);
+extern int drm_plane_set_property(struct drm_plane *plane,
struct drm_plane_state *state,
struct drm_property *property,
uint64_t value, void *blob_data);
extern void drm_encoder_cleanup(struct drm_encoder *encoder);
@@ -1023,6 +1086,17 @@ extern int drm_object_property_set_value(struct drm_mode_object *obj, extern int drm_object_property_get_value(struct drm_mode_object *obj, struct drm_property *property, uint64_t *value);
+int drm_mode_connector_set_obj_prop(struct drm_connector *connector,
void *state, struct drm_property *property,
uint64_t value, void *blob_data);
+int drm_mode_crtc_set_obj_prop(struct drm_crtc *crtc,
void *state, struct drm_property *property,
uint64_t value, void *blob_data);
+int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
void *state, struct drm_property *property,
uint64_t value, void *blob_data);
extern int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, const struct drm_framebuffer_funcs *funcs); -- 1.8.3.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel