Commit 415c3ac3 authored by Maarten Lankhorst's avatar Maarten Lankhorst

drm/atomic: Fix atomic helpers to use the new iterator macros, v3.

There are new iterator macros that annotate whether the new or old
state should be used. This is better than using a state that depends on
whether it's called before or after swap. For clarity, also rename the
variables from $obj_state to (old,new)_$obj_state as well.

Changes since v1:
- Use old/new_*_state for variable names as much as possible. (pinchartl)
- Expand commit message.
Changes since v2:
- Rebase on top of link training patches.
- free -> cleanup (pinchartl)
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: http://patchwork.freedesktop.org/patch/msgid/aafa0d4d-474d-441f-3685-fa6c042ef37e@linux.intel.comTested-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
parent 7160d57b
...@@ -63,14 +63,15 @@ ...@@ -63,14 +63,15 @@
*/ */
static void static void
drm_atomic_helper_plane_changed(struct drm_atomic_state *state, drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
struct drm_plane_state *old_plane_state,
struct drm_plane_state *plane_state, struct drm_plane_state *plane_state,
struct drm_plane *plane) struct drm_plane *plane)
{ {
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
if (plane->state->crtc) { if (old_plane_state->crtc) {
crtc_state = drm_atomic_get_existing_crtc_state(state, crtc_state = drm_atomic_get_existing_crtc_state(state,
plane->state->crtc); old_plane_state->crtc);
if (WARN_ON(!crtc_state)) if (WARN_ON(!crtc_state))
return; return;
...@@ -92,7 +93,7 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state, ...@@ -92,7 +93,7 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
static int handle_conflicting_encoders(struct drm_atomic_state *state, static int handle_conflicting_encoders(struct drm_atomic_state *state,
bool disable_conflicting_encoders) bool disable_conflicting_encoders)
{ {
struct drm_connector_state *conn_state; struct drm_connector_state *new_conn_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter; struct drm_connector_list_iter conn_iter;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -104,15 +105,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, ...@@ -104,15 +105,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
* part of the state. If the same encoder is assigned to multiple * part of the state. If the same encoder is assigned to multiple
* connectors bail out. * connectors bail out.
*/ */
for_each_connector_in_state(state, connector, conn_state, i) { for_each_new_connector_in_state(state, connector, new_conn_state, i) {
const struct drm_connector_helper_funcs *funcs = connector->helper_private; const struct drm_connector_helper_funcs *funcs = connector->helper_private;
struct drm_encoder *new_encoder; struct drm_encoder *new_encoder;
if (!conn_state->crtc) if (!new_conn_state->crtc)
continue; continue;
if (funcs->atomic_best_encoder) if (funcs->atomic_best_encoder)
new_encoder = funcs->atomic_best_encoder(connector, conn_state); new_encoder = funcs->atomic_best_encoder(connector, new_conn_state);
else if (funcs->best_encoder) else if (funcs->best_encoder)
new_encoder = funcs->best_encoder(connector); new_encoder = funcs->best_encoder(connector);
else else
...@@ -166,20 +167,20 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state, ...@@ -166,20 +167,20 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
goto out; goto out;
} }
conn_state = drm_atomic_get_connector_state(state, connector); new_conn_state = drm_atomic_get_connector_state(state, connector);
if (IS_ERR(conn_state)) { if (IS_ERR(new_conn_state)) {
ret = PTR_ERR(conn_state); ret = PTR_ERR(new_conn_state);
goto out; goto out;
} }
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n", DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
encoder->base.id, encoder->name, encoder->base.id, encoder->name,
conn_state->crtc->base.id, conn_state->crtc->name, new_conn_state->crtc->base.id, new_conn_state->crtc->name,
connector->base.id, connector->name); connector->base.id, connector->name);
crtc_state = drm_atomic_get_existing_crtc_state(state, conn_state->crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, new_conn_state->crtc);
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); ret = drm_atomic_set_crtc_for_connector(new_conn_state, NULL);
if (ret) if (ret)
goto out; goto out;
...@@ -245,22 +246,22 @@ steal_encoder(struct drm_atomic_state *state, ...@@ -245,22 +246,22 @@ steal_encoder(struct drm_atomic_state *state,
{ {
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *connector_state; struct drm_connector_state *old_connector_state, *new_connector_state;
int i; int i;
for_each_connector_in_state(state, connector, connector_state, i) { for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
struct drm_crtc *encoder_crtc; struct drm_crtc *encoder_crtc;
if (connector_state->best_encoder != encoder) if (new_connector_state->best_encoder != encoder)
continue; continue;
encoder_crtc = connector->state->crtc; encoder_crtc = old_connector_state->crtc;
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n", DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
encoder->base.id, encoder->name, encoder->base.id, encoder->name,
encoder_crtc->base.id, encoder_crtc->name); encoder_crtc->base.id, encoder_crtc->name);
set_best_encoder(state, connector_state, NULL); set_best_encoder(state, new_connector_state, NULL);
crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc);
crtc_state->connectors_changed = true; crtc_state->connectors_changed = true;
...@@ -272,7 +273,8 @@ steal_encoder(struct drm_atomic_state *state, ...@@ -272,7 +273,8 @@ steal_encoder(struct drm_atomic_state *state,
static int static int
update_connector_routing(struct drm_atomic_state *state, update_connector_routing(struct drm_atomic_state *state,
struct drm_connector *connector, struct drm_connector *connector,
struct drm_connector_state *connector_state) struct drm_connector_state *old_connector_state,
struct drm_connector_state *new_connector_state)
{ {
const struct drm_connector_helper_funcs *funcs; const struct drm_connector_helper_funcs *funcs;
struct drm_encoder *new_encoder; struct drm_encoder *new_encoder;
...@@ -282,24 +284,24 @@ update_connector_routing(struct drm_atomic_state *state, ...@@ -282,24 +284,24 @@ update_connector_routing(struct drm_atomic_state *state,
connector->base.id, connector->base.id,
connector->name); connector->name);
if (connector->state->crtc != connector_state->crtc) { if (old_connector_state->crtc != new_connector_state->crtc) {
if (connector->state->crtc) { if (old_connector_state->crtc) {
crtc_state = drm_atomic_get_existing_crtc_state(state, connector->state->crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, old_connector_state->crtc);
crtc_state->connectors_changed = true; crtc_state->connectors_changed = true;
} }
if (connector_state->crtc) { if (new_connector_state->crtc) {
crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, new_connector_state->crtc);
crtc_state->connectors_changed = true; crtc_state->connectors_changed = true;
} }
} }
if (!connector_state->crtc) { if (!new_connector_state->crtc) {
DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n", DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n",
connector->base.id, connector->base.id,
connector->name); connector->name);
set_best_encoder(state, connector_state, NULL); set_best_encoder(state, new_connector_state, NULL);
return 0; return 0;
} }
...@@ -308,7 +310,7 @@ update_connector_routing(struct drm_atomic_state *state, ...@@ -308,7 +310,7 @@ update_connector_routing(struct drm_atomic_state *state,
if (funcs->atomic_best_encoder) if (funcs->atomic_best_encoder)
new_encoder = funcs->atomic_best_encoder(connector, new_encoder = funcs->atomic_best_encoder(connector,
connector_state); new_connector_state);
else if (funcs->best_encoder) else if (funcs->best_encoder)
new_encoder = funcs->best_encoder(connector); new_encoder = funcs->best_encoder(connector);
else else
...@@ -321,34 +323,34 @@ update_connector_routing(struct drm_atomic_state *state, ...@@ -321,34 +323,34 @@ update_connector_routing(struct drm_atomic_state *state,
return -EINVAL; return -EINVAL;
} }
if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) { if (!drm_encoder_crtc_ok(new_encoder, new_connector_state->crtc)) {
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n", DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n",
new_encoder->base.id, new_encoder->base.id,
new_encoder->name, new_encoder->name,
connector_state->crtc->base.id, new_connector_state->crtc->base.id,
connector_state->crtc->name); new_connector_state->crtc->name);
return -EINVAL; return -EINVAL;
} }
if (new_encoder == connector_state->best_encoder) { if (new_encoder == new_connector_state->best_encoder) {
set_best_encoder(state, connector_state, new_encoder); set_best_encoder(state, new_connector_state, new_encoder);
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n", DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
connector->base.id, connector->base.id,
connector->name, connector->name,
new_encoder->base.id, new_encoder->base.id,
new_encoder->name, new_encoder->name,
connector_state->crtc->base.id, new_connector_state->crtc->base.id,
connector_state->crtc->name); new_connector_state->crtc->name);
return 0; return 0;
} }
steal_encoder(state, new_encoder); steal_encoder(state, new_encoder);
set_best_encoder(state, connector_state, new_encoder); set_best_encoder(state, new_connector_state, new_encoder);
crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc); crtc_state = drm_atomic_get_existing_crtc_state(state, new_connector_state->crtc);
crtc_state->connectors_changed = true; crtc_state->connectors_changed = true;
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n", DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
...@@ -356,8 +358,8 @@ update_connector_routing(struct drm_atomic_state *state, ...@@ -356,8 +358,8 @@ update_connector_routing(struct drm_atomic_state *state,
connector->name, connector->name,
new_encoder->base.id, new_encoder->base.id,
new_encoder->name, new_encoder->name,
connector_state->crtc->base.id, new_connector_state->crtc->base.id,
connector_state->crtc->name); new_connector_state->crtc->name);
return 0; return 0;
} }
...@@ -366,57 +368,57 @@ static int ...@@ -366,57 +368,57 @@ static int
mode_fixup(struct drm_atomic_state *state) mode_fixup(struct drm_atomic_state *state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *conn_state; struct drm_connector_state *new_conn_state;
int i; int i;
int ret; int ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
if (!crtc_state->mode_changed && if (!new_crtc_state->mode_changed &&
!crtc_state->connectors_changed) !new_crtc_state->connectors_changed)
continue; continue;
drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode); drm_mode_copy(&new_crtc_state->adjusted_mode, &new_crtc_state->mode);
} }
for_each_connector_in_state(state, connector, conn_state, i) { for_each_new_connector_in_state(state, connector, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs; const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc); WARN_ON(!!new_conn_state->best_encoder != !!new_conn_state->crtc);
if (!conn_state->crtc || !conn_state->best_encoder) if (!new_conn_state->crtc || !new_conn_state->best_encoder)
continue; continue;
crtc_state = drm_atomic_get_existing_crtc_state(state, new_crtc_state =
conn_state->crtc); drm_atomic_get_existing_crtc_state(state, new_conn_state->crtc);
/* /*
* Each encoder has at most one connector (since we always steal * Each encoder has at most one connector (since we always steal
* it away), so we won't call ->mode_fixup twice. * it away), so we won't call ->mode_fixup twice.
*/ */
encoder = conn_state->best_encoder; encoder = new_conn_state->best_encoder;
funcs = encoder->helper_private; funcs = encoder->helper_private;
ret = drm_bridge_mode_fixup(encoder->bridge, &crtc_state->mode, ret = drm_bridge_mode_fixup(encoder->bridge, &new_crtc_state->mode,
&crtc_state->adjusted_mode); &new_crtc_state->adjusted_mode);
if (!ret) { if (!ret) {
DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
return -EINVAL; return -EINVAL;
} }
if (funcs && funcs->atomic_check) { if (funcs && funcs->atomic_check) {
ret = funcs->atomic_check(encoder, crtc_state, ret = funcs->atomic_check(encoder, new_crtc_state,
conn_state); new_conn_state);
if (ret) { if (ret) {
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n", DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n",
encoder->base.id, encoder->name); encoder->base.id, encoder->name);
return ret; return ret;
} }
} else if (funcs && funcs->mode_fixup) { } else if (funcs && funcs->mode_fixup) {
ret = funcs->mode_fixup(encoder, &crtc_state->mode, ret = funcs->mode_fixup(encoder, &new_crtc_state->mode,
&crtc_state->adjusted_mode); &new_crtc_state->adjusted_mode);
if (!ret) { if (!ret) {
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n", DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n",
encoder->base.id, encoder->name); encoder->base.id, encoder->name);
...@@ -425,22 +427,22 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -425,22 +427,22 @@ mode_fixup(struct drm_atomic_state *state)
} }
} }
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
if (!crtc_state->enable) if (!new_crtc_state->enable)
continue; continue;
if (!crtc_state->mode_changed && if (!new_crtc_state->mode_changed &&
!crtc_state->connectors_changed) !new_crtc_state->connectors_changed)
continue; continue;
funcs = crtc->helper_private; funcs = crtc->helper_private;
if (!funcs->mode_fixup) if (!funcs->mode_fixup)
continue; continue;
ret = funcs->mode_fixup(crtc, &crtc_state->mode, ret = funcs->mode_fixup(crtc, &new_crtc_state->mode,
&crtc_state->adjusted_mode); &new_crtc_state->adjusted_mode);
if (!ret) { if (!ret) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -487,19 +489,19 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -487,19 +489,19 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *connector_state; struct drm_connector_state *old_connector_state, *new_connector_state;
int i, ret; int i, ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) { if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
crtc_state->mode_changed = true; new_crtc_state->mode_changed = true;
} }
if (crtc->state->enable != crtc_state->enable) { if (old_crtc_state->enable != new_crtc_state->enable) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -511,8 +513,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -511,8 +513,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
* The other way around is true as well. enable != 0 * The other way around is true as well. enable != 0
* iff connectors are attached and a mode is set. * iff connectors are attached and a mode is set.
*/ */
crtc_state->mode_changed = true; new_crtc_state->mode_changed = true;
crtc_state->connectors_changed = true; new_crtc_state->connectors_changed = true;
} }
} }
...@@ -520,22 +522,23 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -520,22 +522,23 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (ret) if (ret)
return ret; return ret;
for_each_connector_in_state(state, connector, connector_state, i) { for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
/* /*
* This only sets crtc->connectors_changed for routing changes, * This only sets crtc->connectors_changed for routing changes,
* drivers must set crtc->connectors_changed themselves when * drivers must set crtc->connectors_changed themselves when
* connector properties need to be updated. * connector properties need to be updated.
*/ */
ret = update_connector_routing(state, connector, ret = update_connector_routing(state, connector,
connector_state); old_connector_state,
new_connector_state);
if (ret) if (ret)
return ret; return ret;
if (connector->state->crtc) { if (old_connector_state->crtc) {
crtc_state = drm_atomic_get_existing_crtc_state(state, new_crtc_state = drm_atomic_get_existing_crtc_state(state,
connector->state->crtc); old_connector_state->crtc);
if (connector->state->link_status != if (old_connector_state->link_status !=
connector_state->link_status) new_connector_state->link_status)
crtc_state->connectors_changed = true; new_crtc_state->connectors_changed = true;
} }
} }
...@@ -545,28 +548,28 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -545,28 +548,28 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
* configuration. This must be done before calling mode_fixup in case a * configuration. This must be done before calling mode_fixup in case a
* crtc only changed its mode but has the same set of connectors. * crtc only changed its mode but has the same set of connectors.
*/ */
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
bool has_connectors = bool has_connectors =
!!crtc_state->connector_mask; !!new_crtc_state->connector_mask;
/* /*
* We must set ->active_changed after walking connectors for * We must set ->active_changed after walking connectors for
* otherwise an update that only changes active would result in * otherwise an update that only changes active would result in
* a full modeset because update_connector_routing force that. * a full modeset because update_connector_routing force that.
*/ */
if (crtc->state->active != crtc_state->active) { if (old_crtc_state->active != new_crtc_state->active) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
crtc_state->active_changed = true; new_crtc_state->active_changed = true;
} }
if (!drm_atomic_crtc_needs_modeset(crtc_state)) if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
continue; continue;
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n",
crtc->base.id, crtc->name, crtc->base.id, crtc->name,
crtc_state->enable ? 'y' : 'n', new_crtc_state->enable ? 'y' : 'n',
crtc_state->active ? 'y' : 'n'); new_crtc_state->active ? 'y' : 'n');
ret = drm_atomic_add_affected_connectors(state, crtc); ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret != 0) if (ret != 0)
...@@ -576,7 +579,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -576,7 +579,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (ret != 0) if (ret != 0)
return ret; return ret;
if (crtc_state->enable != has_connectors) { if (new_crtc_state->enable != has_connectors) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -609,22 +612,22 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -609,22 +612,22 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *new_plane_state, *old_plane_state;
int i, ret = 0; int i, ret = 0;
for_each_plane_in_state(state, plane, plane_state, i) { for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
funcs = plane->helper_private; funcs = plane->helper_private;
drm_atomic_helper_plane_changed(state, plane_state, plane); drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane);
if (!funcs || !funcs->atomic_check) if (!funcs || !funcs->atomic_check)
continue; continue;
ret = funcs->atomic_check(plane, plane_state); ret = funcs->atomic_check(plane, new_plane_state);
if (ret) { if (ret) {
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n", DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n",
plane->base.id, plane->name); plane->base.id, plane->name);
...@@ -632,7 +635,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -632,7 +635,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
} }
} }
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
funcs = crtc->helper_private; funcs = crtc->helper_private;
...@@ -640,7 +643,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -640,7 +643,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
if (!funcs || !funcs->atomic_check) if (!funcs || !funcs->atomic_check)
continue; continue;
ret = funcs->atomic_check(crtc, crtc_state); ret = funcs->atomic_check(crtc, new_crtc_state);
if (ret) { if (ret) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -694,12 +697,12 @@ static void ...@@ -694,12 +697,12 @@ static void
disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
{ {
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *old_conn_state; struct drm_connector_state *old_conn_state, *new_conn_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
int i; int i;
for_each_connector_in_state(old_state, connector, old_conn_state, i) { for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs; const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -736,7 +739,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -736,7 +739,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
/* Right function depends upon target state. */ /* Right function depends upon target state. */
if (funcs) { if (funcs) {
if (connector->state->crtc && funcs->prepare) if (new_conn_state->crtc && funcs->prepare)
funcs->prepare(encoder); funcs->prepare(encoder);
else if (funcs->disable) else if (funcs->disable)
funcs->disable(encoder); funcs->disable(encoder);
...@@ -747,11 +750,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -747,11 +750,11 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
drm_bridge_post_disable(encoder->bridge); drm_bridge_post_disable(encoder->bridge);
} }
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
/* Shut down everything that needs a full modeset. */ /* Shut down everything that needs a full modeset. */
if (!drm_atomic_crtc_needs_modeset(crtc->state)) if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
continue; continue;
if (!old_crtc_state->active) if (!old_crtc_state->active)
...@@ -764,7 +767,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -764,7 +767,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
/* Right function depends upon target state. */ /* Right function depends upon target state. */
if (crtc->state->enable && funcs->prepare) if (new_crtc_state->enable && funcs->prepare)
funcs->prepare(crtc); funcs->prepare(crtc);
else if (funcs->atomic_disable) else if (funcs->atomic_disable)
funcs->atomic_disable(crtc, old_crtc_state); funcs->atomic_disable(crtc, old_crtc_state);
...@@ -793,13 +796,13 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, ...@@ -793,13 +796,13 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *old_conn_state; struct drm_connector_state *old_conn_state, *new_conn_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state;
int i; int i;
/* clear out existing links and update dpms */ /* clear out existing links and update dpms */
for_each_connector_in_state(old_state, connector, old_conn_state, i) { for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
if (connector->encoder) { if (connector->encoder) {
WARN_ON(!connector->encoder->crtc); WARN_ON(!connector->encoder->crtc);
...@@ -807,7 +810,7 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, ...@@ -807,7 +810,7 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
connector->encoder = NULL; connector->encoder = NULL;
} }
crtc = connector->state->crtc; crtc = new_conn_state->crtc;
if ((!crtc && old_conn_state->crtc) || if ((!crtc && old_conn_state->crtc) ||
(crtc && drm_atomic_crtc_needs_modeset(crtc->state))) { (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
struct drm_property *dpms_prop = struct drm_property *dpms_prop =
...@@ -824,23 +827,23 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, ...@@ -824,23 +827,23 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
} }
/* set new links */ /* set new links */
for_each_connector_in_state(old_state, connector, old_conn_state, i) { for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
if (!connector->state->crtc) if (!new_conn_state->crtc)
continue; continue;
if (WARN_ON(!connector->state->best_encoder)) if (WARN_ON(!new_conn_state->best_encoder))
continue; continue;
connector->encoder = connector->state->best_encoder; connector->encoder = new_conn_state->best_encoder;
connector->encoder->crtc = connector->state->crtc; connector->encoder->crtc = new_conn_state->crtc;
} }
/* set legacy state in the crtc structure */ /* set legacy state in the crtc structure */
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
struct drm_plane *primary = crtc->primary; struct drm_plane *primary = crtc->primary;
crtc->mode = crtc->state->mode; crtc->mode = new_crtc_state->mode;
crtc->enabled = crtc->state->enable; crtc->enabled = new_crtc_state->enable;
if (drm_atomic_get_existing_plane_state(old_state, primary) && if (drm_atomic_get_existing_plane_state(old_state, primary) &&
primary->state->crtc == crtc) { primary->state->crtc == crtc) {
...@@ -848,9 +851,9 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev, ...@@ -848,9 +851,9 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
crtc->y = primary->state->src_y >> 16; crtc->y = primary->state->src_y >> 16;
} }
if (crtc->state->enable) if (new_crtc_state->enable)
drm_calc_timestamping_constants(crtc, drm_calc_timestamping_constants(crtc,
&crtc->state->adjusted_mode); &new_crtc_state->adjusted_mode);
} }
} }
EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state); EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
...@@ -859,20 +862,20 @@ static void ...@@ -859,20 +862,20 @@ static void
crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state;
int i; int i;
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
if (!crtc->state->mode_changed) if (!new_crtc_state->mode_changed)
continue; continue;
funcs = crtc->helper_private; funcs = crtc->helper_private;
if (crtc->state->enable && funcs->mode_set_nofb) { if (new_crtc_state->enable && funcs->mode_set_nofb) {
DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n", DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -880,18 +883,17 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -880,18 +883,17 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
} }
} }
for_each_connector_in_state(old_state, connector, old_conn_state, i) { for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs; const struct drm_encoder_helper_funcs *funcs;
struct drm_crtc_state *new_crtc_state;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_display_mode *mode, *adjusted_mode; struct drm_display_mode *mode, *adjusted_mode;
if (!connector->state->best_encoder) if (!new_conn_state->best_encoder)
continue; continue;
encoder = connector->state->best_encoder; encoder = new_conn_state->best_encoder;
funcs = encoder->helper_private; funcs = encoder->helper_private;
new_crtc_state = connector->state->crtc->state; new_crtc_state = new_conn_state->crtc->state;
mode = &new_crtc_state->mode; mode = &new_crtc_state->mode;
adjusted_mode = &new_crtc_state->adjusted_mode; adjusted_mode = &new_crtc_state->adjusted_mode;
...@@ -907,7 +909,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state) ...@@ -907,7 +909,7 @@ crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
*/ */
if (funcs && funcs->atomic_mode_set) { if (funcs && funcs->atomic_mode_set) {
funcs->atomic_mode_set(encoder, new_crtc_state, funcs->atomic_mode_set(encoder, new_crtc_state,
connector->state); new_conn_state);
} else if (funcs && funcs->mode_set) { } else if (funcs && funcs->mode_set) {
funcs->mode_set(encoder, mode, adjusted_mode); funcs->mode_set(encoder, mode, adjusted_mode);
} }
...@@ -959,24 +961,24 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -959,24 +961,24 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state;
int i; int i;
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
/* Need to filter out CRTCs where only planes change. */ /* Need to filter out CRTCs where only planes change. */
if (!drm_atomic_crtc_needs_modeset(crtc->state)) if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
continue; continue;
if (!crtc->state->active) if (!new_crtc_state->active)
continue; continue;
funcs = crtc->helper_private; funcs = crtc->helper_private;
if (crtc->state->enable) { if (new_crtc_state->enable) {
DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -987,18 +989,18 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, ...@@ -987,18 +989,18 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
} }
} }
for_each_connector_in_state(old_state, connector, old_conn_state, i) { for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
const struct drm_encoder_helper_funcs *funcs; const struct drm_encoder_helper_funcs *funcs;
struct drm_encoder *encoder; struct drm_encoder *encoder;
if (!connector->state->best_encoder) if (!new_conn_state->best_encoder)
continue; continue;
if (!connector->state->crtc->state->active || if (!new_conn_state->crtc->state->active ||
!drm_atomic_crtc_needs_modeset(connector->state->crtc->state)) !drm_atomic_crtc_needs_modeset(new_conn_state->crtc->state))
continue; continue;
encoder = connector->state->best_encoder; encoder = new_conn_state->best_encoder;
funcs = encoder->helper_private; funcs = encoder->helper_private;
DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n", DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
...@@ -1048,29 +1050,26 @@ int drm_atomic_helper_wait_for_fences(struct drm_device *dev, ...@@ -1048,29 +1050,26 @@ int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
bool pre_swap) bool pre_swap)
{ {
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *new_plane_state;
int i, ret; int i, ret;
for_each_plane_in_state(state, plane, plane_state, i) { for_each_new_plane_in_state(state, plane, new_plane_state, i) {
if (!pre_swap) if (!new_plane_state->fence)
plane_state = plane->state;
if (!plane_state->fence)
continue; continue;
WARN_ON(!plane_state->fb); WARN_ON(!new_plane_state->fb);
/* /*
* If waiting for fences pre-swap (ie: nonblock), userspace can * If waiting for fences pre-swap (ie: nonblock), userspace can
* still interrupt the operation. Instead of blocking until the * still interrupt the operation. Instead of blocking until the
* timer expires, make the wait interruptible. * timer expires, make the wait interruptible.
*/ */
ret = dma_fence_wait(plane_state->fence, pre_swap); ret = dma_fence_wait(new_plane_state->fence, pre_swap);
if (ret) if (ret)
return ret; return ret;
dma_fence_put(plane_state->fence); dma_fence_put(new_plane_state->fence);
plane_state->fence = NULL; new_plane_state->fence = NULL;
} }
return 0; return 0;
...@@ -1093,7 +1092,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, ...@@ -1093,7 +1092,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
int i, ret; int i, ret;
unsigned crtc_mask = 0; unsigned crtc_mask = 0;
...@@ -1104,9 +1103,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, ...@@ -1104,9 +1103,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
if (old_state->legacy_cursor_update) if (old_state->legacy_cursor_update)
return; return;
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
struct drm_crtc_state *new_crtc_state = crtc->state;
if (!new_crtc_state->active || !new_crtc_state->planes_changed) if (!new_crtc_state->active || !new_crtc_state->planes_changed)
continue; continue;
...@@ -1118,7 +1115,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, ...@@ -1118,7 +1115,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
old_state->crtcs[i].last_vblank_count = drm_crtc_vblank_count(crtc); old_state->crtcs[i].last_vblank_count = drm_crtc_vblank_count(crtc);
} }
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
if (!(crtc_mask & drm_crtc_mask(crtc))) if (!(crtc_mask & drm_crtc_mask(crtc)))
continue; continue;
...@@ -1427,11 +1424,11 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, ...@@ -1427,11 +1424,11 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
bool nonblock) bool nonblock)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_crtc_commit *commit; struct drm_crtc_commit *commit;
int i, ret; int i, ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
commit = kzalloc(sizeof(*commit), GFP_KERNEL); commit = kzalloc(sizeof(*commit), GFP_KERNEL);
if (!commit) if (!commit)
return -ENOMEM; return -ENOMEM;
...@@ -1452,7 +1449,7 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, ...@@ -1452,7 +1449,7 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
/* Drivers only send out events when at least either current or /* Drivers only send out events when at least either current or
* new CRTC state is active. Complete right away if everything * new CRTC state is active. Complete right away if everything
* stays off. */ * stays off. */
if (!crtc->state->active && !crtc_state->active) { if (!old_crtc_state->active && !new_crtc_state->active) {
complete_all(&commit->flip_done); complete_all(&commit->flip_done);
continue; continue;
} }
...@@ -1463,17 +1460,17 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, ...@@ -1463,17 +1460,17 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
continue; continue;
} }
if (!crtc_state->event) { if (!new_crtc_state->event) {
commit->event = kzalloc(sizeof(*commit->event), commit->event = kzalloc(sizeof(*commit->event),
GFP_KERNEL); GFP_KERNEL);
if (!commit->event) if (!commit->event)
return -ENOMEM; return -ENOMEM;
crtc_state->event = commit->event; new_crtc_state->event = commit->event;
} }
crtc_state->event->base.completion = &commit->flip_done; new_crtc_state->event->base.completion = &commit->flip_done;
crtc_state->event->base.completion_release = release_crtc_commit; new_crtc_state->event->base.completion_release = release_crtc_commit;
drm_crtc_commit_get(commit); drm_crtc_commit_get(commit);
} }
...@@ -1512,12 +1509,12 @@ static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc) ...@@ -1512,12 +1509,12 @@ static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state) void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_crtc_commit *commit; struct drm_crtc_commit *commit;
int i; int i;
long ret; long ret;
for_each_crtc_in_state(old_state, crtc, crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
spin_lock(&crtc->commit_lock); spin_lock(&crtc->commit_lock);
commit = preceeding_commit(crtc); commit = preceeding_commit(crtc);
if (commit) if (commit)
...@@ -1564,17 +1561,17 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies); ...@@ -1564,17 +1561,17 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state) void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_crtc_commit *commit; struct drm_crtc_commit *commit;
int i; int i;
for_each_crtc_in_state(old_state, crtc, crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
commit = old_state->crtcs[i].commit; commit = old_state->crtcs[i].commit;
if (!commit) if (!commit)
continue; continue;
/* backend must have consumed any event by now */ /* backend must have consumed any event by now */
WARN_ON(crtc->state->event); WARN_ON(new_crtc_state->event);
spin_lock(&crtc->commit_lock); spin_lock(&crtc->commit_lock);
complete_all(&commit->hw_done); complete_all(&commit->hw_done);
spin_unlock(&crtc->commit_lock); spin_unlock(&crtc->commit_lock);
...@@ -1596,12 +1593,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done); ...@@ -1596,12 +1593,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state) void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_crtc_commit *commit; struct drm_crtc_commit *commit;
int i; int i;
long ret; long ret;
for_each_crtc_in_state(old_state, crtc, crtc_state, i) { for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
commit = old_state->crtcs[i].commit; commit = old_state->crtcs[i].commit;
if (WARN_ON(!commit)) if (WARN_ON(!commit))
continue; continue;
...@@ -1652,16 +1649,16 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, ...@@ -1652,16 +1649,16 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *new_plane_state;
int ret, i, j; int ret, i, j;
for_each_plane_in_state(state, plane, plane_state, i) { for_each_new_plane_in_state(state, plane, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
funcs = plane->helper_private; funcs = plane->helper_private;
if (funcs->prepare_fb) { if (funcs->prepare_fb) {
ret = funcs->prepare_fb(plane, plane_state); ret = funcs->prepare_fb(plane, new_plane_state);
if (ret) if (ret)
goto fail; goto fail;
} }
...@@ -1670,7 +1667,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, ...@@ -1670,7 +1667,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
return 0; return 0;
fail: fail:
for_each_plane_in_state(state, plane, plane_state, j) { for_each_new_plane_in_state(state, plane, new_plane_state, j) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
if (j >= i) if (j >= i)
...@@ -1679,7 +1676,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev, ...@@ -1679,7 +1676,7 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
funcs = plane->helper_private; funcs = plane->helper_private;
if (funcs->cleanup_fb) if (funcs->cleanup_fb)
funcs->cleanup_fb(plane, plane_state); funcs->cleanup_fb(plane, new_plane_state);
} }
return ret; return ret;
...@@ -1737,14 +1734,14 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1737,14 +1734,14 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
uint32_t flags) uint32_t flags)
{ {
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state; struct drm_plane_state *old_plane_state, *new_plane_state;
int i; int i;
bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY; bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET; bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
funcs = crtc->helper_private; funcs = crtc->helper_private;
...@@ -1752,13 +1749,13 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1752,13 +1749,13 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (!funcs || !funcs->atomic_begin) if (!funcs || !funcs->atomic_begin)
continue; continue;
if (active_only && !crtc->state->active) if (active_only && !new_crtc_state->active)
continue; continue;
funcs->atomic_begin(crtc, old_crtc_state); funcs->atomic_begin(crtc, old_crtc_state);
} }
for_each_plane_in_state(old_state, plane, old_plane_state, i) { for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
bool disabling; bool disabling;
...@@ -1777,7 +1774,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1777,7 +1774,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
* CRTC to avoid skipping planes being disabled on an * CRTC to avoid skipping planes being disabled on an
* active CRTC. * active CRTC.
*/ */
if (!disabling && !plane_crtc_active(plane->state)) if (!disabling && !plane_crtc_active(new_plane_state))
continue; continue;
if (disabling && !plane_crtc_active(old_plane_state)) if (disabling && !plane_crtc_active(old_plane_state))
continue; continue;
...@@ -1796,12 +1793,12 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1796,12 +1793,12 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
continue; continue;
funcs->atomic_disable(plane, old_plane_state); funcs->atomic_disable(plane, old_plane_state);
} else if (plane->state->crtc || disabling) { } else if (new_plane_state->crtc || disabling) {
funcs->atomic_update(plane, old_plane_state); funcs->atomic_update(plane, old_plane_state);
} }
} }
for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
funcs = crtc->helper_private; funcs = crtc->helper_private;
...@@ -1809,7 +1806,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, ...@@ -1809,7 +1806,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
if (!funcs || !funcs->atomic_flush) if (!funcs || !funcs->atomic_flush)
continue; continue;
if (active_only && !crtc->state->active) if (active_only && !new_crtc_state->active)
continue; continue;
funcs->atomic_flush(crtc, old_crtc_state); funcs->atomic_flush(crtc, old_crtc_state);
...@@ -1936,11 +1933,21 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev, ...@@ -1936,11 +1933,21 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *old_plane_state, *new_plane_state;
int i; int i;
for_each_plane_in_state(old_state, plane, plane_state, i) { for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
struct drm_plane_state *plane_state;
/*
* This might be called before swapping when commit is aborted,
* in which case we have to cleanup the new state.
*/
if (old_plane_state == plane->state)
plane_state = new_plane_state;
else
plane_state = old_plane_state;
funcs = plane->helper_private; funcs = plane->helper_private;
...@@ -1986,15 +1993,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state, ...@@ -1986,15 +1993,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
int i; int i;
long ret; long ret;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *conn_state, *old_conn_state; struct drm_connector_state *old_conn_state, *new_conn_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state, *old_crtc_state; struct drm_crtc_state *old_crtc_state, *new_crtc_state;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state, *old_plane_state; struct drm_plane_state *old_plane_state, *new_plane_state;
struct drm_crtc_commit *commit; struct drm_crtc_commit *commit;
if (stall) { if (stall) {
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
spin_lock(&crtc->commit_lock); spin_lock(&crtc->commit_lock);
commit = list_first_entry_or_null(&crtc->commit_list, commit = list_first_entry_or_null(&crtc->commit_list,
struct drm_crtc_commit, commit_entry); struct drm_crtc_commit, commit_entry);
...@@ -2014,20 +2021,24 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state, ...@@ -2014,20 +2021,24 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
} }
} }
for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) { for_each_oldnew_connector_in_state(state, connector, old_conn_state, new_conn_state, i) {
WARN_ON(connector->state != old_conn_state); WARN_ON(connector->state != old_conn_state);
connector->state->state = state; old_conn_state->state = state;
swap(state->connectors[i].state, connector->state); new_conn_state->state = NULL;
connector->state->state = NULL;
state->connectors[i].state = old_conn_state;
connector->state = new_conn_state;
} }
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, crtc_state, i) { for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
WARN_ON(crtc->state != old_crtc_state); WARN_ON(crtc->state != old_crtc_state);
crtc->state->state = state; old_crtc_state->state = state;
swap(state->crtcs[i].state, crtc->state); new_crtc_state->state = NULL;
crtc->state->state = NULL;
state->crtcs[i].state = old_crtc_state;
crtc->state = new_crtc_state;
if (state->crtcs[i].commit) { if (state->crtcs[i].commit) {
spin_lock(&crtc->commit_lock); spin_lock(&crtc->commit_lock);
...@@ -2039,12 +2050,14 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state, ...@@ -2039,12 +2050,14 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
} }
} }
for_each_oldnew_plane_in_state(state, plane, old_plane_state, plane_state, i) { for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
WARN_ON(plane->state != old_plane_state); WARN_ON(plane->state != old_plane_state);
plane->state->state = state; old_plane_state->state = state;
swap(state->planes[i].state, plane->state); new_plane_state->state = NULL;
plane->state->state = NULL;
state->planes[i].state = old_plane_state;
plane->state = new_plane_state;
} }
} }
EXPORT_SYMBOL(drm_atomic_helper_swap_state); EXPORT_SYMBOL(drm_atomic_helper_swap_state);
...@@ -2227,9 +2240,9 @@ static int update_output_state(struct drm_atomic_state *state, ...@@ -2227,9 +2240,9 @@ static int update_output_state(struct drm_atomic_state *state,
{ {
struct drm_device *dev = set->crtc->dev; struct drm_device *dev = set->crtc->dev;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *conn_state; struct drm_connector_state *new_conn_state;
int ret, i; int ret, i;
ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
...@@ -2242,31 +2255,32 @@ static int update_output_state(struct drm_atomic_state *state, ...@@ -2242,31 +2255,32 @@ static int update_output_state(struct drm_atomic_state *state,
if (ret) if (ret)
return ret; return ret;
for_each_connector_in_state(state, connector, conn_state, i) { for_each_new_connector_in_state(state, connector, new_conn_state, i) {
if (conn_state->crtc == set->crtc) { if (new_conn_state->crtc == set->crtc) {
ret = drm_atomic_set_crtc_for_connector(conn_state, ret = drm_atomic_set_crtc_for_connector(new_conn_state,
NULL); NULL);
if (ret) if (ret)
return ret; return ret;
/* Make sure legacy setCrtc always re-trains */ /* Make sure legacy setCrtc always re-trains */
conn_state->link_status = DRM_LINK_STATUS_GOOD; new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
} }
} }
/* Then set all connectors from set->connectors on the target crtc */ /* Then set all connectors from set->connectors on the target crtc */
for (i = 0; i < set->num_connectors; i++) { for (i = 0; i < set->num_connectors; i++) {
conn_state = drm_atomic_get_connector_state(state, new_conn_state = drm_atomic_get_connector_state(state,
set->connectors[i]); set->connectors[i]);
if (IS_ERR(conn_state)) if (IS_ERR(new_conn_state))
return PTR_ERR(conn_state); return PTR_ERR(new_conn_state);
ret = drm_atomic_set_crtc_for_connector(conn_state, ret = drm_atomic_set_crtc_for_connector(new_conn_state,
set->crtc); set->crtc);
if (ret) if (ret)
return ret; return ret;
} }
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
/* Don't update ->enable for the CRTC in the set_config request, /* Don't update ->enable for the CRTC in the set_config request,
* since a mismatch would indicate a bug in the upper layers. * since a mismatch would indicate a bug in the upper layers.
* The actual modeset code later on will catch any * The actual modeset code later on will catch any
...@@ -2274,13 +2288,13 @@ static int update_output_state(struct drm_atomic_state *state, ...@@ -2274,13 +2288,13 @@ static int update_output_state(struct drm_atomic_state *state,
if (crtc == set->crtc) if (crtc == set->crtc)
continue; continue;
if (!crtc_state->connector_mask) { if (!new_crtc_state->connector_mask) {
ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
NULL); NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
crtc_state->active = false; new_crtc_state->active = false;
} }
} }
...@@ -2583,21 +2597,21 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, ...@@ -2583,21 +2597,21 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
{ {
int i; int i;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *plane_state; struct drm_plane_state *new_plane_state;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_state *conn_state; struct drm_connector_state *new_conn_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state; struct drm_crtc_state *new_crtc_state;
state->acquire_ctx = ctx; state->acquire_ctx = ctx;
for_each_new_plane_in_state(state, plane, plane_state, i) for_each_new_plane_in_state(state, plane, new_plane_state, i)
state->planes[i].old_state = plane->state; state->planes[i].old_state = plane->state;
for_each_new_crtc_in_state(state, crtc, crtc_state, i) for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
state->crtcs[i].old_state = crtc->state; state->crtcs[i].old_state = crtc->state;
for_each_new_connector_in_state(state, connector, conn_state, i) for_each_new_connector_in_state(state, connector, new_conn_state, i)
state->connectors[i].old_state = connector->state; state->connectors[i].old_state = connector->state;
return drm_atomic_commit(state); return drm_atomic_commit(state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment