state->crtcs[index] = crtc;
crtc_state->state = state;
- DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n",
- crtc->base.id, crtc_state, state);
+ DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
+ crtc->base.id, crtc->name, crtc_state, state);
return crtc_state;
}
if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
return 0;
- if (state->mode_blob)
- drm_property_unreference_blob(state->mode_blob);
+ drm_property_unreference_blob(state->mode_blob);
state->mode_blob = NULL;
if (mode) {
if (blob == state->mode_blob)
return 0;
- if (state->mode_blob)
- drm_property_unreference_blob(state->mode_blob);
+ drm_property_unreference_blob(state->mode_blob);
state->mode_blob = NULL;
if (blob) {
struct drm_property_blob *mode =
drm_property_lookup_blob(dev, val);
ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
- if (mode)
- drm_property_unreference_blob(mode);
+ drm_property_unreference_blob(mode);
return ret;
}
else if (crtc->funcs->atomic_set_property)
}
EXPORT_SYMBOL(drm_atomic_crtc_set_property);
-/*
+/**
+ * drm_atomic_crtc_get_property - get property value from CRTC state
+ * @crtc: the drm CRTC to set a property on
+ * @state: the state object to get the property value from
+ * @property: the property to set
+ * @val: return location for the property value
+ *
* This function handles generic/core properties and calls out to
* driver's ->atomic_get_property() for driver properties. To ensure
* consistent behavior you must call this function rather than the
* driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
*/
static int
drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*/
if (state->active && !state->enable) {
- DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n",
- crtc->base.id);
+ DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
+ crtc->base.id, crtc->name);
return -EINVAL;
}
* be able to trigger. */
if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
WARN_ON(state->enable && !state->mode_blob)) {
- DRM_DEBUG_ATOMIC("[CRTC:%d] enabled without mode blob\n",
- crtc->base.id);
+ DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
+ crtc->base.id, crtc->name);
return -EINVAL;
}
if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
WARN_ON(!state->enable && state->mode_blob)) {
- DRM_DEBUG_ATOMIC("[CRTC:%d] disabled with mode blob\n",
- crtc->base.id);
+ DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
+ crtc->base.id, crtc->name);
return -EINVAL;
}
}
EXPORT_SYMBOL(drm_atomic_plane_set_property);
-/*
+/**
+ * drm_atomic_plane_get_property - get property value from plane state
+ * @plane: the drm plane to set a property on
+ * @state: the state object to get the property value from
+ * @property: the property to set
+ * @val: return location for the property value
+ *
* This function handles generic/core properties and calls out to
* driver's ->atomic_get_property() for driver properties. To ensure
* consistent behavior you must call this function rather than the
* driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
*/
static int
drm_atomic_plane_get_property(struct drm_plane *plane,
}
EXPORT_SYMBOL(drm_atomic_connector_set_property);
-/*
+/**
+ * drm_atomic_connector_get_property - get property value from connector state
+ * @connector: the drm connector to set a property on
+ * @state: the state object to get the property value from
+ * @property: the property to set
+ * @val: return location for the property value
+ *
* This function handles generic/core properties and calls out to
* driver's ->atomic_get_property() for driver properties. To ensure
* consistent behavior you must call this function rather than the
* driver hook directly.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
*/
static int
drm_atomic_connector_get_property(struct drm_connector *connector,
}
if (crtc)
- DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n",
- plane_state, crtc->base.id);
+ DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d:%s]\n",
+ plane_state, crtc->base.id, crtc->name);
else
DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n",
plane_state);
conn_state->crtc = crtc;
if (crtc)
- DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n",
- conn_state, crtc->base.id);
+ DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d:%s]\n",
+ conn_state, crtc->base.id, crtc->name);
else
DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n",
conn_state);
if (ret)
return ret;
- DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n",
- crtc->base.id, state);
+ DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
+ crtc->base.id, crtc->name, state);
/*
* Changed connectors are already in @state, so only need to look at the
num_connected_connectors++;
}
- DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n",
- state, num_connected_connectors, crtc->base.id);
+ DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d:%s]\n",
+ state, num_connected_connectors,
+ crtc->base.id, crtc->name);
return num_connected_connectors;
}
retry:
drm_modeset_backoff(state->acquire_ctx);
- ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
- state->acquire_ctx);
- if (ret)
- goto retry;
- ret = drm_modeset_lock_all_crtcs(state->dev,
- state->acquire_ctx);
+ ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
if (ret)
goto retry;
}
for_each_crtc_in_state(state, crtc, crtc_state, i) {
ret = drm_atomic_crtc_check(crtc, crtc_state);
if (ret) {
- DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n",
- crtc->base.id);
+ DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
+ crtc->base.id, crtc->name);
return ret;
}
}
if (!state->allow_modeset) {
for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
- DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n",
- crtc->base.id);
+ DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
+ crtc->base.id, crtc->name);
return -EINVAL;
}
}
return ret;
}
+/**
+ * drm_atomic_clean_old_fb -- Unset old_fb pointers and set plane->fb pointers.
+ *
+ * @dev: drm device to check.
+ * @plane_mask: plane mask for planes that were updated.
+ * @ret: return value, can be -EDEADLK for a retry.
+ *
+ * Before doing an update plane->old_fb is set to plane->fb,
+ * but before dropping the locks old_fb needs to be set to NULL
+ * and plane->fb updated. This is a common operation for each
+ * atomic update, so this call is split off as a helper.
+ */
+void drm_atomic_clean_old_fb(struct drm_device *dev,
+ unsigned plane_mask,
+ int ret)
+{
+ struct drm_plane *plane;
+
+ /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
+ * locks (ie. while it is still safe to deref plane->state). We
+ * need to do this here because the driver entry points cannot
+ * distinguish between legacy and atomic ioctls.
+ */
+ drm_for_each_plane_mask(plane, dev, plane_mask) {
+ if (ret == 0) {
+ struct drm_framebuffer *new_fb = plane->state->fb;
+ if (new_fb)
+ drm_framebuffer_reference(new_fb);
+ plane->fb = new_fb;
+ plane->crtc = plane->state->crtc;
+
+ if (plane->old_fb)
+ drm_framebuffer_unreference(plane->old_fb);
+ }
+ plane->old_fb = NULL;
+ }
+}
+EXPORT_SYMBOL(drm_atomic_clean_old_fb);
+
int drm_mode_atomic_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_plane *plane;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
- unsigned plane_mask = 0;
+ unsigned plane_mask;
int ret = 0;
unsigned int i, j;
state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
retry:
+ plane_mask = 0;
copied_objs = 0;
copied_props = 0;
}
out:
- /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
- * locks (ie. while it is still safe to deref plane->state). We
- * need to do this here because the driver entry points cannot
- * distinguish between legacy and atomic ioctls.
- */
- drm_for_each_plane_mask(plane, dev, plane_mask) {
- if (ret == 0) {
- struct drm_framebuffer *new_fb = plane->state->fb;
- if (new_fb)
- drm_framebuffer_reference(new_fb);
- plane->fb = new_fb;
- plane->crtc = plane->state->crtc;
-
- if (plane->old_fb)
- drm_framebuffer_unreference(plane->old_fb);
- }
- plane->old_fb = NULL;
- }
+ drm_atomic_clean_old_fb(dev, plane_mask, ret);
if (ret && arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
/*