Skip to content

Commit

Permalink
drm/i915: Stage new modeset state straight into atomic state
Browse files Browse the repository at this point in the history
The logic that stages the state before the modeset was still updating
first the old staged config and then populating the atomic state based
on that. Change this to use only the atomic state.

Note that now the staged config is updated in the function
intel_modeset_commit_output_state(). This is done so that the modeset
check and the force restore path in the hw state read out code continue
to work.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Ander Conselvan de Oliveira authored and Daniel Vetter committed May 8, 2015
1 parent b788526 commit d5432a9
Showing 1 changed file with 85 additions and 85 deletions.
170 changes: 85 additions & 85 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -11152,27 +11152,47 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
* intel_modeset_commit_output_state
*
* This function copies the stage display pipe configuration to the real one.
*
* FIXME: we want to replace this with a proper state swap in the future
*/
static void intel_modeset_commit_output_state(struct drm_device *dev)
static void intel_modeset_commit_output_state(struct drm_atomic_state *state)
{
struct intel_crtc *crtc;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
struct intel_connector *connector;
struct intel_connector *intel_connector;
int i;

for_each_intel_connector(dev, connector) {
connector->base.encoder = &connector->new_encoder->base;
for_each_connector_in_state(state, connector, connector_state, i) {
*connector->state = *connector_state;

connector->encoder = connector_state->best_encoder;
if (connector->encoder)
connector->encoder->crtc = connector_state->crtc;
}

for_each_intel_encoder(dev, encoder) {
encoder->base.crtc = &encoder->new_crtc->base;
/* Update crtc of disabled encoders */
for_each_intel_encoder(state->dev, encoder) {
int num_connectors = 0;

for_each_intel_connector(state->dev, intel_connector)
if (intel_connector->base.encoder == &encoder->base)
num_connectors++;

if (num_connectors == 0)
encoder->base.crtc = NULL;
}

for_each_intel_crtc(dev, crtc) {
crtc->base.state->enable = crtc->new_enabled;
crtc->base.enabled = crtc->new_enabled;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
crtc->state->enable = crtc_state->enable;
crtc->enabled = crtc_state->enable;
}

intel_modeset_update_connector_atomic_state(dev);
/* Copy the new configuration to the staged state, to keep the few
* pieces of code that haven't been converted yet happy */
intel_modeset_update_staged_output_state(state->dev);
}

static void
Expand Down Expand Up @@ -11622,7 +11642,7 @@ intel_modeset_update_state(struct drm_atomic_state *state)
intel_encoder->connectors_active = false;
}

intel_modeset_commit_output_state(dev);
intel_modeset_commit_output_state(state);

/* Double check state. */
for_each_crtc(dev, crtc) {
Expand Down Expand Up @@ -12739,10 +12759,11 @@ intel_modeset_stage_output_state(struct drm_device *dev,
struct drm_atomic_state *state)
{
struct intel_connector *connector;
struct drm_connector *drm_connector;
struct drm_connector_state *connector_state;
struct intel_encoder *encoder;
struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int i, ret;

/* The upper layers ensure that we either disable a crtc or have a list
* of connectors. For paranoia, double-check this. */
Expand All @@ -12752,21 +12773,28 @@ intel_modeset_stage_output_state(struct drm_device *dev,
for_each_intel_connector(dev, connector) {
bool in_mode_set = intel_connector_in_mode_set(connector, set);

if (!in_mode_set && connector->base.state->crtc != set->crtc)
continue;

connector_state =
drm_atomic_get_connector_state(state, &connector->base);
if (IS_ERR(connector_state))
return PTR_ERR(connector_state);

if (in_mode_set) {
int pipe = to_intel_crtc(set->crtc)->pipe;
connector->new_encoder =
intel_find_encoder(connector, pipe);
connector_state->best_encoder =
&intel_find_encoder(connector, pipe)->base;
}

if (!connector->base.encoder ||
connector->base.encoder->crtc != set->crtc)
if (connector->base.state->crtc != set->crtc)
continue;

/* If we disable the crtc, disable all its connectors. Also, if
* the connector is on the changing crtc but not on the new
* connector list, disable it. */
if (!set->fb || !in_mode_set) {
connector->new_encoder = NULL;
connector_state->best_encoder = NULL;

DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
connector->base.base.id,
Expand All @@ -12775,86 +12803,58 @@ intel_modeset_stage_output_state(struct drm_device *dev,
}
/* connector->new_encoder is now updated for all connectors. */

/* Update crtc of enabled connectors. */
for_each_intel_connector(dev, connector) {
struct drm_crtc *new_crtc;
for_each_connector_in_state(state, drm_connector, connector_state, i) {
connector = to_intel_connector(drm_connector);

if (!connector_state->best_encoder) {
ret = drm_atomic_set_crtc_for_connector(connector_state,
NULL);
if (ret)
return ret;

if (!connector->new_encoder)
continue;
}

if (intel_connector_in_mode_set(connector, set))
new_crtc = set->crtc;
else
new_crtc = connector->new_encoder->base.crtc;
if (intel_connector_in_mode_set(connector, set)) {
struct drm_crtc *crtc = connector->base.state->crtc;

/* If this connector was in a previous crtc, add it
* to the state. We might need to disable it. */
if (crtc) {
crtc_state =
drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
}

ret = drm_atomic_set_crtc_for_connector(connector_state,
set->crtc);
if (ret)
return ret;
}

/* Make sure the new CRTC will work with the encoder */
if (!drm_encoder_crtc_ok(&connector->new_encoder->base,
new_crtc)) {
if (!drm_encoder_crtc_ok(connector_state->best_encoder,
connector_state->crtc)) {
return -EINVAL;
}
connector->new_encoder->new_crtc = to_intel_crtc(new_crtc);

connector_state =
drm_atomic_get_connector_state(state, &connector->base);
if (IS_ERR(connector_state))
return PTR_ERR(connector_state);

connector_state->crtc = new_crtc;
connector_state->best_encoder = &connector->new_encoder->base;

DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
connector->base.base.id,
connector->base.name,
new_crtc->base.id);
}

/* Check for any encoders that needs to be disabled. */
for_each_intel_encoder(dev, encoder) {
int num_connectors = 0;
for_each_intel_connector(dev, connector) {
if (connector->new_encoder == encoder) {
WARN_ON(!connector->new_encoder->new_crtc);
num_connectors++;
}
}

if (num_connectors == 0)
encoder->new_crtc = NULL;
else if (num_connectors > 1)
return -EINVAL;
}
/* Now we've also updated encoder->new_crtc for all encoders. */
for_each_intel_connector(dev, connector) {
connector_state =
drm_atomic_get_connector_state(state, &connector->base);
if (IS_ERR(connector_state))
return PTR_ERR(connector_state);
connector_state->crtc->base.id);

if (connector->new_encoder) {
if (connector->new_encoder != connector->encoder)
connector->encoder = connector->new_encoder;
} else {
connector_state->crtc = NULL;
connector_state->best_encoder = NULL;
}
if (connector_state->best_encoder != &connector->encoder->base)
connector->encoder =
to_intel_encoder(connector_state->best_encoder);
}
for_each_intel_crtc(dev, crtc) {
crtc->new_enabled = false;

for_each_intel_encoder(dev, encoder) {
if (encoder->new_crtc == crtc) {
crtc->new_enabled = true;
break;
}
}

if (crtc->new_enabled != crtc->base.state->enable) {
crtc_state = intel_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
for_each_crtc_in_state(state, crtc, crtc_state, i) {
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret)
return ret;

crtc_state->base.enable = crtc->new_enabled;
}
crtc_state->enable = drm_atomic_connectors_for_crtc(state, crtc);
}

return 0;
Expand Down

0 comments on commit d5432a9

Please sign in to comment.