Commit fc596660 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter

drm/atomic: add connectors_changed to separate it from mode_changed, v2

This can be a separate case from mode_changed, when connectors stay the
same but only the mode is different. Drivers may choose to implement specific
optimizations to prevent a full modeset for this case.

Changes since v1:
- Update kerneldocs slightly.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarAnder Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 90a21700
...@@ -124,7 +124,7 @@ steal_encoder(struct drm_atomic_state *state, ...@@ -124,7 +124,7 @@ steal_encoder(struct drm_atomic_state *state,
if (IS_ERR(crtc_state)) if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state); return PTR_ERR(crtc_state);
crtc_state->mode_changed = true; crtc_state->connectors_changed = true;
list_for_each_entry(connector, &config->connector_list, head) { list_for_each_entry(connector, &config->connector_list, head) {
if (connector->state->best_encoder != encoder) if (connector->state->best_encoder != encoder)
...@@ -174,14 +174,14 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) ...@@ -174,14 +174,14 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
idx = drm_crtc_index(connector->state->crtc); idx = drm_crtc_index(connector->state->crtc);
crtc_state = state->crtc_states[idx]; crtc_state = state->crtc_states[idx];
crtc_state->mode_changed = true; crtc_state->connectors_changed = true;
} }
if (connector_state->crtc) { if (connector_state->crtc) {
idx = drm_crtc_index(connector_state->crtc); idx = drm_crtc_index(connector_state->crtc);
crtc_state = state->crtc_states[idx]; crtc_state = state->crtc_states[idx];
crtc_state->mode_changed = true; crtc_state->connectors_changed = true;
} }
} }
...@@ -233,7 +233,7 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx) ...@@ -233,7 +233,7 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
idx = drm_crtc_index(connector_state->crtc); idx = drm_crtc_index(connector_state->crtc);
crtc_state = state->crtc_states[idx]; crtc_state = state->crtc_states[idx];
crtc_state->mode_changed = true; crtc_state->connectors_changed = true;
DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n", DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n",
connector->base.id, connector->base.id,
...@@ -256,7 +256,8 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -256,7 +256,8 @@ mode_fixup(struct drm_atomic_state *state)
bool ret; bool ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_crtc_in_state(state, crtc, crtc_state, i) {
if (!crtc_state->mode_changed) if (!crtc_state->mode_changed &&
!crtc_state->connectors_changed)
continue; continue;
drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode); drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
...@@ -312,7 +313,8 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -312,7 +313,8 @@ mode_fixup(struct drm_atomic_state *state)
for_each_crtc_in_state(state, crtc, crtc_state, i) { for_each_crtc_in_state(state, crtc, crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs; const struct drm_crtc_helper_funcs *funcs;
if (!crtc_state->mode_changed) if (!crtc_state->mode_changed &&
!crtc_state->connectors_changed)
continue; continue;
funcs = crtc->helper_private; funcs = crtc->helper_private;
...@@ -338,9 +340,14 @@ mode_fixup(struct drm_atomic_state *state) ...@@ -338,9 +340,14 @@ mode_fixup(struct drm_atomic_state *state)
* *
* Check the state object to see if the requested state is physically possible. * Check the state object to see if the requested state is physically possible.
* This does all the crtc and connector related computations for an atomic * This does all the crtc and connector related computations for an atomic
* update. It computes and updates crtc_state->mode_changed, adds any additional * update and adds any additional connectors needed for full modesets and calls
* connectors needed for full modesets and calls down into ->mode_fixup * down into ->mode_fixup functions of the driver backend.
* functions of the driver backend. *
* crtc_state->mode_changed is set when the input mode is changed.
* crtc_state->connectors_changed is set when a connector is added or
* removed from the crtc.
* crtc_state->active_changed is set when crtc_state->active changes,
* which is used for dpms.
* *
* IMPORTANT: * IMPORTANT:
* *
...@@ -373,7 +380,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -373,7 +380,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (crtc->state->enable != crtc_state->enable) { if (crtc->state->enable != crtc_state->enable) {
DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n", DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
crtc->base.id); crtc->base.id);
/*
* For clarity this assignment is done here, but
* enable == 0 is only true when there are no
* connectors and a NULL mode.
*
* The other way around is true as well. enable != 0
* iff connectors are attached and a mode is set.
*/
crtc_state->mode_changed = true; crtc_state->mode_changed = true;
crtc_state->connectors_changed = true;
} }
} }
...@@ -448,6 +465,9 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset); ...@@ -448,6 +465,9 @@ EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
* This does all the plane update related checks using by calling into the * This does all the plane update related checks using by calling into the
* ->atomic_check hooks provided by the driver. * ->atomic_check hooks provided by the driver.
* *
* It also sets crtc_state->planes_changed to indicate that a crtc has
* updated planes.
*
* RETURNS * RETURNS
* Zero for success or -errno * Zero for success or -errno
*/ */
...@@ -2074,6 +2094,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, ...@@ -2074,6 +2094,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
state->mode_changed = false; state->mode_changed = false;
state->active_changed = false; state->active_changed = false;
state->planes_changed = false; state->planes_changed = false;
state->connectors_changed = false;
state->event = NULL; state->event = NULL;
} }
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
......
...@@ -413,7 +413,7 @@ static const intel_limit_t intel_limits_bxt = { ...@@ -413,7 +413,7 @@ static const intel_limit_t intel_limits_bxt = {
static bool static bool
needs_modeset(struct drm_crtc_state *state) needs_modeset(struct drm_crtc_state *state)
{ {
return state->mode_changed || state->active_changed; return drm_atomic_crtc_needs_modeset(state);
} }
/** /**
......
...@@ -166,7 +166,8 @@ int __must_check drm_atomic_async_commit(struct drm_atomic_state *state); ...@@ -166,7 +166,8 @@ int __must_check drm_atomic_async_commit(struct drm_atomic_state *state);
static inline bool static inline bool
drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state) drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
{ {
return state->mode_changed || state->active_changed; return state->mode_changed || state->active_changed ||
state->connectors_changed;
} }
......
...@@ -255,12 +255,13 @@ struct drm_atomic_state; ...@@ -255,12 +255,13 @@ struct drm_atomic_state;
* @crtc: backpointer to the CRTC * @crtc: backpointer to the CRTC
* @enable: whether the CRTC should be enabled, gates all other state * @enable: whether the CRTC should be enabled, gates all other state
* @active: whether the CRTC is actively displaying (used for DPMS) * @active: whether the CRTC is actively displaying (used for DPMS)
* @mode_changed: for use by helpers and drivers when computing state updates * @planes_changed: planes on this crtc are updated
* @active_changed: for use by helpers and drivers when computing state updates * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
* @active_changed: crtc_state->active has been toggled.
* @connectors_changed: connectors to this crtc have been updated
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes * @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
* @last_vblank_count: for helpers and drivers to capture the vblank of the * @last_vblank_count: for helpers and drivers to capture the vblank of the
* update to ensure framebuffer cleanup isn't done too early * update to ensure framebuffer cleanup isn't done too early
* @planes_changed: for use by helpers and drivers when computing state updates
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
* @mode: current mode timings * @mode: current mode timings
* @event: optional pointer to a DRM event to signal upon completion of the * @event: optional pointer to a DRM event to signal upon completion of the
...@@ -283,6 +284,7 @@ struct drm_crtc_state { ...@@ -283,6 +284,7 @@ struct drm_crtc_state {
bool planes_changed : 1; bool planes_changed : 1;
bool mode_changed : 1; bool mode_changed : 1;
bool active_changed : 1; bool active_changed : 1;
bool connectors_changed : 1;
/* attached planes bitmask: /* attached planes bitmask:
* WARNING: transitional helpers do not maintain plane_mask so * WARNING: transitional helpers do not maintain plane_mask so
......
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