* [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 8:59 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same Maarten Lankhorst
` (19 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
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.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 25 +++++++++++++++++++------
drivers/gpu/drm/i915/intel_display.c | 2 +-
include/drm/drm_atomic.h | 3 ++-
include/drm/drm_crtc.h | 8 +++++---
4 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 66e76f4f43be..b818e3111380 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -124,7 +124,7 @@ steal_encoder(struct drm_atomic_state *state,
if (IS_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) {
if (connector->state->best_encoder != encoder)
@@ -174,14 +174,14 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
idx = drm_crtc_index(connector->state->crtc);
crtc_state = state->crtc_states[idx];
- crtc_state->mode_changed = true;
+ crtc_state->connectors_changed = true;
}
if (connector_state->crtc) {
idx = drm_crtc_index(connector_state->crtc);
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)
idx = drm_crtc_index(connector_state->crtc);
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",
connector->base.id,
@@ -256,7 +256,8 @@ mode_fixup(struct drm_atomic_state *state)
bool ret;
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;
drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
@@ -312,7 +313,8 @@ mode_fixup(struct drm_atomic_state *state)
for_each_crtc_in_state(state, crtc, crtc_state, i) {
const struct drm_crtc_helper_funcs *funcs;
- if (!crtc_state->mode_changed)
+ if (!crtc_state->mode_changed &&
+ !crtc_state->connectors_changed)
continue;
funcs = crtc->helper_private;
@@ -373,7 +375,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
if (crtc->state->enable != crtc_state->enable) {
DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
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->connectors_changed = true;
}
}
@@ -2072,6 +2084,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
state->mode_changed = false;
state->active_changed = false;
state->planes_changed = false;
+ state->connectors_changed = false;
state->event = NULL;
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e91613b1c871..6ddb462b4124 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -421,7 +421,7 @@ static const intel_limit_t intel_limits_bxt = {
static bool
needs_modeset(struct drm_crtc_state *state)
{
- return state->mode_changed || state->active_changed;
+ return drm_atomic_crtc_needs_modeset(state);
}
/**
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8a3a913320eb..e67aeac2aee0 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -166,7 +166,8 @@ int __must_check drm_atomic_async_commit(struct drm_atomic_state *state);
static inline bool
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;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 57ca8cc383a6..e39d6f1de5f7 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -255,12 +255,13 @@ struct drm_atomic_state;
* @crtc: backpointer to the CRTC
* @enable: whether the CRTC should be enabled, gates all other state
* @active: whether the CRTC is actively displaying (used for DPMS)
- * @mode_changed: for use by helpers and drivers when computing state updates
- * @active_changed: for use by helpers and drivers when computing state updates
+ * @planes_changed: planes on this crtc are updated
+ * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
+ * @active_changed: crtc_state->active
+ * @connectors_changed: connectors to this crtc have been updated
* @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
* 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
* @mode: current mode timings
* @event: optional pointer to a DRM event to signal upon completion of the
@@ -283,6 +284,7 @@ struct drm_crtc_state {
bool planes_changed : 1;
bool mode_changed : 1;
bool active_changed : 1;
+ bool connectors_changed : 1;
/* attached planes bitmask:
* WARNING: transitional helpers do not maintain plane_mask so
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed
2015-07-07 7:08 ` [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed Maarten Lankhorst
@ 2015-07-07 8:59 ` Daniel Vetter
2015-07-07 10:05 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 8:59 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 09:08:12AM +0200, Maarten Lankhorst wrote:
> 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.
>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/drm_atomic_helper.c | 25 +++++++++++++++++++------
> drivers/gpu/drm/i915/intel_display.c | 2 +-
> include/drm/drm_atomic.h | 3 ++-
> include/drm/drm_crtc.h | 8 +++++---
> 4 files changed, 27 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 66e76f4f43be..b818e3111380 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -124,7 +124,7 @@ steal_encoder(struct drm_atomic_state *state,
> if (IS_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) {
> if (connector->state->best_encoder != encoder)
> @@ -174,14 +174,14 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
> idx = drm_crtc_index(connector->state->crtc);
>
> crtc_state = state->crtc_states[idx];
> - crtc_state->mode_changed = true;
> + crtc_state->connectors_changed = true;
> }
>
> if (connector_state->crtc) {
> idx = drm_crtc_index(connector_state->crtc);
>
> 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)
> idx = drm_crtc_index(connector_state->crtc);
>
> 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",
> connector->base.id,
> @@ -256,7 +256,8 @@ mode_fixup(struct drm_atomic_state *state)
> bool ret;
>
> 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;
>
> drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
> @@ -312,7 +313,8 @@ mode_fixup(struct drm_atomic_state *state)
> for_each_crtc_in_state(state, crtc, crtc_state, i) {
> const struct drm_crtc_helper_funcs *funcs;
>
> - if (!crtc_state->mode_changed)
> + if (!crtc_state->mode_changed &&
> + !crtc_state->connectors_changed)
> continue;
>
> funcs = crtc->helper_private;
> @@ -373,7 +375,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> if (crtc->state->enable != crtc_state->enable) {
> DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
> 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;
I'd drop this one so that connectors_changed and mode_changed are truly
orthogonal. Also ->enable implies connectors changed since we do check
that there's only connected connectors if the crtc is on. Needs kerneldoc
update too ofc.
> + crtc_state->connectors_changed = true;
> }
> }
>
> @@ -2072,6 +2084,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
> state->mode_changed = false;
> state->active_changed = false;
> state->planes_changed = false;
> + state->connectors_changed = false;
> state->event = NULL;
> }
> EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e91613b1c871..6ddb462b4124 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -421,7 +421,7 @@ static const intel_limit_t intel_limits_bxt = {
> static bool
> needs_modeset(struct drm_crtc_state *state)
> {
> - return state->mode_changed || state->active_changed;
> + return drm_atomic_crtc_needs_modeset(state);
> }
>
> /**
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 8a3a913320eb..e67aeac2aee0 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -166,7 +166,8 @@ int __must_check drm_atomic_async_commit(struct drm_atomic_state *state);
> static inline bool
> 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;
> }
>
>
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 57ca8cc383a6..e39d6f1de5f7 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -255,12 +255,13 @@ struct drm_atomic_state;
> * @crtc: backpointer to the CRTC
> * @enable: whether the CRTC should be enabled, gates all other state
> * @active: whether the CRTC is actively displaying (used for DPMS)
> - * @mode_changed: for use by helpers and drivers when computing state updates
> - * @active_changed: for use by helpers and drivers when computing state updates
> + * @planes_changed: planes on this crtc are updated
> + * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
> + * @active_changed: crtc_state->active
missing a "has changed".
> + * @connectors_changed: connectors to this crtc have been updated
> * @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
> * 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
> * @mode: current mode timings
> * @event: optional pointer to a DRM event to signal upon completion of the
> @@ -283,6 +284,7 @@ struct drm_crtc_state {
> bool planes_changed : 1;
> bool mode_changed : 1;
> bool active_changed : 1;
> + bool connectors_changed : 1;
>
> /* attached planes bitmask:
> * WARNING: transitional helpers do not maintain plane_mask so
> --
> 2.1.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed
2015-07-07 8:59 ` Daniel Vetter
@ 2015-07-07 10:05 ` Maarten Lankhorst
2015-07-07 12:03 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:05 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 07-07-15 om 10:59 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:12AM +0200, Maarten Lankhorst wrote:
>> 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.
>>
>> Cc: dri-devel@lists.freedesktop.org
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/drm_atomic_helper.c | 25 +++++++++++++++++++------
>> drivers/gpu/drm/i915/intel_display.c | 2 +-
>> include/drm/drm_atomic.h | 3 ++-
>> include/drm/drm_crtc.h | 8 +++++---
>> 4 files changed, 27 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>> index 66e76f4f43be..b818e3111380 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -124,7 +124,7 @@ steal_encoder(struct drm_atomic_state *state,
>> if (IS_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) {
>> if (connector->state->best_encoder != encoder)
>> @@ -174,14 +174,14 @@ update_connector_routing(struct drm_atomic_state *state, int conn_idx)
>> idx = drm_crtc_index(connector->state->crtc);
>>
>> crtc_state = state->crtc_states[idx];
>> - crtc_state->mode_changed = true;
>> + crtc_state->connectors_changed = true;
>> }
>>
>> if (connector_state->crtc) {
>> idx = drm_crtc_index(connector_state->crtc);
>>
>> 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)
>> idx = drm_crtc_index(connector_state->crtc);
>>
>> 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",
>> connector->base.id,
>> @@ -256,7 +256,8 @@ mode_fixup(struct drm_atomic_state *state)
>> bool ret;
>>
>> 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;
>>
>> drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
>> @@ -312,7 +313,8 @@ mode_fixup(struct drm_atomic_state *state)
>> for_each_crtc_in_state(state, crtc, crtc_state, i) {
>> const struct drm_crtc_helper_funcs *funcs;
>>
>> - if (!crtc_state->mode_changed)
>> + if (!crtc_state->mode_changed &&
>> + !crtc_state->connectors_changed)
>> continue;
>>
>> funcs = crtc->helper_private;
>> @@ -373,7 +375,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>> if (crtc->state->enable != crtc_state->enable) {
>> DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
>> 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;
> I'd drop this one so that connectors_changed and mode_changed are truly
> orthogonal. Also ->enable implies connectors changed since we do check
> that there's only connected connectors if the crtc is on. Needs kerneldoc
> update too ofc.
They are orthogonal, think of this case:
1. crtc previously enabled, connector removed, mode stays same ->
connector_changed = true, mode_changed = false
2. crtc previously enabled, connectors stay the same, different mode ->
connectors_changed = false, mode_changed = true
The following is enforced by the checks:
crtc disabled, implies 0 connectors, no mode.
crtc enabled implies > 0 connectors, and a mode.
Hence the connectors_changed and mode_changed here are for documentation purposes only. :)
So if someone wonders what happens when enable is changed they don't have to dig through
the entire drm_atomic_helper_check_modeset function and still not be sure if it's coincidence
or not.
You're right about the kerneldoc, I'll fix it.
>> + crtc_state->connectors_changed = true;
>> }
>> }
>>
>> @@ -2072,6 +2084,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
>> state->mode_changed = false;
>> state->active_changed = false;
>> state->planes_changed = false;
>> + state->connectors_changed = false;
>> state->event = NULL;
>> }
>> EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index e91613b1c871..6ddb462b4124 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -421,7 +421,7 @@ static const intel_limit_t intel_limits_bxt = {
>> static bool
>> needs_modeset(struct drm_crtc_state *state)
>> {
>> - return state->mode_changed || state->active_changed;
>> + return drm_atomic_crtc_needs_modeset(state);
>> }
>>
>> /**
>> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
>> index 8a3a913320eb..e67aeac2aee0 100644
>> --- a/include/drm/drm_atomic.h
>> +++ b/include/drm/drm_atomic.h
>> @@ -166,7 +166,8 @@ int __must_check drm_atomic_async_commit(struct drm_atomic_state *state);
>> static inline bool
>> 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;
>> }
>>
>>
>> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
>> index 57ca8cc383a6..e39d6f1de5f7 100644
>> --- a/include/drm/drm_crtc.h
>> +++ b/include/drm/drm_crtc.h
>> @@ -255,12 +255,13 @@ struct drm_atomic_state;
>> * @crtc: backpointer to the CRTC
>> * @enable: whether the CRTC should be enabled, gates all other state
>> * @active: whether the CRTC is actively displaying (used for DPMS)
>> - * @mode_changed: for use by helpers and drivers when computing state updates
>> - * @active_changed: for use by helpers and drivers when computing state updates
>> + * @planes_changed: planes on this crtc are updated
>> + * @mode_changed: crtc_state->mode or crtc_state->enable has been changed
>> + * @active_changed: crtc_state->active
> missing a "has changed".
Oops, indeed!
~Maarten
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed
2015-07-07 10:05 ` Maarten Lankhorst
@ 2015-07-07 12:03 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 12:03 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 12:05:40PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 10:59 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:12AM +0200, Maarten Lankhorst wrote:
> >> @@ -373,7 +375,17 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> >> if (crtc->state->enable != crtc_state->enable) {
> >> DRM_DEBUG_ATOMIC("[CRTC:%d] enable changed\n",
> >> 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;
> > I'd drop this one so that connectors_changed and mode_changed are truly
> > orthogonal. Also ->enable implies connectors changed since we do check
> > that there's only connected connectors if the crtc is on. Needs kerneldoc
> > update too ofc.
>
> They are orthogonal, think of this case:
>
> 1. crtc previously enabled, connector removed, mode stays same ->
> connector_changed = true, mode_changed = false
>
> 2. crtc previously enabled, connectors stay the same, different mode ->
> connectors_changed = false, mode_changed = true
>
> The following is enforced by the checks:
> crtc disabled, implies 0 connectors, no mode.
> crtc enabled implies > 0 connectors, and a mode.
>
> Hence the connectors_changed and mode_changed here are for documentation purposes only. :)
>
> So if someone wonders what happens when enable is changed they don't have to dig through
> the entire drm_atomic_helper_check_modeset function and still not be sure if it's coincidence
> or not.
>
> You're right about the kerneldoc, I'll fix it.
Right, I guess I should have read your comment properly and disregarded
the kerneldoc ;-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:18 ` [Intel-gfx] " Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling Maarten Lankhorst
` (18 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx; +Cc: dri-devel
This allows the first atomic call during hw init to be a real modeset,
which is useful for forcing a recalculation.
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/drm_fb_helper.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index cac422916c7a..33b5e4ecaf46 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -322,10 +322,12 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
drm_warn_on_modeset_not_all_locked(dev);
list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
- if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY &&
+ (!plane->state || plane->state->fb))
drm_plane_force_disable(plane);
- if (dev->mode_config.rotation_property) {
+ if (dev->mode_config.rotation_property &&
+ (!plane->state || plane->state->rotation != BIT(DRM_ROTATE_0))) {
drm_mode_plane_set_obj_prop(plane,
dev->mode_config.rotation_property,
BIT(DRM_ROTATE_0));
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 7:08 ` [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same Maarten Lankhorst
@ 2015-07-07 9:18 ` Daniel Vetter
2015-07-07 10:20 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:18 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> This allows the first atomic call during hw init to be a real modeset,
> which is useful for forcing a recalculation.
fbcon is optional, you can't rely on anything being done in any specific
way. What exactly do you need this for, what's the implications?
-Daniel
>
> Cc: dri-devel@lists.freedesktop.org
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/drm_fb_helper.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index cac422916c7a..33b5e4ecaf46 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -322,10 +322,12 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
> drm_warn_on_modeset_not_all_locked(dev);
>
> list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> - if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> + if (plane->type != DRM_PLANE_TYPE_PRIMARY &&
> + (!plane->state || plane->state->fb))
> drm_plane_force_disable(plane);
>
> - if (dev->mode_config.rotation_property) {
> + if (dev->mode_config.rotation_property &&
> + (!plane->state || plane->state->rotation != BIT(DRM_ROTATE_0))) {
> drm_mode_plane_set_obj_prop(plane,
> dev->mode_config.rotation_property,
> BIT(DRM_ROTATE_0));
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 9:18 ` [Intel-gfx] " Daniel Vetter
@ 2015-07-07 10:20 ` Maarten Lankhorst
2015-07-07 12:10 ` [Intel-gfx] " Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:20 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 07-07-15 om 11:18 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>> This allows the first atomic call during hw init to be a real modeset,
>> which is useful for forcing a recalculation.
> fbcon is optional, you can't rely on anything being done in any specific
> way. What exactly do you need this for, what's the implications?
In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
I want the first function to be the modeset, so we have a sane base to commit changes on.
Ideally this whole function would have a atomic counterpart which does it in one go. :)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 10:20 ` Maarten Lankhorst
@ 2015-07-07 12:10 ` Daniel Vetter
2015-07-07 14:32 ` Maarten Lankhorst
2015-07-07 15:08 ` Maarten Lankhorst
0 siblings, 2 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 12:10 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >> This allows the first atomic call during hw init to be a real modeset,
> >> which is useful for forcing a recalculation.
> > fbcon is optional, you can't rely on anything being done in any specific
> > way. What exactly do you need this for, what's the implications?
> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> I want the first function to be the modeset, so we have a sane base to commit changes on.
> Ideally this whole function would have a atomic counterpart which does it in one go. :)
Yeah. Otoh as soon as we have atomic modeset working we can replace all
the legacy entry points with atomic helpers, and then even plane_disable
will be a full atomic modeset.
What did fall apart with just touching properties/planes now?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 12:10 ` [Intel-gfx] " Daniel Vetter
@ 2015-07-07 14:32 ` Maarten Lankhorst
2015-07-07 16:40 ` Daniel Vetter
2015-07-07 15:08 ` Maarten Lankhorst
1 sibling, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 14:32 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 07-07-15 om 14:10 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>> This allows the first atomic call during hw init to be a real modeset,
>>>> which is useful for forcing a recalculation.
>>> fbcon is optional, you can't rely on anything being done in any specific
>>> way. What exactly do you need this for, what's the implications?
>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> the legacy entry points with atomic helpers, and then even plane_disable
> will be a full atomic modeset.
>
> What did fall apart with just touching properties/planes now?
Setting rotation on the primary plane caused it to be disabled because
the src and dst rectangle are not set up yet until the modeset. So the
check function saw that the plane should be invisible and performs the
update.
It's also an extra vblank wait when the primary plane is visible.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 14:32 ` Maarten Lankhorst
@ 2015-07-07 16:40 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 16:40 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 04:32:44PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>> This allows the first atomic call during hw init to be a real modeset,
> >>>> which is useful for forcing a recalculation.
> >>> fbcon is optional, you can't rely on anything being done in any specific
> >>> way. What exactly do you need this for, what's the implications?
> >> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> > Yeah. Otoh as soon as we have atomic modeset working we can replace all
> > the legacy entry points with atomic helpers, and then even plane_disable
> > will be a full atomic modeset.
> >
> > What did fall apart with just touching properties/planes now?
> Setting rotation on the primary plane caused it to be disabled because
> the src and dst rectangle are not set up yet until the modeset. So the
> check function saw that the plane should be invisible and performs the
> update.
Sounds like a bug - we need to recreate more of the primary plane state.
Or maybe we need to call the atomic_check function for the primary plane
to compute all that derived state. But we really can't rely upon userspace
to do a modeset first, e.g. X at start (if there's no fbcon) loves to read
and then write back all the properties (or at least did).
We really need to handle this in the backend properly.
> It's also an extra vblank wait when the primary plane is visible.
Another bug, no-op changes with the same fb should not result in a vblank
wait. At least not when using the helpers (or if there is a case I need to
copypaste the fix again).
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 12:10 ` [Intel-gfx] " Daniel Vetter
2015-07-07 14:32 ` Maarten Lankhorst
@ 2015-07-07 15:08 ` Maarten Lankhorst
2015-07-07 16:43 ` Daniel Vetter
1 sibling, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 15:08 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 07-07-15 om 14:10 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>> This allows the first atomic call during hw init to be a real modeset,
>>>> which is useful for forcing a recalculation.
>>> fbcon is optional, you can't rely on anything being done in any specific
>>> way. What exactly do you need this for, what's the implications?
>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> the legacy entry points with atomic helpers, and then even plane_disable
> will be a full atomic modeset.
>
> What did fall apart with just touching properties/planes now?
Also when i915 is fully atomic it calculates in intel_modeset_compute_config
if a modeset is needed after the first atomic call. Right now because
intel_modeset_compute_config is only called in set_config so this works as expected.
Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
and if the final mode is different this will introduce a double modeset.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 15:08 ` Maarten Lankhorst
@ 2015-07-07 16:43 ` Daniel Vetter
2015-07-08 8:00 ` [Intel-gfx] " Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 16:43 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>> This allows the first atomic call during hw init to be a real modeset,
> >>>> which is useful for forcing a recalculation.
> >>> fbcon is optional, you can't rely on anything being done in any specific
> >>> way. What exactly do you need this for, what's the implications?
> >> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> > Yeah. Otoh as soon as we have atomic modeset working we can replace all
> > the legacy entry points with atomic helpers, and then even plane_disable
> > will be a full atomic modeset.
> >
> > What did fall apart with just touching properties/planes now?
> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> if a modeset is needed after the first atomic call. Right now because
> intel_modeset_compute_config is only called in set_config so this works as expected.
> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> and if the final mode is different this will introduce a double modeset.
For expensive properties (i.e. a no-op changes causes something that takes
time like modeset or vblank wait) we need to make sure we filter them out
in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
the existing legacy set_prop functions should all filter out no-op changes
themselves. If we don't do that for rotation then that's a bug.
Same for disabling planes harder, that shouldn't take time. Especially
since fbcon only force-disable non-primary plane, and for driver load
that's the exact thing we already do in the driver anyway.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-07 16:43 ` Daniel Vetter
@ 2015-07-08 8:00 ` Maarten Lankhorst
2015-07-08 8:55 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 8:00 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 07-07-15 om 18:43 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>> which is useful for forcing a recalculation.
>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>> way. What exactly do you need this for, what's the implications?
>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>> the legacy entry points with atomic helpers, and then even plane_disable
>>> will be a full atomic modeset.
>>>
>>> What did fall apart with just touching properties/planes now?
>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>> if a modeset is needed after the first atomic call. Right now because
>> intel_modeset_compute_config is only called in set_config so this works as expected.
>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>> and if the final mode is different this will introduce a double modeset.
> For expensive properties (i.e. a no-op changes causes something that takes
> time like modeset or vblank wait) we need to make sure we filter them out
> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> the existing legacy set_prop functions should all filter out no-op changes
> themselves. If we don't do that for rotation then that's a bug.
>
> Same for disabling planes harder, that shouldn't take time. Especially
> since fbcon only force-disable non-primary plane, and for driver load
> that's the exact thing we already do in the driver anyway.
Something like this?
---
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index a1d4e13f3908..2989232f4996 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -30,6 +30,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_atomic_helper.h>
+#include "drm_crtc_internal.h"
#include <linux/fence.h>
/**
@@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
{
struct drm_atomic_state *state;
struct drm_crtc_state *crtc_state;
- int ret = 0;
+ uint64_t retval;
+ int ret;
+
+ ret = drm_atomic_get_property(&crtc->base, property, &retval);
+ if (!ret && val == retval)
+ return 0;
state = drm_atomic_state_alloc(crtc->dev);
if (!state)
@@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
{
struct drm_atomic_state *state;
struct drm_plane_state *plane_state;
- int ret = 0;
+ uint64_t retval;
+ int ret;
+
+ ret = drm_atomic_get_property(&plane->base, property, &retval);
+ if (!ret && val == retval)
+ return 0;
state = drm_atomic_state_alloc(plane->dev);
if (!state)
@@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
{
struct drm_atomic_state *state;
struct drm_connector_state *connector_state;
- int ret = 0;
+ uint64_t retval;
+ int ret;
+
+ ret = drm_atomic_get_property(&connector->base, property, &retval);
+ if (!ret && val == retval)
+ return 0;
state = drm_atomic_state_alloc(connector->dev);
if (!state)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 424c83323aaa..5bab7bff8a15 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1327,7 +1327,8 @@ void drm_plane_force_disable(struct drm_plane *plane)
{
int ret;
- if (!plane->fb)
+ if ((plane->state && !plane->state->fb) ||
+ (!plane->state && !plane->fb))
return;
plane->old_fb = plane->fb;
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 8:00 ` [Intel-gfx] " Maarten Lankhorst
@ 2015-07-08 8:55 ` Daniel Vetter
2015-07-08 16:35 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 8:55 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>> which is useful for forcing a recalculation.
> >>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>> way. What exactly do you need this for, what's the implications?
> >>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>> the legacy entry points with atomic helpers, and then even plane_disable
> >>> will be a full atomic modeset.
> >>>
> >>> What did fall apart with just touching properties/planes now?
> >> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >> if a modeset is needed after the first atomic call. Right now because
> >> intel_modeset_compute_config is only called in set_config so this works as expected.
> >> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >> and if the final mode is different this will introduce a double modeset.
> > For expensive properties (i.e. a no-op changes causes something that takes
> > time like modeset or vblank wait) we need to make sure we filter them out
> > in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> > the existing legacy set_prop functions should all filter out no-op changes
> > themselves. If we don't do that for rotation then that's a bug.
> >
> > Same for disabling planes harder, that shouldn't take time. Especially
> > since fbcon only force-disable non-primary plane, and for driver load
> > that's the exact thing we already do in the driver anyway.
>
> Something like this?
> ---
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index a1d4e13f3908..2989232f4996 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -30,6 +30,7 @@
> #include <drm/drm_plane_helper.h>
> #include <drm/drm_crtc_helper.h>
> #include <drm/drm_atomic_helper.h>
> +#include "drm_crtc_internal.h"
> #include <linux/fence.h>
>
> /**
> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> {
> struct drm_atomic_state *state;
> struct drm_crtc_state *crtc_state;
> - int ret = 0;
> + uint64_t retval;
> + int ret;
> +
> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> + if (!ret && val == retval)
> + return 0;
>
> state = drm_atomic_state_alloc(crtc->dev);
> if (!state)
> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> {
> struct drm_atomic_state *state;
> struct drm_plane_state *plane_state;
> - int ret = 0;
> + uint64_t retval;
> + int ret;
> +
> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> + if (!ret && val == retval)
> + return 0;
>
> state = drm_atomic_state_alloc(plane->dev);
> if (!state)
> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> {
> struct drm_atomic_state *state;
> struct drm_connector_state *connector_state;
> - int ret = 0;
> + uint64_t retval;
> + int ret;
> +
> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> + if (!ret && val == retval)
> + return 0;
>
> state = drm_atomic_state_alloc(connector->dev);
> if (!state)
The reason I didn't do this is that a prop change might still result in no
hw state change (e.g. if you go automitic->explicit setting matching
automatic one). Hence I think we need to solve this in lower levels
anyway, i.e. in when computing the config. But it shouldn't cause trouble
yet.
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 424c83323aaa..5bab7bff8a15 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1327,7 +1327,8 @@ void drm_plane_force_disable(struct drm_plane *plane)
> {
> int ret;
>
> - if (!plane->fb)
> + if ((plane->state && !plane->state->fb) ||
> + (!plane->state && !plane->fb))
> return;
Nah, atomic helpers should figure this out imo. Since if userspace does
the same (loop over all planes) then it won't go through force_disable.
-Daniel
>
> plane->old_fb = plane->fb;
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 8:55 ` Daniel Vetter
@ 2015-07-08 16:35 ` Maarten Lankhorst
2015-07-08 17:52 ` [Intel-gfx] " Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 16:35 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 08-07-15 om 10:55 schreef Daniel Vetter:
> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>>>> which is useful for forcing a recalculation.
>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>>>> way. What exactly do you need this for, what's the implications?
>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>>>> the legacy entry points with atomic helpers, and then even plane_disable
>>>>> will be a full atomic modeset.
>>>>>
>>>>> What did fall apart with just touching properties/planes now?
>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>>>> if a modeset is needed after the first atomic call. Right now because
>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>>>> and if the final mode is different this will introduce a double modeset.
>>> For expensive properties (i.e. a no-op changes causes something that takes
>>> time like modeset or vblank wait) we need to make sure we filter them out
>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
>>> the existing legacy set_prop functions should all filter out no-op changes
>>> themselves. If we don't do that for rotation then that's a bug.
>>>
>>> Same for disabling planes harder, that shouldn't take time. Especially
>>> since fbcon only force-disable non-primary plane, and for driver load
>>> that's the exact thing we already do in the driver anyway.
>> Something like this?
>> ---
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>> index a1d4e13f3908..2989232f4996 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -30,6 +30,7 @@
>> #include <drm/drm_plane_helper.h>
>> #include <drm/drm_crtc_helper.h>
>> #include <drm/drm_atomic_helper.h>
>> +#include "drm_crtc_internal.h"
>> #include <linux/fence.h>
>>
>> /**
>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>> {
>> struct drm_atomic_state *state;
>> struct drm_crtc_state *crtc_state;
>> - int ret = 0;
>> + uint64_t retval;
>> + int ret;
>> +
>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
>> + if (!ret && val == retval)
>> + return 0;
>>
>> state = drm_atomic_state_alloc(crtc->dev);
>> if (!state)
>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
>> {
>> struct drm_atomic_state *state;
>> struct drm_plane_state *plane_state;
>> - int ret = 0;
>> + uint64_t retval;
>> + int ret;
>> +
>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
>> + if (!ret && val == retval)
>> + return 0;
>>
>> state = drm_atomic_state_alloc(plane->dev);
>> if (!state)
>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
>> {
>> struct drm_atomic_state *state;
>> struct drm_connector_state *connector_state;
>> - int ret = 0;
>> + uint64_t retval;
>> + int ret;
>> +
>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
>> + if (!ret && val == retval)
>> + return 0;
>>
>> state = drm_atomic_state_alloc(connector->dev);
>> if (!state)
> The reason I didn't do this is that a prop change might still result in no
> hw state change (e.g. if you go automitic->explicit setting matching
> automatic one). Hence I think we need to solve this in lower levels
> anyway, i.e. in when computing the config. But it shouldn't cause trouble
> yet.
Is that a ack or nack?
>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>> index 424c83323aaa..5bab7bff8a15 100644
>> --- a/drivers/gpu/drm/drm_crtc.c
>> +++ b/drivers/gpu/drm/drm_crtc.c
>> @@ -1327,7 +1327,8 @@ void drm_plane_force_disable(struct drm_plane *plane)
>> {
>> int ret;
>>
>> - if (!plane->fb)
>> + if ((plane->state && !plane->state->fb) ||
>> + (!plane->state && !plane->fb))
>> return;
> Nah, atomic helpers should figure this out imo. Since if userspace does
> the same (loop over all planes) then it won't go through force_disable.
> -Daniel
>
>>
>> plane->old_fb = plane->fb;
>>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 16:35 ` Maarten Lankhorst
@ 2015-07-08 17:52 ` Daniel Vetter
2015-07-08 18:25 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 17:52 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
> Op 08-07-15 om 10:55 schreef Daniel Vetter:
> > On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>>>> which is useful for forcing a recalculation.
> >>>>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>>>> way. What exactly do you need this for, what's the implications?
> >>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>>>> the legacy entry points with atomic helpers, and then even plane_disable
> >>>>> will be a full atomic modeset.
> >>>>>
> >>>>> What did fall apart with just touching properties/planes now?
> >>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >>>> if a modeset is needed after the first atomic call. Right now because
> >>>> intel_modeset_compute_config is only called in set_config so this works as expected.
> >>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >>>> and if the final mode is different this will introduce a double modeset.
> >>> For expensive properties (i.e. a no-op changes causes something that takes
> >>> time like modeset or vblank wait) we need to make sure we filter them out
> >>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> >>> the existing legacy set_prop functions should all filter out no-op changes
> >>> themselves. If we don't do that for rotation then that's a bug.
> >>>
> >>> Same for disabling planes harder, that shouldn't take time. Especially
> >>> since fbcon only force-disable non-primary plane, and for driver load
> >>> that's the exact thing we already do in the driver anyway.
> >> Something like this?
> >> ---
> >> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> >> index a1d4e13f3908..2989232f4996 100644
> >> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >> @@ -30,6 +30,7 @@
> >> #include <drm/drm_plane_helper.h>
> >> #include <drm/drm_crtc_helper.h>
> >> #include <drm/drm_atomic_helper.h>
> >> +#include "drm_crtc_internal.h"
> >> #include <linux/fence.h>
> >>
> >> /**
> >> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> >> {
> >> struct drm_atomic_state *state;
> >> struct drm_crtc_state *crtc_state;
> >> - int ret = 0;
> >> + uint64_t retval;
> >> + int ret;
> >> +
> >> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> >> + if (!ret && val == retval)
> >> + return 0;
> >>
> >> state = drm_atomic_state_alloc(crtc->dev);
> >> if (!state)
> >> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> >> {
> >> struct drm_atomic_state *state;
> >> struct drm_plane_state *plane_state;
> >> - int ret = 0;
> >> + uint64_t retval;
> >> + int ret;
> >> +
> >> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> >> + if (!ret && val == retval)
> >> + return 0;
> >>
> >> state = drm_atomic_state_alloc(plane->dev);
> >> if (!state)
> >> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> >> {
> >> struct drm_atomic_state *state;
> >> struct drm_connector_state *connector_state;
> >> - int ret = 0;
> >> + uint64_t retval;
> >> + int ret;
> >> +
> >> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> >> + if (!ret && val == retval)
> >> + return 0;
> >>
> >> state = drm_atomic_state_alloc(connector->dev);
> >> if (!state)
> > The reason I didn't do this is that a prop change might still result in no
> > hw state change (e.g. if you go automitic->explicit setting matching
> > automatic one). Hence I think we need to solve this in lower levels
> > anyway, i.e. in when computing the config. But it shouldn't cause trouble
> > yet.
> Is that a ack or nack?
I think we shouldn't need this really for i915, and it might cover up
bugs. I prefer we just do the evade modeset logic you've implemented once
we switch over to atomic props. Since atm we only have atomic props which
get updated in pageflips we shouldn't have serious problems here yet (for
setting the rotation prop to 0° again when fbdev starts up).
Or do I miss something still here?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 17:52 ` [Intel-gfx] " Daniel Vetter
@ 2015-07-08 18:25 ` Maarten Lankhorst
2015-07-08 20:12 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 18:25 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 08-07-15 om 19:52 schreef Daniel Vetter:
> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>>>>>> which is useful for forcing a recalculation.
>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>>>>>> way. What exactly do you need this for, what's the implications?
>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
>>>>>>> will be a full atomic modeset.
>>>>>>>
>>>>>>> What did fall apart with just touching properties/planes now?
>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>>>>>> if a modeset is needed after the first atomic call. Right now because
>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>>>>>> and if the final mode is different this will introduce a double modeset.
>>>>> For expensive properties (i.e. a no-op changes causes something that takes
>>>>> time like modeset or vblank wait) we need to make sure we filter them out
>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
>>>>> the existing legacy set_prop functions should all filter out no-op changes
>>>>> themselves. If we don't do that for rotation then that's a bug.
>>>>>
>>>>> Same for disabling planes harder, that shouldn't take time. Especially
>>>>> since fbcon only force-disable non-primary plane, and for driver load
>>>>> that's the exact thing we already do in the driver anyway.
>>>> Something like this?
>>>> ---
>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>>> index a1d4e13f3908..2989232f4996 100644
>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>> @@ -30,6 +30,7 @@
>>>> #include <drm/drm_plane_helper.h>
>>>> #include <drm/drm_crtc_helper.h>
>>>> #include <drm/drm_atomic_helper.h>
>>>> +#include "drm_crtc_internal.h"
>>>> #include <linux/fence.h>
>>>>
>>>> /**
>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>>>> {
>>>> struct drm_atomic_state *state;
>>>> struct drm_crtc_state *crtc_state;
>>>> - int ret = 0;
>>>> + uint64_t retval;
>>>> + int ret;
>>>> +
>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
>>>> + if (!ret && val == retval)
>>>> + return 0;
>>>>
>>>> state = drm_atomic_state_alloc(crtc->dev);
>>>> if (!state)
>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
>>>> {
>>>> struct drm_atomic_state *state;
>>>> struct drm_plane_state *plane_state;
>>>> - int ret = 0;
>>>> + uint64_t retval;
>>>> + int ret;
>>>> +
>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
>>>> + if (!ret && val == retval)
>>>> + return 0;
>>>>
>>>> state = drm_atomic_state_alloc(plane->dev);
>>>> if (!state)
>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
>>>> {
>>>> struct drm_atomic_state *state;
>>>> struct drm_connector_state *connector_state;
>>>> - int ret = 0;
>>>> + uint64_t retval;
>>>> + int ret;
>>>> +
>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
>>>> + if (!ret && val == retval)
>>>> + return 0;
>>>>
>>>> state = drm_atomic_state_alloc(connector->dev);
>>>> if (!state)
>>> The reason I didn't do this is that a prop change might still result in no
>>> hw state change (e.g. if you go automitic->explicit setting matching
>>> automatic one). Hence I think we need to solve this in lower levels
>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
>>> yet.
>> Is that a ack or nack?
> I think we shouldn't need this really for i915, and it might cover up
> bugs. I prefer we just do the evade modeset logic you've implemented once
> we switch over to atomic props. Since atm we only have atomic props which
> get updated in pageflips we shouldn't have serious problems here yet (for
> setting the rotation prop to 0° again when fbdev starts up).
>
> Or do I miss something still here?
Yes, if the hardware mode is incompatible with its calculated sw mode,
and we set a different mode from fbdev you get 2 modesets instead of 1.
First to make the mode compatible because of the rotate_0, second to set the new mode.
~Maarten
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 18:25 ` Maarten Lankhorst
@ 2015-07-08 20:12 ` Daniel Vetter
2015-07-13 8:59 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 20:12 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
> Op 08-07-15 om 19:52 schreef Daniel Vetter:
> > On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
> >> Op 08-07-15 om 10:55 schreef Daniel Vetter:
> >>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> >>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> >>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>>>>>> which is useful for forcing a recalculation.
> >>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>>>>>> way. What exactly do you need this for, what's the implications?
> >>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
> >>>>>>> will be a full atomic modeset.
> >>>>>>>
> >>>>>>> What did fall apart with just touching properties/planes now?
> >>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >>>>>> if a modeset is needed after the first atomic call. Right now because
> >>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
> >>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >>>>>> and if the final mode is different this will introduce a double modeset.
> >>>>> For expensive properties (i.e. a no-op changes causes something that takes
> >>>>> time like modeset or vblank wait) we need to make sure we filter them out
> >>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> >>>>> the existing legacy set_prop functions should all filter out no-op changes
> >>>>> themselves. If we don't do that for rotation then that's a bug.
> >>>>>
> >>>>> Same for disabling planes harder, that shouldn't take time. Especially
> >>>>> since fbcon only force-disable non-primary plane, and for driver load
> >>>>> that's the exact thing we already do in the driver anyway.
> >>>> Something like this?
> >>>> ---
> >>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> >>>> index a1d4e13f3908..2989232f4996 100644
> >>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>>> @@ -30,6 +30,7 @@
> >>>> #include <drm/drm_plane_helper.h>
> >>>> #include <drm/drm_crtc_helper.h>
> >>>> #include <drm/drm_atomic_helper.h>
> >>>> +#include "drm_crtc_internal.h"
> >>>> #include <linux/fence.h>
> >>>>
> >>>> /**
> >>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> >>>> {
> >>>> struct drm_atomic_state *state;
> >>>> struct drm_crtc_state *crtc_state;
> >>>> - int ret = 0;
> >>>> + uint64_t retval;
> >>>> + int ret;
> >>>> +
> >>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> >>>> + if (!ret && val == retval)
> >>>> + return 0;
> >>>>
> >>>> state = drm_atomic_state_alloc(crtc->dev);
> >>>> if (!state)
> >>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> >>>> {
> >>>> struct drm_atomic_state *state;
> >>>> struct drm_plane_state *plane_state;
> >>>> - int ret = 0;
> >>>> + uint64_t retval;
> >>>> + int ret;
> >>>> +
> >>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> >>>> + if (!ret && val == retval)
> >>>> + return 0;
> >>>>
> >>>> state = drm_atomic_state_alloc(plane->dev);
> >>>> if (!state)
> >>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> >>>> {
> >>>> struct drm_atomic_state *state;
> >>>> struct drm_connector_state *connector_state;
> >>>> - int ret = 0;
> >>>> + uint64_t retval;
> >>>> + int ret;
> >>>> +
> >>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> >>>> + if (!ret && val == retval)
> >>>> + return 0;
> >>>>
> >>>> state = drm_atomic_state_alloc(connector->dev);
> >>>> if (!state)
> >>> The reason I didn't do this is that a prop change might still result in no
> >>> hw state change (e.g. if you go automitic->explicit setting matching
> >>> automatic one). Hence I think we need to solve this in lower levels
> >>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
> >>> yet.
> >> Is that a ack or nack?
> > I think we shouldn't need this really for i915, and it might cover up
> > bugs. I prefer we just do the evade modeset logic you've implemented once
> > we switch over to atomic props. Since atm we only have atomic props which
> > get updated in pageflips we shouldn't have serious problems here yet (for
> > setting the rotation prop to 0° again when fbdev starts up).
> >
> > Or do I miss something still here?
> Yes, if the hardware mode is incompatible with its calculated sw mode,
> and we set a different mode from fbdev you get 2 modesets instead of 1.
How does that happen? For setting the rotation property we should just
duplicate the current crtc state. Since there's no mode changing (they
should match perfectly no matter how botched the reconstruction is) there
shouldn't be any need to recompute the config completely and discover that
there's a mismatch. Which means we'll just do the plane update (which
might do a few silly mmios but shouldn't block) and that's it.
At least that's what I'd expect - where does this fall apart?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-08 20:12 ` Daniel Vetter
@ 2015-07-13 8:59 ` Maarten Lankhorst
2015-07-13 9:13 ` [Intel-gfx] " Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-13 8:59 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 08-07-15 om 22:12 schreef Daniel Vetter:
> On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
>> Op 08-07-15 om 19:52 schreef Daniel Vetter:
>>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
>>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
>>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
>>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
>>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>>>>>>>> which is useful for forcing a recalculation.
>>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>>>>>>>> way. What exactly do you need this for, what's the implications?
>>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
>>>>>>>>> will be a full atomic modeset.
>>>>>>>>>
>>>>>>>>> What did fall apart with just touching properties/planes now?
>>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>>>>>>>> if a modeset is needed after the first atomic call. Right now because
>>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
>>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>>>>>>>> and if the final mode is different this will introduce a double modeset.
>>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
>>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
>>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
>>>>>>> the existing legacy set_prop functions should all filter out no-op changes
>>>>>>> themselves. If we don't do that for rotation then that's a bug.
>>>>>>>
>>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
>>>>>>> since fbcon only force-disable non-primary plane, and for driver load
>>>>>>> that's the exact thing we already do in the driver anyway.
>>>>>> Something like this?
>>>>>> ---
>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>> index a1d4e13f3908..2989232f4996 100644
>>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>> @@ -30,6 +30,7 @@
>>>>>> #include <drm/drm_plane_helper.h>
>>>>>> #include <drm/drm_crtc_helper.h>
>>>>>> #include <drm/drm_atomic_helper.h>
>>>>>> +#include "drm_crtc_internal.h"
>>>>>> #include <linux/fence.h>
>>>>>>
>>>>>> /**
>>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>>>>>> {
>>>>>> struct drm_atomic_state *state;
>>>>>> struct drm_crtc_state *crtc_state;
>>>>>> - int ret = 0;
>>>>>> + uint64_t retval;
>>>>>> + int ret;
>>>>>> +
>>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
>>>>>> + if (!ret && val == retval)
>>>>>> + return 0;
>>>>>>
>>>>>> state = drm_atomic_state_alloc(crtc->dev);
>>>>>> if (!state)
>>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
>>>>>> {
>>>>>> struct drm_atomic_state *state;
>>>>>> struct drm_plane_state *plane_state;
>>>>>> - int ret = 0;
>>>>>> + uint64_t retval;
>>>>>> + int ret;
>>>>>> +
>>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
>>>>>> + if (!ret && val == retval)
>>>>>> + return 0;
>>>>>>
>>>>>> state = drm_atomic_state_alloc(plane->dev);
>>>>>> if (!state)
>>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
>>>>>> {
>>>>>> struct drm_atomic_state *state;
>>>>>> struct drm_connector_state *connector_state;
>>>>>> - int ret = 0;
>>>>>> + uint64_t retval;
>>>>>> + int ret;
>>>>>> +
>>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
>>>>>> + if (!ret && val == retval)
>>>>>> + return 0;
>>>>>>
>>>>>> state = drm_atomic_state_alloc(connector->dev);
>>>>>> if (!state)
>>>>> The reason I didn't do this is that a prop change might still result in no
>>>>> hw state change (e.g. if you go automitic->explicit setting matching
>>>>> automatic one). Hence I think we need to solve this in lower levels
>>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
>>>>> yet.
>>>> Is that a ack or nack?
>>> I think we shouldn't need this really for i915, and it might cover up
>>> bugs. I prefer we just do the evade modeset logic you've implemented once
>>> we switch over to atomic props. Since atm we only have atomic props which
>>> get updated in pageflips we shouldn't have serious problems here yet (for
>>> setting the rotation prop to 0° again when fbdev starts up).
>>>
>>> Or do I miss something still here?
>> Yes, if the hardware mode is incompatible with its calculated sw mode,
>> and we set a different mode from fbdev you get 2 modesets instead of 1.
> How does that happen? For setting the rotation property we should just
> duplicate the current crtc state. Since there's no mode changing (they
> should match perfectly no matter how botched the reconstruction is) there
> shouldn't be any need to recompute the config completely and discover that
> there's a mismatch. Which means we'll just do the plane update (which
> might do a few silly mmios but shouldn't block) and that's it.
>
> At least that's what I'd expect - where does this fall apart?
If crtc is active and primary fb visible, and converted to atomic:
restore_fbdev_mode() ->
drm_mode_plane_set_obj_prop() ->
drm_atomic_helper_plane_set_property() ->
drm_atomic_get_plane_state() ->
drm_atomic_get_crtc_state()
crtc state is part of the state, intel_modeset_pipe_config performs
the initial check if modeset's needed. Lets assume yes:
modeset()
drm_mode_set_config_internal() ->
modeset()
Boom double modeset. :(
The alternative solution is making a atomic version of restore_fbdev_mode,
but that would break drivers that are only partially converted to atomic,
like i915 with i915.nuclear_pageflip=true before the convert to atomic commit.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-13 8:59 ` Maarten Lankhorst
@ 2015-07-13 9:13 ` Daniel Vetter
2015-07-13 9:23 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-13 9:13 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Mon, Jul 13, 2015 at 10:59:32AM +0200, Maarten Lankhorst wrote:
> Op 08-07-15 om 22:12 schreef Daniel Vetter:
> > On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
> >> Op 08-07-15 om 19:52 schreef Daniel Vetter:
> >>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
> >>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
> >>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> >>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> >>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>>>>>>>> which is useful for forcing a recalculation.
> >>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>>>>>>>> way. What exactly do you need this for, what's the implications?
> >>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
> >>>>>>>>> will be a full atomic modeset.
> >>>>>>>>>
> >>>>>>>>> What did fall apart with just touching properties/planes now?
> >>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >>>>>>>> if a modeset is needed after the first atomic call. Right now because
> >>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
> >>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >>>>>>>> and if the final mode is different this will introduce a double modeset.
> >>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
> >>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
> >>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> >>>>>>> the existing legacy set_prop functions should all filter out no-op changes
> >>>>>>> themselves. If we don't do that for rotation then that's a bug.
> >>>>>>>
> >>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
> >>>>>>> since fbcon only force-disable non-primary plane, and for driver load
> >>>>>>> that's the exact thing we already do in the driver anyway.
> >>>>>> Something like this?
> >>>>>> ---
> >>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>> index a1d4e13f3908..2989232f4996 100644
> >>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>> @@ -30,6 +30,7 @@
> >>>>>> #include <drm/drm_plane_helper.h>
> >>>>>> #include <drm/drm_crtc_helper.h>
> >>>>>> #include <drm/drm_atomic_helper.h>
> >>>>>> +#include "drm_crtc_internal.h"
> >>>>>> #include <linux/fence.h>
> >>>>>>
> >>>>>> /**
> >>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> >>>>>> {
> >>>>>> struct drm_atomic_state *state;
> >>>>>> struct drm_crtc_state *crtc_state;
> >>>>>> - int ret = 0;
> >>>>>> + uint64_t retval;
> >>>>>> + int ret;
> >>>>>> +
> >>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> >>>>>> + if (!ret && val == retval)
> >>>>>> + return 0;
> >>>>>>
> >>>>>> state = drm_atomic_state_alloc(crtc->dev);
> >>>>>> if (!state)
> >>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> >>>>>> {
> >>>>>> struct drm_atomic_state *state;
> >>>>>> struct drm_plane_state *plane_state;
> >>>>>> - int ret = 0;
> >>>>>> + uint64_t retval;
> >>>>>> + int ret;
> >>>>>> +
> >>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> >>>>>> + if (!ret && val == retval)
> >>>>>> + return 0;
> >>>>>>
> >>>>>> state = drm_atomic_state_alloc(plane->dev);
> >>>>>> if (!state)
> >>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> >>>>>> {
> >>>>>> struct drm_atomic_state *state;
> >>>>>> struct drm_connector_state *connector_state;
> >>>>>> - int ret = 0;
> >>>>>> + uint64_t retval;
> >>>>>> + int ret;
> >>>>>> +
> >>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> >>>>>> + if (!ret && val == retval)
> >>>>>> + return 0;
> >>>>>>
> >>>>>> state = drm_atomic_state_alloc(connector->dev);
> >>>>>> if (!state)
> >>>>> The reason I didn't do this is that a prop change might still result in no
> >>>>> hw state change (e.g. if you go automitic->explicit setting matching
> >>>>> automatic one). Hence I think we need to solve this in lower levels
> >>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
> >>>>> yet.
> >>>> Is that a ack or nack?
> >>> I think we shouldn't need this really for i915, and it might cover up
> >>> bugs. I prefer we just do the evade modeset logic you've implemented once
> >>> we switch over to atomic props. Since atm we only have atomic props which
> >>> get updated in pageflips we shouldn't have serious problems here yet (for
> >>> setting the rotation prop to 0° again when fbdev starts up).
> >>>
> >>> Or do I miss something still here?
> >> Yes, if the hardware mode is incompatible with its calculated sw mode,
> >> and we set a different mode from fbdev you get 2 modesets instead of 1.
> > How does that happen? For setting the rotation property we should just
> > duplicate the current crtc state. Since there's no mode changing (they
> > should match perfectly no matter how botched the reconstruction is) there
> > shouldn't be any need to recompute the config completely and discover that
> > there's a mismatch. Which means we'll just do the plane update (which
> > might do a few silly mmios but shouldn't block) and that's it.
> >
> > At least that's what I'd expect - where does this fall apart?
> If crtc is active and primary fb visible, and converted to atomic:
>
> restore_fbdev_mode() ->
> drm_mode_plane_set_obj_prop() ->
> drm_atomic_helper_plane_set_property() ->
> drm_atomic_get_plane_state() ->
> drm_atomic_get_crtc_state()
> crtc state is part of the state, intel_modeset_pipe_config performs
> the initial check if modeset's needed. Lets assume yes:
"Let's assume yes" -> that's imo a bug, so where does this happen so that
we can fix it? Disabling a plane or setting a plane prop really shouldn't
result in a modeset. Well at least if it's not a plane prop that does
required a modeset (but I don't think we have any of those).
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-13 9:13 ` [Intel-gfx] " Daniel Vetter
@ 2015-07-13 9:23 ` Maarten Lankhorst
2015-07-13 9:45 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-13 9:23 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 13-07-15 om 11:13 schreef Daniel Vetter:
> On Mon, Jul 13, 2015 at 10:59:32AM +0200, Maarten Lankhorst wrote:
>> Op 08-07-15 om 22:12 schreef Daniel Vetter:
>>> On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
>>>> Op 08-07-15 om 19:52 schreef Daniel Vetter:
>>>>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
>>>>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
>>>>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
>>>>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
>>>>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>>>>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>>>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>>>>>>>>>> which is useful for forcing a recalculation.
>>>>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>>>>>>>>>> way. What exactly do you need this for, what's the implications?
>>>>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>>>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>>>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
>>>>>>>>>>> will be a full atomic modeset.
>>>>>>>>>>>
>>>>>>>>>>> What did fall apart with just touching properties/planes now?
>>>>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>>>>>>>>>> if a modeset is needed after the first atomic call. Right now because
>>>>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
>>>>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>>>>>>>>>> and if the final mode is different this will introduce a double modeset.
>>>>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
>>>>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
>>>>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
>>>>>>>>> the existing legacy set_prop functions should all filter out no-op changes
>>>>>>>>> themselves. If we don't do that for rotation then that's a bug.
>>>>>>>>>
>>>>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
>>>>>>>>> since fbcon only force-disable non-primary plane, and for driver load
>>>>>>>>> that's the exact thing we already do in the driver anyway.
>>>>>>>> Something like this?
>>>>>>>> ---
>>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>> index a1d4e13f3908..2989232f4996 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>> @@ -30,6 +30,7 @@
>>>>>>>> #include <drm/drm_plane_helper.h>
>>>>>>>> #include <drm/drm_crtc_helper.h>
>>>>>>>> #include <drm/drm_atomic_helper.h>
>>>>>>>> +#include "drm_crtc_internal.h"
>>>>>>>> #include <linux/fence.h>
>>>>>>>>
>>>>>>>> /**
>>>>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>>>>>>>> {
>>>>>>>> struct drm_atomic_state *state;
>>>>>>>> struct drm_crtc_state *crtc_state;
>>>>>>>> - int ret = 0;
>>>>>>>> + uint64_t retval;
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
>>>>>>>> + if (!ret && val == retval)
>>>>>>>> + return 0;
>>>>>>>>
>>>>>>>> state = drm_atomic_state_alloc(crtc->dev);
>>>>>>>> if (!state)
>>>>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
>>>>>>>> {
>>>>>>>> struct drm_atomic_state *state;
>>>>>>>> struct drm_plane_state *plane_state;
>>>>>>>> - int ret = 0;
>>>>>>>> + uint64_t retval;
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
>>>>>>>> + if (!ret && val == retval)
>>>>>>>> + return 0;
>>>>>>>>
>>>>>>>> state = drm_atomic_state_alloc(plane->dev);
>>>>>>>> if (!state)
>>>>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
>>>>>>>> {
>>>>>>>> struct drm_atomic_state *state;
>>>>>>>> struct drm_connector_state *connector_state;
>>>>>>>> - int ret = 0;
>>>>>>>> + uint64_t retval;
>>>>>>>> + int ret;
>>>>>>>> +
>>>>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
>>>>>>>> + if (!ret && val == retval)
>>>>>>>> + return 0;
>>>>>>>>
>>>>>>>> state = drm_atomic_state_alloc(connector->dev);
>>>>>>>> if (!state)
>>>>>>> The reason I didn't do this is that a prop change might still result in no
>>>>>>> hw state change (e.g. if you go automitic->explicit setting matching
>>>>>>> automatic one). Hence I think we need to solve this in lower levels
>>>>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
>>>>>>> yet.
>>>>>> Is that a ack or nack?
>>>>> I think we shouldn't need this really for i915, and it might cover up
>>>>> bugs. I prefer we just do the evade modeset logic you've implemented once
>>>>> we switch over to atomic props. Since atm we only have atomic props which
>>>>> get updated in pageflips we shouldn't have serious problems here yet (for
>>>>> setting the rotation prop to 0° again when fbdev starts up).
>>>>>
>>>>> Or do I miss something still here?
>>>> Yes, if the hardware mode is incompatible with its calculated sw mode,
>>>> and we set a different mode from fbdev you get 2 modesets instead of 1.
>>> How does that happen? For setting the rotation property we should just
>>> duplicate the current crtc state. Since there's no mode changing (they
>>> should match perfectly no matter how botched the reconstruction is) there
>>> shouldn't be any need to recompute the config completely and discover that
>>> there's a mismatch. Which means we'll just do the plane update (which
>>> might do a few silly mmios but shouldn't block) and that's it.
>>>
>>> At least that's what I'd expect - where does this fall apart?
>> If crtc is active and primary fb visible, and converted to atomic:
>>
>> restore_fbdev_mode() ->
>> drm_mode_plane_set_obj_prop() ->
>> drm_atomic_helper_plane_set_property() ->
>> drm_atomic_get_plane_state() ->
>> drm_atomic_get_crtc_state()
>> crtc state is part of the state, intel_modeset_pipe_config performs
>> the initial check if modeset's needed. Lets assume yes:
> "Let's assume yes" -> that's imo a bug, so where does this happen so that
> we can fix it? Disabling a plane or setting a plane prop really shouldn't
> result in a modeset. Well at least if it's not a plane prop that does
> required a modeset (but I don't think we have any of those).
From a driver point of view you wouldn't be able to distinguish it from a real modeset to the same mode. :(
In both cases you have all planes added and the crtc.
Thinking about it more there will be 1 thing saving us from a modeset,
drm_atomic_crtc_check will reject enable without mode_blob for atomic drivers,
so until the first mode is set all atomic updates to the crtc will be rejected.
Unfortunately you will still get WARN_ON's for this, so a better solution's needed.
~Maarten
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-13 9:23 ` Maarten Lankhorst
@ 2015-07-13 9:45 ` Daniel Vetter
2015-07-13 9:49 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-13 9:45 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Mon, Jul 13, 2015 at 11:23:45AM +0200, Maarten Lankhorst wrote:
> Op 13-07-15 om 11:13 schreef Daniel Vetter:
> > On Mon, Jul 13, 2015 at 10:59:32AM +0200, Maarten Lankhorst wrote:
> >> Op 08-07-15 om 22:12 schreef Daniel Vetter:
> >>> On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
> >>>> Op 08-07-15 om 19:52 schreef Daniel Vetter:
> >>>>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
> >>>>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
> >>>>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> >>>>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> >>>>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>>>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>>>>>>>>>> which is useful for forcing a recalculation.
> >>>>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>>>>>>>>>> way. What exactly do you need this for, what's the implications?
> >>>>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>>>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>>>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
> >>>>>>>>>>> will be a full atomic modeset.
> >>>>>>>>>>>
> >>>>>>>>>>> What did fall apart with just touching properties/planes now?
> >>>>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >>>>>>>>>> if a modeset is needed after the first atomic call. Right now because
> >>>>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
> >>>>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >>>>>>>>>> and if the final mode is different this will introduce a double modeset.
> >>>>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
> >>>>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
> >>>>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> >>>>>>>>> the existing legacy set_prop functions should all filter out no-op changes
> >>>>>>>>> themselves. If we don't do that for rotation then that's a bug.
> >>>>>>>>>
> >>>>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
> >>>>>>>>> since fbcon only force-disable non-primary plane, and for driver load
> >>>>>>>>> that's the exact thing we already do in the driver anyway.
> >>>>>>>> Something like this?
> >>>>>>>> ---
> >>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>> index a1d4e13f3908..2989232f4996 100644
> >>>>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>> @@ -30,6 +30,7 @@
> >>>>>>>> #include <drm/drm_plane_helper.h>
> >>>>>>>> #include <drm/drm_crtc_helper.h>
> >>>>>>>> #include <drm/drm_atomic_helper.h>
> >>>>>>>> +#include "drm_crtc_internal.h"
> >>>>>>>> #include <linux/fence.h>
> >>>>>>>>
> >>>>>>>> /**
> >>>>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> >>>>>>>> {
> >>>>>>>> struct drm_atomic_state *state;
> >>>>>>>> struct drm_crtc_state *crtc_state;
> >>>>>>>> - int ret = 0;
> >>>>>>>> + uint64_t retval;
> >>>>>>>> + int ret;
> >>>>>>>> +
> >>>>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> >>>>>>>> + if (!ret && val == retval)
> >>>>>>>> + return 0;
> >>>>>>>>
> >>>>>>>> state = drm_atomic_state_alloc(crtc->dev);
> >>>>>>>> if (!state)
> >>>>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> >>>>>>>> {
> >>>>>>>> struct drm_atomic_state *state;
> >>>>>>>> struct drm_plane_state *plane_state;
> >>>>>>>> - int ret = 0;
> >>>>>>>> + uint64_t retval;
> >>>>>>>> + int ret;
> >>>>>>>> +
> >>>>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> >>>>>>>> + if (!ret && val == retval)
> >>>>>>>> + return 0;
> >>>>>>>>
> >>>>>>>> state = drm_atomic_state_alloc(plane->dev);
> >>>>>>>> if (!state)
> >>>>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> >>>>>>>> {
> >>>>>>>> struct drm_atomic_state *state;
> >>>>>>>> struct drm_connector_state *connector_state;
> >>>>>>>> - int ret = 0;
> >>>>>>>> + uint64_t retval;
> >>>>>>>> + int ret;
> >>>>>>>> +
> >>>>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> >>>>>>>> + if (!ret && val == retval)
> >>>>>>>> + return 0;
> >>>>>>>>
> >>>>>>>> state = drm_atomic_state_alloc(connector->dev);
> >>>>>>>> if (!state)
> >>>>>>> The reason I didn't do this is that a prop change might still result in no
> >>>>>>> hw state change (e.g. if you go automitic->explicit setting matching
> >>>>>>> automatic one). Hence I think we need to solve this in lower levels
> >>>>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
> >>>>>>> yet.
> >>>>>> Is that a ack or nack?
> >>>>> I think we shouldn't need this really for i915, and it might cover up
> >>>>> bugs. I prefer we just do the evade modeset logic you've implemented once
> >>>>> we switch over to atomic props. Since atm we only have atomic props which
> >>>>> get updated in pageflips we shouldn't have serious problems here yet (for
> >>>>> setting the rotation prop to 0° again when fbdev starts up).
> >>>>>
> >>>>> Or do I miss something still here?
> >>>> Yes, if the hardware mode is incompatible with its calculated sw mode,
> >>>> and we set a different mode from fbdev you get 2 modesets instead of 1.
> >>> How does that happen? For setting the rotation property we should just
> >>> duplicate the current crtc state. Since there's no mode changing (they
> >>> should match perfectly no matter how botched the reconstruction is) there
> >>> shouldn't be any need to recompute the config completely and discover that
> >>> there's a mismatch. Which means we'll just do the plane update (which
> >>> might do a few silly mmios but shouldn't block) and that's it.
> >>>
> >>> At least that's what I'd expect - where does this fall apart?
> >> If crtc is active and primary fb visible, and converted to atomic:
> >>
> >> restore_fbdev_mode() ->
> >> drm_mode_plane_set_obj_prop() ->
> >> drm_atomic_helper_plane_set_property() ->
> >> drm_atomic_get_plane_state() ->
> >> drm_atomic_get_crtc_state()
> >> crtc state is part of the state, intel_modeset_pipe_config performs
> >> the initial check if modeset's needed. Lets assume yes:
> > "Let's assume yes" -> that's imo a bug, so where does this happen so that
> > we can fix it? Disabling a plane or setting a plane prop really shouldn't
> > result in a modeset. Well at least if it's not a plane prop that does
> > required a modeset (but I don't think we have any of those).
> From a driver point of view you wouldn't be able to distinguish it from a real modeset to the same mode. :(
> In both cases you have all planes added and the crtc.
>
> Thinking about it more there will be 1 thing saving us from a modeset,
> drm_atomic_crtc_check will reject enable without mode_blob for atomic drivers,
> so until the first mode is set all atomic updates to the crtc will be rejected.
>
> Unfortunately you will still get WARN_ON's for this, so a better solution's needed.
Ok I think I start to grasp what's wrong, the trouble is that we don't
have the mode stuff fully set up yet (which is part of fastboot), which
means we'll get a bogus crtc_state->mode_changed despite that nothing
really changed. Ugly.
Could we insert a dummy mode_blob to avoid the WARNs and the bogus
mode_changed instead? The problem really is that doing this here is just
plugging the one source of troubles you're seeing right now (fbcon), the
initial set_* calls could come from anything really in any order. So we
really better be able to cope.
Even converting fbdev to have an optional atomic patch for DRIVER_ATOMIC
(unsafe i915 options aren't a concern here for me) won't fix this.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-13 9:45 ` Daniel Vetter
@ 2015-07-13 9:49 ` Maarten Lankhorst
2015-07-13 10:06 ` [Intel-gfx] " Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-13 9:49 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx, dri-devel
Op 13-07-15 om 11:45 schreef Daniel Vetter:
> On Mon, Jul 13, 2015 at 11:23:45AM +0200, Maarten Lankhorst wrote:
>> Op 13-07-15 om 11:13 schreef Daniel Vetter:
>>> On Mon, Jul 13, 2015 at 10:59:32AM +0200, Maarten Lankhorst wrote:
>>>> Op 08-07-15 om 22:12 schreef Daniel Vetter:
>>>>> On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
>>>>>> Op 08-07-15 om 19:52 schreef Daniel Vetter:
>>>>>>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
>>>>>>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
>>>>>>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
>>>>>>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
>>>>>>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
>>>>>>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>>>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
>>>>>>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
>>>>>>>>>>>>>>>> which is useful for forcing a recalculation.
>>>>>>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
>>>>>>>>>>>>>>> way. What exactly do you need this for, what's the implications?
>>>>>>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
>>>>>>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
>>>>>>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
>>>>>>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
>>>>>>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
>>>>>>>>>>>>> will be a full atomic modeset.
>>>>>>>>>>>>>
>>>>>>>>>>>>> What did fall apart with just touching properties/planes now?
>>>>>>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
>>>>>>>>>>>> if a modeset is needed after the first atomic call. Right now because
>>>>>>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
>>>>>>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
>>>>>>>>>>>> and if the final mode is different this will introduce a double modeset.
>>>>>>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
>>>>>>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
>>>>>>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
>>>>>>>>>>> the existing legacy set_prop functions should all filter out no-op changes
>>>>>>>>>>> themselves. If we don't do that for rotation then that's a bug.
>>>>>>>>>>>
>>>>>>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
>>>>>>>>>>> since fbcon only force-disable non-primary plane, and for driver load
>>>>>>>>>>> that's the exact thing we already do in the driver anyway.
>>>>>>>>>> Something like this?
>>>>>>>>>> ---
>>>>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>>>> index a1d4e13f3908..2989232f4996 100644
>>>>>>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>>>>>>>>> @@ -30,6 +30,7 @@
>>>>>>>>>> #include <drm/drm_plane_helper.h>
>>>>>>>>>> #include <drm/drm_crtc_helper.h>
>>>>>>>>>> #include <drm/drm_atomic_helper.h>
>>>>>>>>>> +#include "drm_crtc_internal.h"
>>>>>>>>>> #include <linux/fence.h>
>>>>>>>>>>
>>>>>>>>>> /**
>>>>>>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
>>>>>>>>>> {
>>>>>>>>>> struct drm_atomic_state *state;
>>>>>>>>>> struct drm_crtc_state *crtc_state;
>>>>>>>>>> - int ret = 0;
>>>>>>>>>> + uint64_t retval;
>>>>>>>>>> + int ret;
>>>>>>>>>> +
>>>>>>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
>>>>>>>>>> + if (!ret && val == retval)
>>>>>>>>>> + return 0;
>>>>>>>>>>
>>>>>>>>>> state = drm_atomic_state_alloc(crtc->dev);
>>>>>>>>>> if (!state)
>>>>>>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
>>>>>>>>>> {
>>>>>>>>>> struct drm_atomic_state *state;
>>>>>>>>>> struct drm_plane_state *plane_state;
>>>>>>>>>> - int ret = 0;
>>>>>>>>>> + uint64_t retval;
>>>>>>>>>> + int ret;
>>>>>>>>>> +
>>>>>>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
>>>>>>>>>> + if (!ret && val == retval)
>>>>>>>>>> + return 0;
>>>>>>>>>>
>>>>>>>>>> state = drm_atomic_state_alloc(plane->dev);
>>>>>>>>>> if (!state)
>>>>>>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
>>>>>>>>>> {
>>>>>>>>>> struct drm_atomic_state *state;
>>>>>>>>>> struct drm_connector_state *connector_state;
>>>>>>>>>> - int ret = 0;
>>>>>>>>>> + uint64_t retval;
>>>>>>>>>> + int ret;
>>>>>>>>>> +
>>>>>>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
>>>>>>>>>> + if (!ret && val == retval)
>>>>>>>>>> + return 0;
>>>>>>>>>>
>>>>>>>>>> state = drm_atomic_state_alloc(connector->dev);
>>>>>>>>>> if (!state)
>>>>>>>>> The reason I didn't do this is that a prop change might still result in no
>>>>>>>>> hw state change (e.g. if you go automitic->explicit setting matching
>>>>>>>>> automatic one). Hence I think we need to solve this in lower levels
>>>>>>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
>>>>>>>>> yet.
>>>>>>>> Is that a ack or nack?
>>>>>>> I think we shouldn't need this really for i915, and it might cover up
>>>>>>> bugs. I prefer we just do the evade modeset logic you've implemented once
>>>>>>> we switch over to atomic props. Since atm we only have atomic props which
>>>>>>> get updated in pageflips we shouldn't have serious problems here yet (for
>>>>>>> setting the rotation prop to 0° again when fbdev starts up).
>>>>>>>
>>>>>>> Or do I miss something still here?
>>>>>> Yes, if the hardware mode is incompatible with its calculated sw mode,
>>>>>> and we set a different mode from fbdev you get 2 modesets instead of 1.
>>>>> How does that happen? For setting the rotation property we should just
>>>>> duplicate the current crtc state. Since there's no mode changing (they
>>>>> should match perfectly no matter how botched the reconstruction is) there
>>>>> shouldn't be any need to recompute the config completely and discover that
>>>>> there's a mismatch. Which means we'll just do the plane update (which
>>>>> might do a few silly mmios but shouldn't block) and that's it.
>>>>>
>>>>> At least that's what I'd expect - where does this fall apart?
>>>> If crtc is active and primary fb visible, and converted to atomic:
>>>>
>>>> restore_fbdev_mode() ->
>>>> drm_mode_plane_set_obj_prop() ->
>>>> drm_atomic_helper_plane_set_property() ->
>>>> drm_atomic_get_plane_state() ->
>>>> drm_atomic_get_crtc_state()
>>>> crtc state is part of the state, intel_modeset_pipe_config performs
>>>> the initial check if modeset's needed. Lets assume yes:
>>> "Let's assume yes" -> that's imo a bug, so where does this happen so that
>>> we can fix it? Disabling a plane or setting a plane prop really shouldn't
>>> result in a modeset. Well at least if it's not a plane prop that does
>>> required a modeset (but I don't think we have any of those).
>> From a driver point of view you wouldn't be able to distinguish it from a real modeset to the same mode. :(
>> In both cases you have all planes added and the crtc.
>>
>> Thinking about it more there will be 1 thing saving us from a modeset,
>> drm_atomic_crtc_check will reject enable without mode_blob for atomic drivers,
>> so until the first mode is set all atomic updates to the crtc will be rejected.
>>
>> Unfortunately you will still get WARN_ON's for this, so a better solution's needed.
> Ok I think I start to grasp what's wrong, the trouble is that we don't
> have the mode stuff fully set up yet (which is part of fastboot), which
> means we'll get a bogus crtc_state->mode_changed despite that nothing
> really changed. Ugly.
No, mode_changed would be harmless, with proper skip modeset support it can be converted to a noop.
> Could we insert a dummy mode_blob to avoid the WARNs and the bogus
> mode_changed instead? The problem really is that doing this here is just
> plugging the one source of troubles you're seeing right now (fbcon), the
> initial set_* calls could come from anything really in any order. So we
> really better be able to cope.
Doesn't this mean we should set a real mode read out from hw state instead?
> Even converting fbdev to have an optional atomic patch for DRIVER_ATOMIC
> (unsafe i915 options aren't a concern here for me) won't fix this.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [Intel-gfx] [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same
2015-07-13 9:49 ` Maarten Lankhorst
@ 2015-07-13 10:06 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-13 10:06 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx, dri-devel
On Mon, Jul 13, 2015 at 11:49:01AM +0200, Maarten Lankhorst wrote:
> Op 13-07-15 om 11:45 schreef Daniel Vetter:
> > On Mon, Jul 13, 2015 at 11:23:45AM +0200, Maarten Lankhorst wrote:
> >> Op 13-07-15 om 11:13 schreef Daniel Vetter:
> >>> On Mon, Jul 13, 2015 at 10:59:32AM +0200, Maarten Lankhorst wrote:
> >>>> Op 08-07-15 om 22:12 schreef Daniel Vetter:
> >>>>> On Wed, Jul 08, 2015 at 08:25:07PM +0200, Maarten Lankhorst wrote:
> >>>>>> Op 08-07-15 om 19:52 schreef Daniel Vetter:
> >>>>>>> On Wed, Jul 08, 2015 at 06:35:47PM +0200, Maarten Lankhorst wrote:
> >>>>>>>> Op 08-07-15 om 10:55 schreef Daniel Vetter:
> >>>>>>>>> On Wed, Jul 08, 2015 at 10:00:22AM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>> Op 07-07-15 om 18:43 schreef Daniel Vetter:
> >>>>>>>>>>> On Tue, Jul 07, 2015 at 05:08:34PM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>> Op 07-07-15 om 14:10 schreef Daniel Vetter:
> >>>>>>>>>>>>> On Tue, Jul 07, 2015 at 12:20:10PM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>>>>>>>>>>>>>> On Tue, Jul 07, 2015 at 09:08:13AM +0200, Maarten Lankhorst wrote:
> >>>>>>>>>>>>>>>> This allows the first atomic call during hw init to be a real modeset,
> >>>>>>>>>>>>>>>> which is useful for forcing a recalculation.
> >>>>>>>>>>>>>>> fbcon is optional, you can't rely on anything being done in any specific
> >>>>>>>>>>>>>>> way. What exactly do you need this for, what's the implications?
> >>>>>>>>>>>>>> In the hw readout I noticed some warnings when I wasn't setting any mode property in the readout.
> >>>>>>>>>>>>>> I want the first function to be the modeset, so we have a sane base to commit changes on.
> >>>>>>>>>>>>>> Ideally this whole function would have a atomic counterpart which does it in one go. :)
> >>>>>>>>>>>>> Yeah. Otoh as soon as we have atomic modeset working we can replace all
> >>>>>>>>>>>>> the legacy entry points with atomic helpers, and then even plane_disable
> >>>>>>>>>>>>> will be a full atomic modeset.
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> What did fall apart with just touching properties/planes now?
> >>>>>>>>>>>> Also when i915 is fully atomic it calculates in intel_modeset_compute_config
> >>>>>>>>>>>> if a modeset is needed after the first atomic call. Right now because
> >>>>>>>>>>>> intel_modeset_compute_config is only called in set_config so this works as expected.
> >>>>>>>>>>>> Otherwise drm_plane_force_disable or rotate_0 will force a modeset,
> >>>>>>>>>>>> and if the final mode is different this will introduce a double modeset.
> >>>>>>>>>>> For expensive properties (i.e. a no-op changes causes something that takes
> >>>>>>>>>>> time like modeset or vblank wait) we need to make sure we filter them out
> >>>>>>>>>>> in atomic_check. Yeah not quite there yet with pure atomic, but meanwhile
> >>>>>>>>>>> the existing legacy set_prop functions should all filter out no-op changes
> >>>>>>>>>>> themselves. If we don't do that for rotation then that's a bug.
> >>>>>>>>>>>
> >>>>>>>>>>> Same for disabling planes harder, that shouldn't take time. Especially
> >>>>>>>>>>> since fbcon only force-disable non-primary plane, and for driver load
> >>>>>>>>>>> that's the exact thing we already do in the driver anyway.
> >>>>>>>>>> Something like this?
> >>>>>>>>>> ---
> >>>>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>>>> index a1d4e13f3908..2989232f4996 100644
> >>>>>>>>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> >>>>>>>>>> @@ -30,6 +30,7 @@
> >>>>>>>>>> #include <drm/drm_plane_helper.h>
> >>>>>>>>>> #include <drm/drm_crtc_helper.h>
> >>>>>>>>>> #include <drm/drm_atomic_helper.h>
> >>>>>>>>>> +#include "drm_crtc_internal.h"
> >>>>>>>>>> #include <linux/fence.h>
> >>>>>>>>>>
> >>>>>>>>>> /**
> >>>>>>>>>> @@ -1716,7 +1717,12 @@ drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
> >>>>>>>>>> {
> >>>>>>>>>> struct drm_atomic_state *state;
> >>>>>>>>>> struct drm_crtc_state *crtc_state;
> >>>>>>>>>> - int ret = 0;
> >>>>>>>>>> + uint64_t retval;
> >>>>>>>>>> + int ret;
> >>>>>>>>>> +
> >>>>>>>>>> + ret = drm_atomic_get_property(&crtc->base, property, &retval);
> >>>>>>>>>> + if (!ret && val == retval)
> >>>>>>>>>> + return 0;
> >>>>>>>>>>
> >>>>>>>>>> state = drm_atomic_state_alloc(crtc->dev);
> >>>>>>>>>> if (!state)
> >>>>>>>>>> @@ -1776,7 +1782,12 @@ drm_atomic_helper_plane_set_property(struct drm_plane *plane,
> >>>>>>>>>> {
> >>>>>>>>>> struct drm_atomic_state *state;
> >>>>>>>>>> struct drm_plane_state *plane_state;
> >>>>>>>>>> - int ret = 0;
> >>>>>>>>>> + uint64_t retval;
> >>>>>>>>>> + int ret;
> >>>>>>>>>> +
> >>>>>>>>>> + ret = drm_atomic_get_property(&plane->base, property, &retval);
> >>>>>>>>>> + if (!ret && val == retval)
> >>>>>>>>>> + return 0;
> >>>>>>>>>>
> >>>>>>>>>> state = drm_atomic_state_alloc(plane->dev);
> >>>>>>>>>> if (!state)
> >>>>>>>>>> @@ -1836,7 +1847,12 @@ drm_atomic_helper_connector_set_property(struct drm_connector *connector,
> >>>>>>>>>> {
> >>>>>>>>>> struct drm_atomic_state *state;
> >>>>>>>>>> struct drm_connector_state *connector_state;
> >>>>>>>>>> - int ret = 0;
> >>>>>>>>>> + uint64_t retval;
> >>>>>>>>>> + int ret;
> >>>>>>>>>> +
> >>>>>>>>>> + ret = drm_atomic_get_property(&connector->base, property, &retval);
> >>>>>>>>>> + if (!ret && val == retval)
> >>>>>>>>>> + return 0;
> >>>>>>>>>>
> >>>>>>>>>> state = drm_atomic_state_alloc(connector->dev);
> >>>>>>>>>> if (!state)
> >>>>>>>>> The reason I didn't do this is that a prop change might still result in no
> >>>>>>>>> hw state change (e.g. if you go automitic->explicit setting matching
> >>>>>>>>> automatic one). Hence I think we need to solve this in lower levels
> >>>>>>>>> anyway, i.e. in when computing the config. But it shouldn't cause trouble
> >>>>>>>>> yet.
> >>>>>>>> Is that a ack or nack?
> >>>>>>> I think we shouldn't need this really for i915, and it might cover up
> >>>>>>> bugs. I prefer we just do the evade modeset logic you've implemented once
> >>>>>>> we switch over to atomic props. Since atm we only have atomic props which
> >>>>>>> get updated in pageflips we shouldn't have serious problems here yet (for
> >>>>>>> setting the rotation prop to 0° again when fbdev starts up).
> >>>>>>>
> >>>>>>> Or do I miss something still here?
> >>>>>> Yes, if the hardware mode is incompatible with its calculated sw mode,
> >>>>>> and we set a different mode from fbdev you get 2 modesets instead of 1.
> >>>>> How does that happen? For setting the rotation property we should just
> >>>>> duplicate the current crtc state. Since there's no mode changing (they
> >>>>> should match perfectly no matter how botched the reconstruction is) there
> >>>>> shouldn't be any need to recompute the config completely and discover that
> >>>>> there's a mismatch. Which means we'll just do the plane update (which
> >>>>> might do a few silly mmios but shouldn't block) and that's it.
> >>>>>
> >>>>> At least that's what I'd expect - where does this fall apart?
> >>>> If crtc is active and primary fb visible, and converted to atomic:
> >>>>
> >>>> restore_fbdev_mode() ->
> >>>> drm_mode_plane_set_obj_prop() ->
> >>>> drm_atomic_helper_plane_set_property() ->
> >>>> drm_atomic_get_plane_state() ->
> >>>> drm_atomic_get_crtc_state()
> >>>> crtc state is part of the state, intel_modeset_pipe_config performs
> >>>> the initial check if modeset's needed. Lets assume yes:
> >>> "Let's assume yes" -> that's imo a bug, so where does this happen so that
> >>> we can fix it? Disabling a plane or setting a plane prop really shouldn't
> >>> result in a modeset. Well at least if it's not a plane prop that does
> >>> required a modeset (but I don't think we have any of those).
> >> From a driver point of view you wouldn't be able to distinguish it from a real modeset to the same mode. :(
> >> In both cases you have all planes added and the crtc.
> >>
> >> Thinking about it more there will be 1 thing saving us from a modeset,
> >> drm_atomic_crtc_check will reject enable without mode_blob for atomic drivers,
> >> so until the first mode is set all atomic updates to the crtc will be rejected.
> >>
> >> Unfortunately you will still get WARN_ON's for this, so a better solution's needed.
> > Ok I think I start to grasp what's wrong, the trouble is that we don't
> > have the mode stuff fully set up yet (which is part of fastboot), which
> > means we'll get a bogus crtc_state->mode_changed despite that nothing
> > really changed. Ugly.
> No, mode_changed would be harmless, with proper skip modeset support it can be converted to a noop.
> > Could we insert a dummy mode_blob to avoid the WARNs and the bogus
> > mode_changed instead? The problem really is that doing this here is just
> > plugging the one source of troubles you're seeing right now (fbcon), the
> > initial set_* calls could come from anything really in any order. So we
> > really better be able to cope.
> Doesn't this mean we should set a real mode read out from hw state instead?
Yeah I guess so. We simply need to make sure that we have a mismatch.
Your DRIVER_MODE approach seems like it should work out.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 01/20] drm/atomic: add connectors_changed to separate it from mode_changed Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 02/20] drm: Don't update plane properties for atomic planes if it stays the same Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:18 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled Maarten Lankhorst
` (17 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This should fix suspend on newer platforms.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6ddb462b4124..4d1a474e0d13 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6179,6 +6179,8 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
for_each_power_domain(domain, domains)
intel_display_power_put(dev_priv, domain);
intel_crtc->enabled_power_domains = 0;
+ intel_crtc->active = false;
+ intel_disable_shared_dpll(intel_crtc);
}
/*
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 7:08 ` [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling Maarten Lankhorst
@ 2015-07-07 9:18 ` Daniel Vetter
2015-07-07 10:22 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:18 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
> This should fix suspend on newer platforms.
Which patch broke this? Also what is "newer platform" and what exactly got
fixed? Please elaborate a bit more in your commit messages, they're too
terse.
-Daniel
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 6ddb462b4124..4d1a474e0d13 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6179,6 +6179,8 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
> for_each_power_domain(domain, domains)
> intel_display_power_put(dev_priv, domain);
> intel_crtc->enabled_power_domains = 0;
> + intel_crtc->active = false;
> + intel_disable_shared_dpll(intel_crtc);
> }
>
> /*
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 9:18 ` Daniel Vetter
@ 2015-07-07 10:22 ` Maarten Lankhorst
2015-07-07 12:39 ` Patrik Jakobsson
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:22 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 11:18 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
>> This should fix suspend on newer platforms.
> Which patch broke this? Also what is "newer platform" and what exactly got
> fixed? Please elaborate a bit more in your commit messages, they're too
> terse.
There were a lot of warnings about active mismatches and power well not being idle on suspend.
This should fix the power well by disabling the shared dpll and unsetting crtc->active.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 10:22 ` Maarten Lankhorst
@ 2015-07-07 12:39 ` Patrik Jakobsson
2015-07-07 14:14 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Patrik Jakobsson @ 2015-07-07 12:39 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 12:22:12PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
> >> This should fix suspend on newer platforms.
> > Which patch broke this? Also what is "newer platform" and what exactly got
> > fixed? Please elaborate a bit more in your commit messages, they're too
> > terse.
> There were a lot of warnings about active mismatches and power well not being idle on suspend.
>
> This should fix the power well by disabling the shared dpll and unsetting crtc->active.
This got broken by:
commit eddfcbcdc27fbecb33bff098967bbdd7ca75bfa6
Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date: Mon Jun 15 12:33:53 2015 +0200
drm/i915: Update less state during modeset.
No need to repeatedly call update_watermarks, or update_fbc.
Down to a single call to update_watermarks in .crtc_enable
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Unfortunately the patch doesn't fix the CAT_ERR on resume I'm experiencing on
SKL. An additional intel_update_watermarks() is needed to set DDB back to 0,0.
Also this is required in *_crtc_disable() since we forget to do the same thing
there. Not sure we also need to take care of disabling fbc at these places?
-Patrik
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 12:39 ` Patrik Jakobsson
@ 2015-07-07 14:14 ` Maarten Lankhorst
2015-07-08 8:12 ` Patrik Jakobsson
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 14:14 UTC (permalink / raw)
To: Daniel Vetter, intel-gfx
Op 07-07-15 om 14:39 schreef Patrik Jakobsson:
> On Tue, Jul 07, 2015 at 12:22:12PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
>>>> This should fix suspend on newer platforms.
>>> Which patch broke this? Also what is "newer platform" and what exactly got
>>> fixed? Please elaborate a bit more in your commit messages, they're too
>>> terse.
>> There were a lot of warnings about active mismatches and power well not being idle on suspend.
>>
>> This should fix the power well by disabling the shared dpll and unsetting crtc->active.
> This got broken by:
>
> commit eddfcbcdc27fbecb33bff098967bbdd7ca75bfa6
> Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Date: Mon Jun 15 12:33:53 2015 +0200
>
> drm/i915: Update less state during modeset.
>
> No need to repeatedly call update_watermarks, or update_fbc.
> Down to a single call to update_watermarks in .crtc_enable
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> Unfortunately the patch doesn't fix the CAT_ERR on resume I'm experiencing on
> SKL. An additional intel_update_watermarks() is needed to set DDB back to 0,0.
> Also this is required in *_crtc_disable() since we forget to do the same thing
> there. Not sure we also need to take care of disabling fbc at these places?
I would prefer to have this fix, and leave updating the watermark code out of crtc disable.
Does it work If you add a intel_update_watermarks to the noatomic function?
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-07 14:14 ` Maarten Lankhorst
@ 2015-07-08 8:12 ` Patrik Jakobsson
2015-07-08 8:50 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Patrik Jakobsson @ 2015-07-08 8:12 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 04:14:01PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 14:39 schreef Patrik Jakobsson:
> > On Tue, Jul 07, 2015 at 12:22:12PM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 11:18 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
> >>>> This should fix suspend on newer platforms.
> >>> Which patch broke this? Also what is "newer platform" and what exactly got
> >>> fixed? Please elaborate a bit more in your commit messages, they're too
> >>> terse.
> >> There were a lot of warnings about active mismatches and power well not being idle on suspend.
> >>
> >> This should fix the power well by disabling the shared dpll and unsetting crtc->active.
> > This got broken by:
> >
> > commit eddfcbcdc27fbecb33bff098967bbdd7ca75bfa6
> > Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Date: Mon Jun 15 12:33:53 2015 +0200
> >
> > drm/i915: Update less state during modeset.
> >
> > No need to repeatedly call update_watermarks, or update_fbc.
> > Down to a single call to update_watermarks in .crtc_enable
> >
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> > Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> >
> > Unfortunately the patch doesn't fix the CAT_ERR on resume I'm experiencing on
> > SKL. An additional intel_update_watermarks() is needed to set DDB back to 0,0.
> > Also this is required in *_crtc_disable() since we forget to do the same thing
> > there. Not sure we also need to take care of disabling fbc at these places?
> I would prefer to have this fix, and leave updating the watermark code out of crtc disable.
>
> Does it work If you add a intel_update_watermarks to the noatomic function?
No that doesn't help. The only other callsite I can find is __intel_set_mode()
so I guess watermarks need updating there as well.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling.
2015-07-08 8:12 ` Patrik Jakobsson
@ 2015-07-08 8:50 ` Maarten Lankhorst
0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 8:50 UTC (permalink / raw)
To: Patrik Jakobsson; +Cc: intel-gfx
Op 08-07-15 om 10:12 schreef Patrik Jakobsson:
> On Tue, Jul 07, 2015 at 04:14:01PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 14:39 schreef Patrik Jakobsson:
>>> On Tue, Jul 07, 2015 at 12:22:12PM +0200, Maarten Lankhorst wrote:
>>>> Op 07-07-15 om 11:18 schreef Daniel Vetter:
>>>>> On Tue, Jul 07, 2015 at 09:08:14AM +0200, Maarten Lankhorst wrote:
>>>>>> This should fix suspend on newer platforms.
>>>>> Which patch broke this? Also what is "newer platform" and what exactly got
>>>>> fixed? Please elaborate a bit more in your commit messages, they're too
>>>>> terse.
>>>> There were a lot of warnings about active mismatches and power well not being idle on suspend.
>>>>
>>>> This should fix the power well by disabling the shared dpll and unsetting crtc->active.
>>> This got broken by:
>>>
>>> commit eddfcbcdc27fbecb33bff098967bbdd7ca75bfa6
>>> Author: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>> Date: Mon Jun 15 12:33:53 2015 +0200
>>>
>>> drm/i915: Update less state during modeset.
>>>
>>> No need to repeatedly call update_watermarks, or update_fbc.
>>> Down to a single call to update_watermarks in .crtc_enable
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
>>> Tested-by(IVB): Matt Roper <matthew.d.roper@intel.com>
>>> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
>>>
>>> Unfortunately the patch doesn't fix the CAT_ERR on resume I'm experiencing on
>>> SKL. An additional intel_update_watermarks() is needed to set DDB back to 0,0.
>>> Also this is required in *_crtc_disable() since we forget to do the same thing
>>> there. Not sure we also need to take care of disabling fbc at these places?
>> I would prefer to have this fix, and leave updating the watermark code out of crtc disable.
>>
>> Does it work If you add a intel_update_watermarks to the noatomic function?
> No that doesn't help. The only other callsite I can find is __intel_set_mode()
> so I guess watermarks need updating there as well.
Did you add it after the line that sets crtc->active = false?
And the watermark update is forced by intel_crtc_atomic_check, if you need 2 wm updates post disable
that seems like a bug..
In any case below should work then.
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6ddb462b4124..c1f7dfb62909 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6179,6 +6179,9 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
for_each_power_domain(domain, domains)
intel_display_power_put(dev_priv, domain);
intel_crtc->enabled_power_domains = 0;
+ intel_crtc->active = false;
+ intel_disable_shared_dpll(intel_crtc);
+ intel_update_watermarks(crtc);
}
/*
@@ -13158,7 +13161,8 @@ static int __intel_set_mode(struct drm_atomic_state *state)
if (needs_modeset(crtc->state) && crtc->state->active) {
update_scanline_offset(to_intel_crtc(crtc));
dev_priv->display.crtc_enable(crtc);
- }
+ } else if (!crtc->state->active && crtc_state->active)
+ intel_update_watermarks(crtc);
drm_atomic_helper_commit_planes_on_crtc(crtc_state);
}
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread
* [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (2 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 03/20] drm/i915: Fix noatomic crtc disabling Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:26 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 05/20] drm/i915: Do not use plane_config in intel_fbdev.c Maarten Lankhorst
` (16 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This must be done in advance, and during crtc_disable all scalers
can be force disabled.
This means intel_atomic_setup_scalers is only called in 1 place now,
during crtc_check.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_atomic.c | 14 ++------
drivers/gpu/drm/i915/intel_display.c | 68 +++++++++++++++++++++++-------------
drivers/gpu/drm/i915/intel_dp.c | 2 +-
drivers/gpu/drm/i915/intel_drv.h | 2 +-
4 files changed, 48 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 0aeced82201e..429677a111d5 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
struct drm_plane *plane = NULL;
struct intel_plane *intel_plane;
struct intel_plane_state *plane_state = NULL;
- struct intel_crtc_scaler_state *scaler_state;
- struct drm_atomic_state *drm_state;
+ struct intel_crtc_scaler_state *scaler_state =
+ &crtc_state->scaler_state;
+ struct drm_atomic_state *drm_state = crtc_state->base.state;
int num_scalers_need;
int i, j;
- if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
- return 0;
-
- scaler_state = &crtc_state->scaler_state;
- drm_state = crtc_state->base.state;
-
num_scalers_need = hweight32(scaler_state->scaler_users);
DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
crtc_state, num_scalers_need, intel_crtc->num_scalers,
@@ -327,9 +322,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
name = "PLANE";
idx = plane->base.id;
- if (!drm_state)
- continue;
-
/* plane scaler case: assign as a plane scaler */
/* find the plane that set the bit as scaler_user */
plane = drm_state->planes[i];
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4d1a474e0d13..8cd3a7eb1e30 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2909,29 +2909,32 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
return i915_gem_obj_ggtt_offset_view(obj, view);
}
+static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
+{
+ struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
+ I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
+ I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
+ DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
+ intel_crtc->base.base.id, intel_crtc->pipe, id);
+}
+
/*
* This function detaches (aka. unbinds) unused scalers in hardware
*/
static void skl_detach_scalers(struct intel_crtc *intel_crtc)
{
- struct drm_device *dev;
- struct drm_i915_private *dev_priv;
struct intel_crtc_scaler_state *scaler_state;
int i;
- dev = intel_crtc->base.dev;
- dev_priv = dev->dev_private;
scaler_state = &intel_crtc->config->scaler_state;
/* loop through and disable scalers that aren't in use */
for (i = 0; i < intel_crtc->num_scalers; i++) {
- if (!scaler_state->scalers[i].in_use) {
- I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, i), 0);
- I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, i), 0);
- I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, i), 0);
- DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
- intel_crtc->base.base.id, intel_crtc->pipe, i);
- }
+ if (!scaler_state->scalers[i].in_use)
+ skl_detach_scaler(intel_crtc, i);
}
}
@@ -4362,13 +4365,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
* skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
*
* @state: crtc's scaler state
- * @force_detach: whether to forcibly disable scaler
*
* Return
* 0 - scaler_usage updated successfully
* error - requested scaling cannot be supported or other error condition
*/
-int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
+int skl_update_scaler_crtc(struct intel_crtc_state *state)
{
struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
struct drm_display_mode *adjusted_mode =
@@ -4377,7 +4379,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n",
intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
- return skl_update_scaler(state, force_detach, SKL_CRTC_INDEX,
+ return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
&state->scaler_state.scaler_id, DRM_ROTATE_0,
state->pipe_src_w, state->pipe_src_h,
adjusted_mode->hdisplay, adjusted_mode->vdisplay);
@@ -4451,7 +4453,15 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
return 0;
}
-static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
+static void skylake_scaler_disable(struct intel_crtc *crtc)
+{
+ int i;
+
+ for (i = 0; i < crtc->num_scalers; i++)
+ skl_detach_scaler(crtc, i);
+}
+
+static void skylake_pfit_enable(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4461,13 +4471,6 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
- /* To update pfit, first update scaler state */
- skl_update_scaler_crtc(crtc->config, !enable);
- intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
- skl_detach_scalers(crtc);
- if (!enable)
- return;
-
if (crtc->config->pch_pfit.enabled) {
int id;
@@ -4941,7 +4944,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_ddi_enable_pipe_clock(intel_crtc);
if (INTEL_INFO(dev)->gen == 9)
- skylake_pfit_update(intel_crtc, 1);
+ skylake_pfit_enable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_enable(intel_crtc);
else
@@ -5075,7 +5078,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
if (INTEL_INFO(dev)->gen == 9)
- skylake_pfit_update(intel_crtc, 0);
+ skylake_scaler_disable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
ironlake_pfit_disable(intel_crtc);
else
@@ -11823,7 +11826,17 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
return ret;
}
- return intel_atomic_setup_scalers(dev, intel_crtc, pipe_config);
+ ret = 0;
+ if (INTEL_INFO(dev)->gen >= 9) {
+ if (mode_changed)
+ ret = skl_update_scaler_crtc(pipe_config);
+
+ if (!ret)
+ ret = intel_atomic_setup_scalers(dev, intel_crtc,
+ pipe_config);
+ }
+
+ return ret;
}
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
@@ -15327,6 +15340,11 @@ static void readout_plane_state(struct intel_crtc *crtc,
continue;
drm_plane_state = p->base.state;
+
+ /* Plane scaler state is not touched here. The first atomic
+ * commit will restore all plane scalers to its old state.
+ */
+
if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
visible = primary_get_hw_state(crtc);
to_intel_plane_state(drm_plane_state)->visible = visible;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fcc64e5ef9c8..f1b9f939b435 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1384,7 +1384,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
if (INTEL_INFO(dev)->gen >= 9) {
int ret;
- ret = skl_update_scaler_crtc(pipe_config, 0);
+ ret = skl_update_scaler_crtc(pipe_config);
if (ret)
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 63d7d32e6123..2ed618f78fe6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1152,7 +1152,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
-int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state, int force_detach);
+int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled.
2015-07-07 7:08 ` [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled Maarten Lankhorst
@ 2015-07-07 9:26 ` Daniel Vetter
2015-07-07 10:46 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:26 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:15AM +0200, Maarten Lankhorst wrote:
> This must be done in advance, and during crtc_disable all scalers
"in advance" ... before what exactly? Yes I'm harping a bit about commit
messages today ;-)
> can be force disabled.
Why does it matter that all scalers can be force disabled?
> This means intel_atomic_setup_scalers is only called in 1 place now,
> during crtc_check.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
tbh I don't really understand what's the problem and what's the solution
implemented here. Judging from comments the trouble is that we don't
correctly recover the pfit state for skl scalers at hw readout time?
I guess we should fix that for at lest the crtc level scaler (including
cross-checking of all scaler state) and in sanitize_plane force-disabling
any plane that is using a scaler. But really not much clue here.
> ---
> drivers/gpu/drm/i915/intel_atomic.c | 14 ++------
> drivers/gpu/drm/i915/intel_display.c | 68 +++++++++++++++++++++++-------------
> drivers/gpu/drm/i915/intel_dp.c | 2 +-
> drivers/gpu/drm/i915/intel_drv.h | 2 +-
> 4 files changed, 48 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 0aeced82201e..429677a111d5 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
This function is way too big. Yeah not your doing, but imo would be good
to split it up a bit. Especially since it already has a comment explaining
the high-level flow which would be a good pattern to structure the
subfunction extraction after.
> struct drm_plane *plane = NULL;
> struct intel_plane *intel_plane;
> struct intel_plane_state *plane_state = NULL;
> - struct intel_crtc_scaler_state *scaler_state;
> - struct drm_atomic_state *drm_state;
> + struct intel_crtc_scaler_state *scaler_state =
> + &crtc_state->scaler_state;
> + struct drm_atomic_state *drm_state = crtc_state->base.state;
> int num_scalers_need;
> int i, j;
>
> - if (INTEL_INFO(dev)->gen < 9 || !intel_crtc || !crtc_state)
> - return 0;
> -
> - scaler_state = &crtc_state->scaler_state;
> - drm_state = crtc_state->base.state;
> -
> num_scalers_need = hweight32(scaler_state->scaler_users);
> DRM_DEBUG_KMS("crtc_state = %p need = %d avail = %d scaler_users = 0x%x\n",
> crtc_state, num_scalers_need, intel_crtc->num_scalers,
> @@ -327,9 +322,6 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
> name = "PLANE";
> idx = plane->base.id;
>
> - if (!drm_state)
> - continue;
> -
> /* plane scaler case: assign as a plane scaler */
> /* find the plane that set the bit as scaler_user */
> plane = drm_state->planes[i];
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 4d1a474e0d13..8cd3a7eb1e30 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2909,29 +2909,32 @@ unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> return i915_gem_obj_ggtt_offset_view(obj, view);
> }
>
> +static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
> +{
> + struct drm_device *dev = intel_crtc->base.dev;
> + struct drm_i915_private *dev_priv = dev->dev_private;
> +
> + I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0);
> + I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
> + I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
> + DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
> + intel_crtc->base.base.id, intel_crtc->pipe, id);
> +}
> +
> /*
> * This function detaches (aka. unbinds) unused scalers in hardware
> */
> static void skl_detach_scalers(struct intel_crtc *intel_crtc)
> {
> - struct drm_device *dev;
> - struct drm_i915_private *dev_priv;
> struct intel_crtc_scaler_state *scaler_state;
> int i;
>
> - dev = intel_crtc->base.dev;
> - dev_priv = dev->dev_private;
> scaler_state = &intel_crtc->config->scaler_state;
>
> /* loop through and disable scalers that aren't in use */
> for (i = 0; i < intel_crtc->num_scalers; i++) {
> - if (!scaler_state->scalers[i].in_use) {
> - I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, i), 0);
> - I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, i), 0);
> - I915_WRITE(SKL_PS_WIN_SZ(intel_crtc->pipe, i), 0);
> - DRM_DEBUG_KMS("CRTC:%d Disabled scaler id %u.%u\n",
> - intel_crtc->base.base.id, intel_crtc->pipe, i);
> - }
> + if (!scaler_state->scalers[i].in_use)
> + skl_detach_scaler(intel_crtc, i);
> }
> }
>
> @@ -4362,13 +4365,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> * skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
> *
> * @state: crtc's scaler state
> - * @force_detach: whether to forcibly disable scaler
> *
> * Return
> * 0 - scaler_usage updated successfully
> * error - requested scaling cannot be supported or other error condition
> */
> -int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
> +int skl_update_scaler_crtc(struct intel_crtc_state *state)
> {
> struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
> struct drm_display_mode *adjusted_mode =
> @@ -4377,7 +4379,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state, int force_detach)
> DRM_DEBUG_KMS("Updating scaler for [CRTC:%i] scaler_user index %u.%u\n",
> intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
>
> - return skl_update_scaler(state, force_detach, SKL_CRTC_INDEX,
> + return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
> &state->scaler_state.scaler_id, DRM_ROTATE_0,
> state->pipe_src_w, state->pipe_src_h,
> adjusted_mode->hdisplay, adjusted_mode->vdisplay);
> @@ -4451,7 +4453,15 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
> return 0;
> }
>
> -static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
> +static void skylake_scaler_disable(struct intel_crtc *crtc)
> +{
> + int i;
> +
> + for (i = 0; i < crtc->num_scalers; i++)
> + skl_detach_scaler(crtc, i);
> +}
> +
> +static void skylake_pfit_enable(struct intel_crtc *crtc)
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -4461,13 +4471,6 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
>
> DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
>
> - /* To update pfit, first update scaler state */
> - skl_update_scaler_crtc(crtc->config, !enable);
> - intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
> - skl_detach_scalers(crtc);
> - if (!enable)
> - return;
> -
> if (crtc->config->pch_pfit.enabled) {
> int id;
>
> @@ -4941,7 +4944,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> intel_ddi_enable_pipe_clock(intel_crtc);
>
> if (INTEL_INFO(dev)->gen == 9)
> - skylake_pfit_update(intel_crtc, 1);
> + skylake_pfit_enable(intel_crtc);
> else if (INTEL_INFO(dev)->gen < 9)
> ironlake_pfit_enable(intel_crtc);
> else
> @@ -5075,7 +5078,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
> intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
>
> if (INTEL_INFO(dev)->gen == 9)
> - skylake_pfit_update(intel_crtc, 0);
> + skylake_scaler_disable(intel_crtc);
> else if (INTEL_INFO(dev)->gen < 9)
> ironlake_pfit_disable(intel_crtc);
> else
> @@ -11823,7 +11826,17 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
> return ret;
> }
>
> - return intel_atomic_setup_scalers(dev, intel_crtc, pipe_config);
> + ret = 0;
> + if (INTEL_INFO(dev)->gen >= 9) {
> + if (mode_changed)
> + ret = skl_update_scaler_crtc(pipe_config);
> +
> + if (!ret)
> + ret = intel_atomic_setup_scalers(dev, intel_crtc,
> + pipe_config);
> + }
> +
> + return ret;
> }
>
> static const struct drm_crtc_helper_funcs intel_helper_funcs = {
> @@ -15327,6 +15340,11 @@ static void readout_plane_state(struct intel_crtc *crtc,
> continue;
>
> drm_plane_state = p->base.state;
> +
> + /* Plane scaler state is not touched here. The first atomic
> + * commit will restore all plane scalers to its old state.
> + */
> +
> if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
> visible = primary_get_hw_state(crtc);
> to_intel_plane_state(drm_plane_state)->visible = visible;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index fcc64e5ef9c8..f1b9f939b435 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1384,7 +1384,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>
> if (INTEL_INFO(dev)->gen >= 9) {
> int ret;
> - ret = skl_update_scaler_crtc(pipe_config, 0);
> + ret = skl_update_scaler_crtc(pipe_config);
> if (ret)
> return ret;
> }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 63d7d32e6123..2ed618f78fe6 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1152,7 +1152,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
> void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc);
> void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file);
>
> -int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state, int force_detach);
> +int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
> int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
>
> unsigned long intel_plane_obj_offset(struct intel_plane *intel_plane,
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled.
2015-07-07 9:26 ` Daniel Vetter
@ 2015-07-07 10:46 ` Maarten Lankhorst
0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:46 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 11:26 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:15AM +0200, Maarten Lankhorst wrote:
>> This must be done in advance, and during crtc_disable all scalers
> "in advance" ... before what exactly? Yes I'm harping a bit about commit
> messages today ;-)
>
>> can be force disabled.
> Why does it matter that all scalers can be force disabled?
>
>> This means intel_atomic_setup_scalers is only called in 1 place now,
>> during crtc_check.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> tbh I don't really understand what's the problem and what's the solution
> implemented here. Judging from comments the trouble is that we don't
> correctly recover the pfit state for skl scalers at hw readout time?
>
> I guess we should fix that for at lest the crtc level scaler (including
> cross-checking of all scaler state) and in sanitize_plane force-disabling
> any plane that is using a scaler. But really not much clue here.
intel_atomic_setup_scalers should only be called for the new state,
but it's called on the old state which doesn't need to be modified.
The crtc_disable function can just disable all scalers since there's no point in
doing a full recheck.
Alternatively it could only disable the crtc scaler id if it's >= 0, but I think
disabling all might be better for paranoia reasons.
>> ---
>> drivers/gpu/drm/i915/intel_atomic.c | 14 ++------
>> drivers/gpu/drm/i915/intel_display.c | 68 +++++++++++++++++++++++-------------
>> drivers/gpu/drm/i915/intel_dp.c | 2 +-
>> drivers/gpu/drm/i915/intel_drv.h | 2 +-
>> 4 files changed, 48 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
>> index 0aeced82201e..429677a111d5 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>> @@ -272,17 +272,12 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
> This function is way too big. Yeah not your doing, but imo would be good
> to split it up a bit. Especially since it already has a comment explaining
> the high-level flow which would be a good pattern to structure the
> subfunction extraction after.
I think adding a pipe_to_scaler_id or something would remove the whole plane
special casing block and make it a lot more readable.
Not checking intel_plane->pipe would be a good thing too, not sure how that could even happen.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 05/20] drm/i915: Do not use plane_config in intel_fbdev.c
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (3 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 04/20] drm/i915: Do not update pfit state when toggling crtc enabled Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare Maarten Lankhorst
` (15 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Use the atomic state instead, this allows removing plane_config
from the crtc after the full hw readout is completed.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_fbdev.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 2a1724e34a36..3d5bb56477ab 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -582,7 +582,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
struct intel_framebuffer *fb = NULL;
struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
- struct intel_initial_plane_config *plane_config = NULL;
unsigned int max_size = 0;
if (!i915.fastboot)
@@ -590,20 +589,21 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
/* Find the largest fb */
for_each_crtc(dev, crtc) {
+ struct drm_i915_gem_object *obj =
+ intel_fb_obj(crtc->primary->state->fb);
intel_crtc = to_intel_crtc(crtc);
- if (!intel_crtc->active || !crtc->primary->fb) {
+ if (!intel_crtc->active || !obj) {
DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
pipe_name(intel_crtc->pipe));
continue;
}
- if (intel_crtc->plane_config.size > max_size) {
+ if (obj->base.size > max_size) {
DRM_DEBUG_KMS("found possible fb from plane %c\n",
pipe_name(intel_crtc->pipe));
- plane_config = &intel_crtc->plane_config;
- fb = to_intel_framebuffer(crtc->primary->fb);
- max_size = plane_config->size;
+ fb = to_intel_framebuffer(crtc->primary->state->fb);
+ max_size = obj->base.size;
}
}
@@ -638,7 +638,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
pipe_name(intel_crtc->pipe),
cur_size, fb->base.pitches[0]);
- plane_config = NULL;
fb = NULL;
break;
}
@@ -659,7 +658,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
pipe_name(intel_crtc->pipe),
cur_size, max_size);
- plane_config = NULL;
fb = NULL;
break;
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (4 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 05/20] drm/i915: Do not use plane_config in intel_fbdev.c Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 10:11 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly Maarten Lankhorst
` (14 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Instead of doing ad-hoc checks we already have a way of checking
if the state is compatible or not. Use this to force a modeset.
Only during modesets, or with PIPE_CONFIG_QUIRK_INHERITED_MODE
we should check if a full modeset is really needed.
Fastboot will allow the adjust parameter to ignore some stuff
too, and it will fix up differences in state that are ignored
by the compare function.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 198 ++++++++++++++++++++++++-----------
1 file changed, 139 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8cd3a7eb1e30..eb7c2e2819b7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12277,19 +12277,6 @@ encoder_retry:
DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
- /* Check if we need to force a modeset */
- if (pipe_config->has_audio !=
- to_intel_crtc_state(crtc->state)->has_audio) {
- pipe_config->base.mode_changed = true;
- ret = drm_atomic_add_affected_planes(state, crtc);
- }
-
- /*
- * Note we have an issue here with infoframes: current code
- * only updates them on the full mode set path per hw
- * requirements. So here we should be checking for any
- * required changes and forcing a mode set.
- */
fail:
return ret;
}
@@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
base.head) \
if (mask & (1 <<(intel_crtc)->pipe))
+
+static bool
+intel_compare_m_n(unsigned int m, unsigned int n,
+ unsigned int m2, unsigned int n2)
+{
+ if (m == m2 && n == n2)
+ return true;
+
+ if (!m || !n || !m2 || !n2)
+ return false;
+
+ if (m > m2) {
+ while (m > m2) {
+ m >>= 1;
+ n >>= 1;
+ }
+ } else if (m < m2) {
+ while (m < m2) {
+ m2 >>= 1;
+ n2 >>= 1;
+ }
+ }
+
+ return m == m2 && n == n2;
+}
+
+static bool
+intel_compare_link_m_n(const struct intel_link_m_n *m_n,
+ const struct intel_link_m_n *m2_n2)
+{
+ if (m_n->tu == m2_n2->tu &&
+ intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
+ m2_n2->gmch_m, m2_n2->gmch_n) &&
+ intel_compare_m_n(m_n->link_m, m_n->link_n,
+ m2_n2->link_m, m2_n2->link_n))
+ return true;
+
+ return false;
+}
+
static bool
intel_pipe_config_compare(struct drm_device *dev,
struct intel_crtc_state *current_config,
- struct intel_crtc_state *pipe_config)
+ struct intel_crtc_state *pipe_config,
+ bool adjust)
{
+ bool ret = true;
+
+#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
+ do { \
+ if (!adjust) \
+ DRM_ERROR(fmt, ##__VA_ARGS__); \
+ else \
+ DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
+ } while (0)
+
#define PIPE_CONF_CHECK_X(name) \
if (current_config->name != pipe_config->name) { \
- DRM_ERROR("mismatch in " #name " " \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected 0x%08x, found 0x%08x)\n", \
current_config->name, \
pipe_config->name); \
- return false; \
+ ret = false; \
}
#define PIPE_CONF_CHECK_I(name) \
if (current_config->name != pipe_config->name) { \
- DRM_ERROR("mismatch in " #name " " \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %i, found %i)\n", \
current_config->name, \
pipe_config->name); \
- return false; \
+ ret = false; \
+ }
+
+#define PIPE_CONF_CHECK_M_N(name) \
+ if (!intel_compare_link_m_n(¤t_config->name, \
+ &pipe_config->name)) { \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+ "(expected tu %i gmch %i/%i link %i/%i, " \
+ "found tu %i, gmch %i/%i link %i/%i)\n", \
+ current_config->name.tu, \
+ current_config->name.gmch_m, \
+ current_config->name.gmch_n, \
+ current_config->name.link_m, \
+ current_config->name.link_n, \
+ pipe_config->name.tu, \
+ pipe_config->name.gmch_m, \
+ pipe_config->name.gmch_n, \
+ pipe_config->name.link_m, \
+ pipe_config->name.link_n); \
+ ret = false; \
+ }
+
+#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
+ if (!intel_compare_link_m_n(¤t_config->name, \
+ &pipe_config->name) && \
+ !intel_compare_link_m_n(¤t_config->alt_name, \
+ &pipe_config->name)) { \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+ "(expected tu %i gmch %i/%i link %i/%i, " \
+ "or tu %i gmch %i/%i link %i/%i, " \
+ "found tu %i, gmch %i/%i link %i/%i)\n", \
+ current_config->name.tu, \
+ current_config->name.gmch_m, \
+ current_config->name.gmch_n, \
+ current_config->name.link_m, \
+ current_config->name.link_n, \
+ current_config->alt_name.tu, \
+ current_config->alt_name.gmch_m, \
+ current_config->alt_name.gmch_n, \
+ current_config->alt_name.link_m, \
+ current_config->alt_name.link_n, \
+ pipe_config->name.tu, \
+ pipe_config->name.gmch_m, \
+ pipe_config->name.gmch_n, \
+ pipe_config->name.link_m, \
+ pipe_config->name.link_n); \
+ ret = false; \
}
/* This is required for BDW+ where there is only one set of registers for
@@ -12423,30 +12507,30 @@ intel_pipe_config_compare(struct drm_device *dev,
#define PIPE_CONF_CHECK_I_ALT(name, alt_name) \
if ((current_config->name != pipe_config->name) && \
(current_config->alt_name != pipe_config->name)) { \
- DRM_ERROR("mismatch in " #name " " \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %i or %i, found %i)\n", \
current_config->name, \
current_config->alt_name, \
pipe_config->name); \
- return false; \
+ ret = false; \
}
#define PIPE_CONF_CHECK_FLAGS(name, mask) \
if ((current_config->name ^ pipe_config->name) & (mask)) { \
- DRM_ERROR("mismatch in " #name "(" #mask ") " \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
"(expected %i, found %i)\n", \
current_config->name & (mask), \
pipe_config->name & (mask)); \
- return false; \
+ ret = false; \
}
#define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
- DRM_ERROR("mismatch in " #name " " \
+ INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
"(expected %i, found %i)\n", \
current_config->name, \
pipe_config->name); \
- return false; \
+ ret = false; \
}
#define PIPE_CONF_QUIRK(quirk) \
@@ -12456,35 +12540,18 @@ intel_pipe_config_compare(struct drm_device *dev,
PIPE_CONF_CHECK_I(has_pch_encoder);
PIPE_CONF_CHECK_I(fdi_lanes);
- PIPE_CONF_CHECK_I(fdi_m_n.gmch_m);
- PIPE_CONF_CHECK_I(fdi_m_n.gmch_n);
- PIPE_CONF_CHECK_I(fdi_m_n.link_m);
- PIPE_CONF_CHECK_I(fdi_m_n.link_n);
- PIPE_CONF_CHECK_I(fdi_m_n.tu);
+ PIPE_CONF_CHECK_M_N(fdi_m_n);
PIPE_CONF_CHECK_I(has_dp_encoder);
if (INTEL_INFO(dev)->gen < 8) {
- PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
- PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
- PIPE_CONF_CHECK_I(dp_m_n.link_m);
- PIPE_CONF_CHECK_I(dp_m_n.link_n);
- PIPE_CONF_CHECK_I(dp_m_n.tu);
-
- if (current_config->has_drrs) {
- PIPE_CONF_CHECK_I(dp_m2_n2.gmch_m);
- PIPE_CONF_CHECK_I(dp_m2_n2.gmch_n);
- PIPE_CONF_CHECK_I(dp_m2_n2.link_m);
- PIPE_CONF_CHECK_I(dp_m2_n2.link_n);
- PIPE_CONF_CHECK_I(dp_m2_n2.tu);
- }
- } else {
- PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_m, dp_m2_n2.gmch_m);
- PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_n, dp_m2_n2.gmch_n);
- PIPE_CONF_CHECK_I_ALT(dp_m_n.link_m, dp_m2_n2.link_m);
- PIPE_CONF_CHECK_I_ALT(dp_m_n.link_n, dp_m2_n2.link_n);
- PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu);
- }
+ PIPE_CONF_CHECK_M_N(dp_m_n);
+
+ PIPE_CONF_CHECK_I(has_drrs);
+ if (current_config->has_drrs)
+ PIPE_CONF_CHECK_M_N(dp_m2_n2);
+ } else
+ PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
@@ -12580,8 +12647,9 @@ intel_pipe_config_compare(struct drm_device *dev,
#undef PIPE_CONF_CHECK_FLAGS
#undef PIPE_CONF_CHECK_CLOCK_FUZZY
#undef PIPE_CONF_QUIRK
+#undef INTEL_ERR_OR_DBG_KMS
- return true;
+ return ret;
}
static void check_wm_state(struct drm_device *dev)
@@ -12773,8 +12841,11 @@ check_crtc_state(struct drm_device *dev)
"transitional active state does not match atomic hw state "
"(expected %i, found %i)\n", crtc->base.state->active, crtc->active);
- if (active &&
- !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
+ if (!active)
+ continue;
+
+ if (!intel_pipe_config_compare(dev, crtc->config,
+ &pipe_config, false)) {
I915_STATE_WARN(1, "pipe state doesn't match!\n");
intel_dump_pipe_config(crtc, &pipe_config,
"[hw state]");
@@ -13075,14 +13146,16 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
return ret;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ struct intel_crtc_state *pipe_config =
+ to_intel_crtc_state(crtc_state);
+
if (!crtc_state->enable) {
if (needs_modeset(crtc_state))
any_ms = true;
continue;
}
- if (to_intel_crtc_state(crtc_state)->quirks &
- PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
+ if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
ret = drm_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
@@ -13096,21 +13169,28 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
}
if (!needs_modeset(crtc_state)) {
+ if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
+ continue;
+
ret = drm_atomic_add_affected_connectors(state, crtc);
if (ret)
return ret;
}
- ret = intel_modeset_pipe_config(crtc,
- to_intel_crtc_state(crtc_state));
+ ret = intel_modeset_pipe_config(crtc, pipe_config);
if (ret)
return ret;
- if (needs_modeset(crtc_state))
- any_ms = true;
+ if (!intel_pipe_config_compare(state->dev,
+ to_intel_crtc_state(crtc->state),
+ pipe_config, true))
+ crtc_state->mode_changed = true;
+ else if (!needs_modeset(crtc_state))
+ continue;
+ any_ms = true;
intel_dump_pipe_config(to_intel_crtc(crtc),
- to_intel_crtc_state(crtc_state),
+ pipe_config,
"[modeset]");
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-07 7:08 ` [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare Maarten Lankhorst
@ 2015-07-07 10:11 ` Daniel Vetter
2015-07-08 8:38 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 10:11 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:17AM +0200, Maarten Lankhorst wrote:
> Instead of doing ad-hoc checks we already have a way of checking
> if the state is compatible or not. Use this to force a modeset.
>
> Only during modesets, or with PIPE_CONFIG_QUIRK_INHERITED_MODE
> we should check if a full modeset is really needed.
>
> Fastboot will allow the adjust parameter to ignore some stuff
> too, and it will fix up differences in state that are ignored
> by the compare function.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 198 ++++++++++++++++++++++++-----------
> 1 file changed, 139 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8cd3a7eb1e30..eb7c2e2819b7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12277,19 +12277,6 @@ encoder_retry:
> DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
> base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>
> - /* Check if we need to force a modeset */
> - if (pipe_config->has_audio !=
> - to_intel_crtc_state(crtc->state)->has_audio) {
> - pipe_config->base.mode_changed = true;
> - ret = drm_atomic_add_affected_planes(state, crtc);
> - }
> -
> - /*
> - * Note we have an issue here with infoframes: current code
> - * only updates them on the full mode set path per hw
> - * requirements. So here we should be checking for any
> - * required changes and forcing a mode set.
> - */
> fail:
> return ret;
> }
> @@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
> base.head) \
> if (mask & (1 <<(intel_crtc)->pipe))
>
> +
> +static bool
> +intel_compare_m_n(unsigned int m, unsigned int n,
> + unsigned int m2, unsigned int n2)
> +{
> + if (m == m2 && n == n2)
> + return true;
> +
> + if (!m || !n || !m2 || !n2)
> + return false;
> +
> + if (m > m2) {
> + while (m > m2) {
I think we need to make sure we don't reduce precision by eating low bits,
i.e.
while (m > m2 && !(m & 1) && !(n & 1)) {
> + m >>= 1;
> + n >>= 1;
> + }
> + } else if (m < m2) {
> + while (m < m2) {
> + m2 >>= 1;
> + n2 >>= 1;
> + }
> + }
> +
> + return m == m2 && n == n2;
> +}
> +
> +static bool
> +intel_compare_link_m_n(const struct intel_link_m_n *m_n,
> + const struct intel_link_m_n *m2_n2)
I think these need to take adjust as an agurment and check for exact match
(not just matching ratio), like before.
> +{
> + if (m_n->tu == m2_n2->tu &&
> + intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
> + m2_n2->gmch_m, m2_n2->gmch_n) &&
> + intel_compare_m_n(m_n->link_m, m_n->link_n,
> + m2_n2->link_m, m2_n2->link_n))
> + return true;
> +
> + return false;
> +}
> +
> static bool
> intel_pipe_config_compare(struct drm_device *dev,
> struct intel_crtc_state *current_config,
> - struct intel_crtc_state *pipe_config)
> + struct intel_crtc_state *pipe_config,
> + bool adjust)
> {
> + bool ret = true;
> +
> +#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
> + do { \
> + if (!adjust) \
> + DRM_ERROR(fmt, ##__VA_ARGS__); \
> + else \
> + DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
> + } while (0)
> +
> #define PIPE_CONF_CHECK_X(name) \
> if (current_config->name != pipe_config->name) { \
> - DRM_ERROR("mismatch in " #name " " \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> "(expected 0x%08x, found 0x%08x)\n", \
> current_config->name, \
> pipe_config->name); \
> - return false; \
> + ret = false; \
> }
>
> #define PIPE_CONF_CHECK_I(name) \
> if (current_config->name != pipe_config->name) { \
> - DRM_ERROR("mismatch in " #name " " \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> "(expected %i, found %i)\n", \
> current_config->name, \
> pipe_config->name); \
> - return false; \
> + ret = false; \
> + }
> +
> +#define PIPE_CONF_CHECK_M_N(name) \
> + if (!intel_compare_link_m_n(¤t_config->name, \
> + &pipe_config->name)) { \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> + "(expected tu %i gmch %i/%i link %i/%i, " \
> + "found tu %i, gmch %i/%i link %i/%i)\n", \
> + current_config->name.tu, \
> + current_config->name.gmch_m, \
> + current_config->name.gmch_n, \
> + current_config->name.link_m, \
> + current_config->name.link_n, \
> + pipe_config->name.tu, \
> + pipe_config->name.gmch_m, \
> + pipe_config->name.gmch_n, \
> + pipe_config->name.link_m, \
> + pipe_config->name.link_n); \
> + ret = false; \
> + }
> +
> +#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
> + if (!intel_compare_link_m_n(¤t_config->name, \
> + &pipe_config->name) && \
> + !intel_compare_link_m_n(¤t_config->alt_name, \
> + &pipe_config->name)) { \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> + "(expected tu %i gmch %i/%i link %i/%i, " \
> + "or tu %i gmch %i/%i link %i/%i, " \
> + "found tu %i, gmch %i/%i link %i/%i)\n", \
> + current_config->name.tu, \
> + current_config->name.gmch_m, \
> + current_config->name.gmch_n, \
> + current_config->name.link_m, \
> + current_config->name.link_n, \
> + current_config->alt_name.tu, \
> + current_config->alt_name.gmch_m, \
> + current_config->alt_name.gmch_n, \
> + current_config->alt_name.link_m, \
> + current_config->alt_name.link_n, \
> + pipe_config->name.tu, \
> + pipe_config->name.gmch_m, \
> + pipe_config->name.gmch_n, \
> + pipe_config->name.link_m, \
> + pipe_config->name.link_n); \
> + ret = false; \
> }
>
> /* This is required for BDW+ where there is only one set of registers for
> @@ -12423,30 +12507,30 @@ intel_pipe_config_compare(struct drm_device *dev,
> #define PIPE_CONF_CHECK_I_ALT(name, alt_name) \
> if ((current_config->name != pipe_config->name) && \
> (current_config->alt_name != pipe_config->name)) { \
> - DRM_ERROR("mismatch in " #name " " \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> "(expected %i or %i, found %i)\n", \
> current_config->name, \
> current_config->alt_name, \
> pipe_config->name); \
> - return false; \
> + ret = false; \
> }
>
> #define PIPE_CONF_CHECK_FLAGS(name, mask) \
> if ((current_config->name ^ pipe_config->name) & (mask)) { \
> - DRM_ERROR("mismatch in " #name "(" #mask ") " \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
> "(expected %i, found %i)\n", \
> current_config->name & (mask), \
> pipe_config->name & (mask)); \
> - return false; \
> + ret = false; \
> }
>
> #define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
> if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
> - DRM_ERROR("mismatch in " #name " " \
> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
> "(expected %i, found %i)\n", \
> current_config->name, \
> pipe_config->name); \
> - return false; \
> + ret = false; \
> }
>
> #define PIPE_CONF_QUIRK(quirk) \
> @@ -12456,35 +12540,18 @@ intel_pipe_config_compare(struct drm_device *dev,
>
> PIPE_CONF_CHECK_I(has_pch_encoder);
> PIPE_CONF_CHECK_I(fdi_lanes);
> - PIPE_CONF_CHECK_I(fdi_m_n.gmch_m);
> - PIPE_CONF_CHECK_I(fdi_m_n.gmch_n);
> - PIPE_CONF_CHECK_I(fdi_m_n.link_m);
> - PIPE_CONF_CHECK_I(fdi_m_n.link_n);
> - PIPE_CONF_CHECK_I(fdi_m_n.tu);
> + PIPE_CONF_CHECK_M_N(fdi_m_n);
>
> PIPE_CONF_CHECK_I(has_dp_encoder);
>
> if (INTEL_INFO(dev)->gen < 8) {
> - PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
> - PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
> - PIPE_CONF_CHECK_I(dp_m_n.link_m);
> - PIPE_CONF_CHECK_I(dp_m_n.link_n);
> - PIPE_CONF_CHECK_I(dp_m_n.tu);
> -
> - if (current_config->has_drrs) {
> - PIPE_CONF_CHECK_I(dp_m2_n2.gmch_m);
> - PIPE_CONF_CHECK_I(dp_m2_n2.gmch_n);
> - PIPE_CONF_CHECK_I(dp_m2_n2.link_m);
> - PIPE_CONF_CHECK_I(dp_m2_n2.link_n);
> - PIPE_CONF_CHECK_I(dp_m2_n2.tu);
> - }
> - } else {
> - PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_m, dp_m2_n2.gmch_m);
> - PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_n, dp_m2_n2.gmch_n);
> - PIPE_CONF_CHECK_I_ALT(dp_m_n.link_m, dp_m2_n2.link_m);
> - PIPE_CONF_CHECK_I_ALT(dp_m_n.link_n, dp_m2_n2.link_n);
> - PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu);
> - }
> + PIPE_CONF_CHECK_M_N(dp_m_n);
> +
> + PIPE_CONF_CHECK_I(has_drrs);
> + if (current_config->has_drrs)
> + PIPE_CONF_CHECK_M_N(dp_m2_n2);
> + } else
> + PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
>
> PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
> PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
> @@ -12580,8 +12647,9 @@ intel_pipe_config_compare(struct drm_device *dev,
> #undef PIPE_CONF_CHECK_FLAGS
> #undef PIPE_CONF_CHECK_CLOCK_FUZZY
> #undef PIPE_CONF_QUIRK
> +#undef INTEL_ERR_OR_DBG_KMS
>
> - return true;
> + return ret;
> }
>
> static void check_wm_state(struct drm_device *dev)
> @@ -12773,8 +12841,11 @@ check_crtc_state(struct drm_device *dev)
> "transitional active state does not match atomic hw state "
> "(expected %i, found %i)\n", crtc->base.state->active, crtc->active);
>
> - if (active &&
> - !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
> + if (!active)
> + continue;
> +
> + if (!intel_pipe_config_compare(dev, crtc->config,
> + &pipe_config, false)) {
> I915_STATE_WARN(1, "pipe state doesn't match!\n");
> intel_dump_pipe_config(crtc, &pipe_config,
> "[hw state]");
> @@ -13075,14 +13146,16 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
> return ret;
>
> for_each_crtc_in_state(state, crtc, crtc_state, i) {
> + struct intel_crtc_state *pipe_config =
> + to_intel_crtc_state(crtc_state);
> +
> if (!crtc_state->enable) {
> if (needs_modeset(crtc_state))
> any_ms = true;
> continue;
> }
>
> - if (to_intel_crtc_state(crtc_state)->quirks &
> - PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> + if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> ret = drm_atomic_add_affected_planes(state, crtc);
> if (ret)
> return ret;
> @@ -13096,21 +13169,28 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
> }
>
> if (!needs_modeset(crtc_state)) {
> + if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
> + continue;
double negative is harder to read ... what about:
if (!needs_modeset && !INHERITED_MODE)
continue;
And then just unconditionally doing the
add_affected_connectors? It'll be redundant almost always,
but it also won't really matter since it'll be fast.
> +
> ret = drm_atomic_add_affected_connectors(state, crtc);
> if (ret)
> return ret;
> }
>
> - ret = intel_modeset_pipe_config(crtc,
> - to_intel_crtc_state(crtc_state));
> + ret = intel_modeset_pipe_config(crtc, pipe_config);
> if (ret)
> return ret;
>
> - if (needs_modeset(crtc_state))
> - any_ms = true;
> + if (!intel_pipe_config_compare(state->dev,
> + to_intel_crtc_state(crtc->state),
> + pipe_config, true))
> + crtc_state->mode_changed = true;
> + else if (!needs_modeset(crtc_state))
> + continue;
Hm for bebugging I'd always dump the pipe config, even if we notice that
fastboot is posible. Perhaps changes the "[modeset]" below to a
needs_modset() ? "[modeset: full]" : "[modeset: fast]"
>
> + any_ms = true;
> intel_dump_pipe_config(to_intel_crtc(crtc),
> - to_intel_crtc_state(crtc_state),
> + pipe_config,
> "[modeset]");
> }
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-07 10:11 ` Daniel Vetter
@ 2015-07-08 8:38 ` Maarten Lankhorst
2015-07-08 9:09 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 8:38 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 12:11 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:17AM +0200, Maarten Lankhorst wrote:
>> Instead of doing ad-hoc checks we already have a way of checking
>> if the state is compatible or not. Use this to force a modeset.
>>
>> Only during modesets, or with PIPE_CONFIG_QUIRK_INHERITED_MODE
>> we should check if a full modeset is really needed.
>>
>> Fastboot will allow the adjust parameter to ignore some stuff
>> too, and it will fix up differences in state that are ignored
>> by the compare function.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_display.c | 198 ++++++++++++++++++++++++-----------
>> 1 file changed, 139 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 8cd3a7eb1e30..eb7c2e2819b7 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -12277,19 +12277,6 @@ encoder_retry:
>> DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
>> base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>>
>> - /* Check if we need to force a modeset */
>> - if (pipe_config->has_audio !=
>> - to_intel_crtc_state(crtc->state)->has_audio) {
>> - pipe_config->base.mode_changed = true;
>> - ret = drm_atomic_add_affected_planes(state, crtc);
>> - }
>> -
>> - /*
>> - * Note we have an issue here with infoframes: current code
>> - * only updates them on the full mode set path per hw
>> - * requirements. So here we should be checking for any
>> - * required changes and forcing a mode set.
>> - */
>> fail:
>> return ret;
>> }
>> @@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
>> base.head) \
>> if (mask & (1 <<(intel_crtc)->pipe))
>>
>> +
>> +static bool
>> +intel_compare_m_n(unsigned int m, unsigned int n,
>> + unsigned int m2, unsigned int n2)
>> +{
>> + if (m == m2 && n == n2)
>> + return true;
>> +
>> + if (!m || !n || !m2 || !n2)
>> + return false;
>> +
>> + if (m > m2) {
>> + while (m > m2) {
> I think we need to make sure we don't reduce precision by eating low bits,
> i.e.
> while (m > m2 && !(m & 1) && !(n & 1)) {
Could be useful, lets hope everyone rounds in the same way. :)
>> + m >>= 1;
>> + n >>= 1;
>> + }
>> + } else if (m < m2) {
>> + while (m < m2) {
>> + m2 >>= 1;
>> + n2 >>= 1;
>> + }
>> + }
>> +
>> + return m == m2 && n == n2;
>> +}
>> +
>> +static bool
>> +intel_compare_link_m_n(const struct intel_link_m_n *m_n,
>> + const struct intel_link_m_n *m2_n2)
> I think these need to take adjust as an agurment and check for exact match
> (not just matching ratio), like before.
I just implemented it, then remembered why I didn't.
It will cause a failure in intel_modeset_check_state.
>> +{
>> + if (m_n->tu == m2_n2->tu &&
>> + intel_compare_m_n(m_n->gmch_m, m_n->gmch_n,
>> + m2_n2->gmch_m, m2_n2->gmch_n) &&
>> + intel_compare_m_n(m_n->link_m, m_n->link_n,
>> + m2_n2->link_m, m2_n2->link_n))
>> + return true;
>> +
>> + return false;
>> +}
>> +
>> static bool
>> intel_pipe_config_compare(struct drm_device *dev,
>> struct intel_crtc_state *current_config,
>> - struct intel_crtc_state *pipe_config)
>> + struct intel_crtc_state *pipe_config,
>> + bool adjust)
>> {
>> + bool ret = true;
>> +
>> +#define INTEL_ERR_OR_DBG_KMS(fmt, ...) \
>> + do { \
>> + if (!adjust) \
>> + DRM_ERROR(fmt, ##__VA_ARGS__); \
>> + else \
>> + DRM_DEBUG_KMS(fmt, ##__VA_ARGS__); \
>> + } while (0)
>> +
>> #define PIPE_CONF_CHECK_X(name) \
>> if (current_config->name != pipe_config->name) { \
>> - DRM_ERROR("mismatch in " #name " " \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> "(expected 0x%08x, found 0x%08x)\n", \
>> current_config->name, \
>> pipe_config->name); \
>> - return false; \
>> + ret = false; \
>> }
>>
>> #define PIPE_CONF_CHECK_I(name) \
>> if (current_config->name != pipe_config->name) { \
>> - DRM_ERROR("mismatch in " #name " " \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> "(expected %i, found %i)\n", \
>> current_config->name, \
>> pipe_config->name); \
>> - return false; \
>> + ret = false; \
>> + }
>> +
>> +#define PIPE_CONF_CHECK_M_N(name) \
>> + if (!intel_compare_link_m_n(¤t_config->name, \
>> + &pipe_config->name)) { \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> + "(expected tu %i gmch %i/%i link %i/%i, " \
>> + "found tu %i, gmch %i/%i link %i/%i)\n", \
>> + current_config->name.tu, \
>> + current_config->name.gmch_m, \
>> + current_config->name.gmch_n, \
>> + current_config->name.link_m, \
>> + current_config->name.link_n, \
>> + pipe_config->name.tu, \
>> + pipe_config->name.gmch_m, \
>> + pipe_config->name.gmch_n, \
>> + pipe_config->name.link_m, \
>> + pipe_config->name.link_n); \
>> + ret = false; \
>> + }
>> +
>> +#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) \
>> + if (!intel_compare_link_m_n(¤t_config->name, \
>> + &pipe_config->name) && \
>> + !intel_compare_link_m_n(¤t_config->alt_name, \
>> + &pipe_config->name)) { \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> + "(expected tu %i gmch %i/%i link %i/%i, " \
>> + "or tu %i gmch %i/%i link %i/%i, " \
>> + "found tu %i, gmch %i/%i link %i/%i)\n", \
>> + current_config->name.tu, \
>> + current_config->name.gmch_m, \
>> + current_config->name.gmch_n, \
>> + current_config->name.link_m, \
>> + current_config->name.link_n, \
>> + current_config->alt_name.tu, \
>> + current_config->alt_name.gmch_m, \
>> + current_config->alt_name.gmch_n, \
>> + current_config->alt_name.link_m, \
>> + current_config->alt_name.link_n, \
>> + pipe_config->name.tu, \
>> + pipe_config->name.gmch_m, \
>> + pipe_config->name.gmch_n, \
>> + pipe_config->name.link_m, \
>> + pipe_config->name.link_n); \
>> + ret = false; \
>> }
>>
>> /* This is required for BDW+ where there is only one set of registers for
>> @@ -12423,30 +12507,30 @@ intel_pipe_config_compare(struct drm_device *dev,
>> #define PIPE_CONF_CHECK_I_ALT(name, alt_name) \
>> if ((current_config->name != pipe_config->name) && \
>> (current_config->alt_name != pipe_config->name)) { \
>> - DRM_ERROR("mismatch in " #name " " \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> "(expected %i or %i, found %i)\n", \
>> current_config->name, \
>> current_config->alt_name, \
>> pipe_config->name); \
>> - return false; \
>> + ret = false; \
>> }
>>
>> #define PIPE_CONF_CHECK_FLAGS(name, mask) \
>> if ((current_config->name ^ pipe_config->name) & (mask)) { \
>> - DRM_ERROR("mismatch in " #name "(" #mask ") " \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name "(" #mask ") " \
>> "(expected %i, found %i)\n", \
>> current_config->name & (mask), \
>> pipe_config->name & (mask)); \
>> - return false; \
>> + ret = false; \
>> }
>>
>> #define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
>> if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
>> - DRM_ERROR("mismatch in " #name " " \
>> + INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
>> "(expected %i, found %i)\n", \
>> current_config->name, \
>> pipe_config->name); \
>> - return false; \
>> + ret = false; \
>> }
>>
>> #define PIPE_CONF_QUIRK(quirk) \
>> @@ -12456,35 +12540,18 @@ intel_pipe_config_compare(struct drm_device *dev,
>>
>> PIPE_CONF_CHECK_I(has_pch_encoder);
>> PIPE_CONF_CHECK_I(fdi_lanes);
>> - PIPE_CONF_CHECK_I(fdi_m_n.gmch_m);
>> - PIPE_CONF_CHECK_I(fdi_m_n.gmch_n);
>> - PIPE_CONF_CHECK_I(fdi_m_n.link_m);
>> - PIPE_CONF_CHECK_I(fdi_m_n.link_n);
>> - PIPE_CONF_CHECK_I(fdi_m_n.tu);
>> + PIPE_CONF_CHECK_M_N(fdi_m_n);
>>
>> PIPE_CONF_CHECK_I(has_dp_encoder);
>>
>> if (INTEL_INFO(dev)->gen < 8) {
>> - PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
>> - PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
>> - PIPE_CONF_CHECK_I(dp_m_n.link_m);
>> - PIPE_CONF_CHECK_I(dp_m_n.link_n);
>> - PIPE_CONF_CHECK_I(dp_m_n.tu);
>> -
>> - if (current_config->has_drrs) {
>> - PIPE_CONF_CHECK_I(dp_m2_n2.gmch_m);
>> - PIPE_CONF_CHECK_I(dp_m2_n2.gmch_n);
>> - PIPE_CONF_CHECK_I(dp_m2_n2.link_m);
>> - PIPE_CONF_CHECK_I(dp_m2_n2.link_n);
>> - PIPE_CONF_CHECK_I(dp_m2_n2.tu);
>> - }
>> - } else {
>> - PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_m, dp_m2_n2.gmch_m);
>> - PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_n, dp_m2_n2.gmch_n);
>> - PIPE_CONF_CHECK_I_ALT(dp_m_n.link_m, dp_m2_n2.link_m);
>> - PIPE_CONF_CHECK_I_ALT(dp_m_n.link_n, dp_m2_n2.link_n);
>> - PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu);
>> - }
>> + PIPE_CONF_CHECK_M_N(dp_m_n);
>> +
>> + PIPE_CONF_CHECK_I(has_drrs);
>> + if (current_config->has_drrs)
>> + PIPE_CONF_CHECK_M_N(dp_m2_n2);
>> + } else
>> + PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
>>
>> PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
>> PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
>> @@ -12580,8 +12647,9 @@ intel_pipe_config_compare(struct drm_device *dev,
>> #undef PIPE_CONF_CHECK_FLAGS
>> #undef PIPE_CONF_CHECK_CLOCK_FUZZY
>> #undef PIPE_CONF_QUIRK
>> +#undef INTEL_ERR_OR_DBG_KMS
>>
>> - return true;
>> + return ret;
>> }
>>
>> static void check_wm_state(struct drm_device *dev)
>> @@ -12773,8 +12841,11 @@ check_crtc_state(struct drm_device *dev)
>> "transitional active state does not match atomic hw state "
>> "(expected %i, found %i)\n", crtc->base.state->active, crtc->active);
>>
>> - if (active &&
>> - !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
>> + if (!active)
>> + continue;
>> +
>> + if (!intel_pipe_config_compare(dev, crtc->config,
>> + &pipe_config, false)) {
>> I915_STATE_WARN(1, "pipe state doesn't match!\n");
>> intel_dump_pipe_config(crtc, &pipe_config,
>> "[hw state]");
>> @@ -13075,14 +13146,16 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
>> return ret;
>>
>> for_each_crtc_in_state(state, crtc, crtc_state, i) {
>> + struct intel_crtc_state *pipe_config =
>> + to_intel_crtc_state(crtc_state);
>> +
>> if (!crtc_state->enable) {
>> if (needs_modeset(crtc_state))
>> any_ms = true;
>> continue;
>> }
>>
>> - if (to_intel_crtc_state(crtc_state)->quirks &
>> - PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>> + if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>> ret = drm_atomic_add_affected_planes(state, crtc);
>> if (ret)
>> return ret;
>> @@ -13096,21 +13169,28 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
>> }
>>
>> if (!needs_modeset(crtc_state)) {
>> + if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
>> + continue;
> double negative is harder to read ... what about:
>
> if (!needs_modeset && !INHERITED_MODE)
> continue;
>
> And then just unconditionally doing the
> add_affected_connectors? It'll be redundant almost always,
> but it also won't really matter since it'll be fast.
Ok.
>> +
>> ret = drm_atomic_add_affected_connectors(state, crtc);
>> if (ret)
>> return ret;
>> }
>>
>> - ret = intel_modeset_pipe_config(crtc,
>> - to_intel_crtc_state(crtc_state));
>> + ret = intel_modeset_pipe_config(crtc, pipe_config);
>> if (ret)
>> return ret;
>>
>> - if (needs_modeset(crtc_state))
>> - any_ms = true;
>> + if (!intel_pipe_config_compare(state->dev,
>> + to_intel_crtc_state(crtc->state),
>> + pipe_config, true))
>> + crtc_state->mode_changed = true;
>> + else if (!needs_modeset(crtc_state))
>> + continue;
> Hm for bebugging I'd always dump the pipe config, even if we notice that
> fastboot is posible. Perhaps changes the "[modeset]" below to a
>
> needs_modset() ? "[modeset: full]" : "[modeset: fast]"
Ok.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-08 8:38 ` Maarten Lankhorst
@ 2015-07-08 9:09 ` Daniel Vetter
2015-07-08 9:18 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 9:09 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Wed, Jul 08, 2015 at 10:38:33AM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 12:11 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:17AM +0200, Maarten Lankhorst wrote:
> >> @@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
> >> base.head) \
> >> if (mask & (1 <<(intel_crtc)->pipe))
> >>
> >> +
> >> +static bool
> >> +intel_compare_m_n(unsigned int m, unsigned int n,
> >> + unsigned int m2, unsigned int n2)
> >> +{
> >> + if (m == m2 && n == n2)
> >> + return true;
> >> +
> >> + if (!m || !n || !m2 || !n2)
> >> + return false;
> >> +
> >> + if (m > m2) {
> >> + while (m > m2) {
> > I think we need to make sure we don't reduce precision by eating low bits,
> > i.e.
> > while (m > m2 && !(m & 1) && !(n & 1)) {
> Could be useful, lets hope everyone rounds in the same way. :)
> >> + m >>= 1;
> >> + n >>= 1;
> >> + }
> >> + } else if (m < m2) {
> >> + while (m < m2) {
> >> + m2 >>= 1;
> >> + n2 >>= 1;
> >> + }
> >> + }
> >> +
> >> + return m == m2 && n == n2;
> >> +}
> >> +
> >> +static bool
> >> +intel_compare_link_m_n(const struct intel_link_m_n *m_n,
> >> + const struct intel_link_m_n *m2_n2)
> > I think these need to take adjust as an agurment and check for exact match
> > (not just matching ratio), like before.
> I just implemented it, then remembered why I didn't.
>
> It will cause a failure in intel_modeset_check_state.
That shouldn't happen. I guess the bug is that adjust doesn't live up to
it's name and doesn't copy the current value over to the new config if
they're compatible?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-08 9:09 ` Daniel Vetter
@ 2015-07-08 9:18 ` Maarten Lankhorst
2015-07-08 9:33 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 9:18 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 08-07-15 om 11:09 schreef Daniel Vetter:
> On Wed, Jul 08, 2015 at 10:38:33AM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 12:11 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 09:08:17AM +0200, Maarten Lankhorst wrote:
>>>> @@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
>>>> base.head) \
>>>> if (mask & (1 <<(intel_crtc)->pipe))
>>>>
>>>> +
>>>> +static bool
>>>> +intel_compare_m_n(unsigned int m, unsigned int n,
>>>> + unsigned int m2, unsigned int n2)
>>>> +{
>>>> + if (m == m2 && n == n2)
>>>> + return true;
>>>> +
>>>> + if (!m || !n || !m2 || !n2)
>>>> + return false;
>>>> +
>>>> + if (m > m2) {
>>>> + while (m > m2) {
>>> I think we need to make sure we don't reduce precision by eating low bits,
>>> i.e.
>>> while (m > m2 && !(m & 1) && !(n & 1)) {
>> Could be useful, lets hope everyone rounds in the same way. :)
>>>> + m >>= 1;
>>>> + n >>= 1;
>>>> + }
>>>> + } else if (m < m2) {
>>>> + while (m < m2) {
>>>> + m2 >>= 1;
>>>> + n2 >>= 1;
>>>> + }
>>>> + }
>>>> +
>>>> + return m == m2 && n == n2;
>>>> +}
>>>> +
>>>> +static bool
>>>> +intel_compare_link_m_n(const struct intel_link_m_n *m_n,
>>>> + const struct intel_link_m_n *m2_n2)
>>> I think these need to take adjust as an agurment and check for exact match
>>> (not just matching ratio), like before.
>> I just implemented it, then remembered why I didn't.
>>
>> It will cause a failure in intel_modeset_check_state.
> That shouldn't happen. I guess the bug is that adjust doesn't live up to
> it's name and doesn't copy the current value over to the new config if
> they're compatible?
It's a compare function, I didn't want to do adjustments in it and leaving it as a multiple is harmless.
In case of gen >= 8 it might even fix itself through intel_dp_set_drrs_state.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare.
2015-07-08 9:18 ` Maarten Lankhorst
@ 2015-07-08 9:33 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 9:33 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Wed, Jul 08, 2015 at 11:18:27AM +0200, Maarten Lankhorst wrote:
> Op 08-07-15 om 11:09 schreef Daniel Vetter:
> > On Wed, Jul 08, 2015 at 10:38:33AM +0200, Maarten Lankhorst wrote:
> >> Op 07-07-15 om 12:11 schreef Daniel Vetter:
> >>> On Tue, Jul 07, 2015 at 09:08:17AM +0200, Maarten Lankhorst wrote:
> >>>> @@ -12392,27 +12379,124 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
> >>>> base.head) \
> >>>> if (mask & (1 <<(intel_crtc)->pipe))
> >>>>
> >>>> +
> >>>> +static bool
> >>>> +intel_compare_m_n(unsigned int m, unsigned int n,
> >>>> + unsigned int m2, unsigned int n2)
> >>>> +{
> >>>> + if (m == m2 && n == n2)
> >>>> + return true;
> >>>> +
> >>>> + if (!m || !n || !m2 || !n2)
> >>>> + return false;
> >>>> +
> >>>> + if (m > m2) {
> >>>> + while (m > m2) {
> >>> I think we need to make sure we don't reduce precision by eating low bits,
> >>> i.e.
> >>> while (m > m2 && !(m & 1) && !(n & 1)) {
> >> Could be useful, lets hope everyone rounds in the same way. :)
> >>>> + m >>= 1;
> >>>> + n >>= 1;
> >>>> + }
> >>>> + } else if (m < m2) {
> >>>> + while (m < m2) {
> >>>> + m2 >>= 1;
> >>>> + n2 >>= 1;
> >>>> + }
> >>>> + }
> >>>> +
> >>>> + return m == m2 && n == n2;
> >>>> +}
> >>>> +
> >>>> +static bool
> >>>> +intel_compare_link_m_n(const struct intel_link_m_n *m_n,
> >>>> + const struct intel_link_m_n *m2_n2)
> >>> I think these need to take adjust as an agurment and check for exact match
> >>> (not just matching ratio), like before.
> >> I just implemented it, then remembered why I didn't.
> >>
> >> It will cause a failure in intel_modeset_check_state.
> > That shouldn't happen. I guess the bug is that adjust doesn't live up to
> > it's name and doesn't copy the current value over to the new config if
> > they're compatible?
> It's a compare function, I didn't want to do adjustments in it and leaving it as a multiple is harmless.
> In case of gen >= 8 it might even fix itself through intel_dp_set_drrs_state.
Well pass it the bool adjust like for config_compare. I think in general
(i.e. when it's not too much work, which isn't the case here) doing exact
matches for hw/sw state checks is the right approach.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (5 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 06/20] drm/i915: Allow fuzzy matching in pipe_config_compare Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 11:16 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 08/20] drm/i915: fill in more mode members Maarten Lankhorst
` (13 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Make sure the primary plane is set up correctly. This is done by
setting plane_state->src and plane_state->crtc.
All non-primary planes get disabled.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_atomic.c | 7 --
drivers/gpu/drm/i915/intel_display.c | 167 +++++++++++++----------------------
drivers/gpu/drm/i915/intel_drv.h | 2 -
3 files changed, 60 insertions(+), 116 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 429677a111d5..b593612a917d 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -98,13 +98,6 @@ int intel_atomic_check(struct drm_device *dev,
return -EINVAL;
}
- if (crtc_state &&
- crtc_state->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
- ret = drm_atomic_add_affected_planes(state, &nuclear_crtc->base);
- if (ret)
- return ret;
- }
-
ret = drm_atomic_helper_check_planes(dev, state);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index eb7c2e2819b7..fa1102392eca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -109,6 +109,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
struct intel_crtc_state *crtc_state);
static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
int num_connectors);
+static void intel_pre_disable_primary(struct drm_crtc *crtc);
static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
{
@@ -2582,11 +2583,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *c;
- struct intel_crtc *i;
struct drm_i915_gem_object *obj;
- struct drm_plane *primary = intel_crtc->base.primary;
struct drm_framebuffer *fb;
+ struct drm_plane *primary = intel_crtc->base.primary;
+ struct intel_plane *p;
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(primary->state);
if (!plane_config->fb)
return;
@@ -2602,16 +2604,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
* Failed to alloc the obj, check to see if we should share
* an fb with another CRTC instead
*/
- for_each_crtc(dev, c) {
- i = to_intel_crtc(c);
-
- if (c == &intel_crtc->base)
- continue;
-
- if (!i->active)
+ for_each_intel_plane(dev, p) {
+ if (p->base.type != DRM_PLANE_TYPE_PRIMARY)
continue;
- fb = c->primary->fb;
+ fb = p->base.state->fb;
if (!fb)
continue;
@@ -2622,18 +2619,28 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
}
}
+ intel_pre_disable_primary(&intel_crtc->base);
+ to_intel_plane(primary)->disable_plane(primary, &intel_crtc->base);
+
return;
valid_fb:
+ drm_framebuffer_reference(fb);
+ primary->fb = plane_state->base.fb = fb;
+ plane_state->base.crtc = primary->crtc = &intel_crtc->base;
+
+ plane_state->base.src_x = plane_state->base.src_y = 0;
+ plane_state->base.src_w = fb->width << 16;
+ plane_state->base.src_h = fb->height << 16;
+
+ plane_state->base.crtc_x = plane_state->base.src_y = 0;
+ plane_state->base.crtc_w = fb->width;
+ plane_state->base.crtc_h = fb->height;
+
+ plane_state->visible = true;
obj = intel_fb_obj(fb);
if (obj->tiling_mode != I915_TILING_NONE)
dev_priv->preserve_bios_swizzle = true;
-
- primary->fb = fb;
- primary->crtc = primary->state->crtc = &intel_crtc->base;
- update_state_fb(primary);
- intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
- obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
}
static void i9xx_update_primary_plane(struct drm_crtc *crtc,
@@ -11761,34 +11768,6 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
return true;
}
-static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
- struct drm_crtc_state *crtc_state)
-{
- struct intel_crtc_state *pipe_config =
- to_intel_crtc_state(crtc_state);
- struct drm_plane *p;
- unsigned visible_mask = 0;
-
- drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
- struct drm_plane_state *plane_state =
- drm_atomic_get_existing_plane_state(crtc_state->state, p);
-
- if (WARN_ON(!plane_state))
- continue;
-
- if (!plane_state->fb)
- crtc_state->plane_mask &=
- ~(1 << drm_plane_index(p));
- else if (to_intel_plane_state(plane_state)->visible)
- visible_mask |= 1 << drm_plane_index(p);
- }
-
- if (!visible_mask)
- return;
-
- pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
-}
-
static int intel_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_crtc_state *crtc_state)
{
@@ -11810,10 +11789,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
"[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
idx, crtc->state->active, intel_crtc->active);
- /* plane mask is fixed up after all initial planes are calculated */
- if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
- intel_crtc_check_initial_planes(crtc, crtc_state);
-
if (mode_changed && !crtc_state->active)
intel_crtc->atomic.update_wm_post = true;
@@ -13155,19 +13130,6 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
continue;
}
- if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
- ret = drm_atomic_add_affected_planes(state, crtc);
- if (ret)
- return ret;
-
- /*
- * We ought to handle i915.fastboot here.
- * If no modeset is required and the primary plane has
- * a fb, update the members of crtc_state as needed,
- * and run the necessary updates during vblank evasion.
- */
- }
-
if (!needs_modeset(crtc_state)) {
if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
continue;
@@ -15149,25 +15111,30 @@ void intel_modeset_init(struct drm_device *dev)
drm_modeset_unlock_all(dev);
for_each_intel_crtc(dev, crtc) {
- if (!crtc->active)
+ struct intel_initial_plane_config plane_config;
+ struct drm_plane *plane;
+
+ if (!crtc->base.state->active)
continue;
+ /* disable all non-primary planes */
+ drm_for_each_plane_mask(plane, dev,
+ crtc->base.state->plane_mask)
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ to_intel_plane(plane)->disable_plane(plane, &crtc->base);
+
+ crtc->base.state->plane_mask &=
+ 1 << drm_plane_index(crtc->base.primary);
+
+ plane_config.fb = NULL;
+ dev_priv->display.get_initial_plane_config(crtc,
+ &plane_config);
+
/*
- * Note that reserving the BIOS fb up front prevents us
- * from stuffing other stolen allocations like the ring
- * on top. This prevents some ugliness at boot time, and
- * can even allow for smooth boot transitions if the BIOS
- * fb is large enough for the active pipe configuration.
+ * If the fb is shared between multiple heads, we'll
+ * just get the first one.
*/
- if (dev_priv->display.get_initial_plane_config) {
- dev_priv->display.get_initial_plane_config(crtc,
- &crtc->plane_config);
- /*
- * If the fb is shared between multiple heads, we'll
- * just get the first one.
- */
- intel_find_initial_plane_obj(crtc, &crtc->plane_config);
- }
+ intel_find_initial_plane_obj(crtc, &plane_config);
}
}
@@ -15404,47 +15371,30 @@ static void readout_plane_state(struct intel_crtc *crtc,
struct intel_plane *p;
struct drm_plane_state *drm_plane_state;
bool active = crtc_state->base.active;
+ bool wrong_plane;
- if (active) {
- crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
-
- /* apply to previous sw state too */
- to_intel_crtc_state(crtc->base.state)->quirks |=
- PIPE_CONFIG_QUIRK_INITIAL_PLANES;
- }
+ wrong_plane = active && !intel_check_plane_mapping(crtc);
+ if (wrong_plane)
+ crtc->pipe = !crtc->pipe;
for_each_intel_plane(crtc->base.dev, p) {
- bool visible = active;
-
if (crtc->pipe != p->pipe)
continue;
drm_plane_state = p->base.state;
- /* Plane scaler state is not touched here. The first atomic
- * commit will restore all plane scalers to its old state.
- */
-
- if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
- visible = primary_get_hw_state(crtc);
- to_intel_plane_state(drm_plane_state)->visible = visible;
- } else {
- /*
- * unknown state, assume it's off to force a transition
- * to on when calculating state changes.
- */
+ if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
+ to_intel_plane_state(drm_plane_state)->visible =
+ primary_get_hw_state(crtc);
+ else
to_intel_plane_state(drm_plane_state)->visible = false;
- }
- if (visible) {
- crtc_state->base.plane_mask |=
- 1 << drm_plane_index(&p->base);
- } else if (crtc_state->base.state) {
- /* Make this unconditional for atomic hw readout. */
- crtc_state->base.plane_mask &=
- ~(1 << drm_plane_index(&p->base));
- }
+ crtc_state->base.plane_mask |=
+ 1 << drm_plane_index(&p->base);
}
+
+ if (wrong_plane)
+ crtc->pipe = !crtc->pipe;
}
static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15664,6 +15614,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
update_state_fb(c->primary);
c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
}
+ else
+ obj->frontbuffer_bits |=
+ to_intel_plane(c->primary)->frontbuffer_bit;
}
intel_backlight_register(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2ed618f78fe6..c3cea178c809 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -341,7 +341,6 @@ struct intel_crtc_state {
*/
#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
-#define PIPE_CONFIG_QUIRK_INITIAL_PLANES (1<<2) /* planes are in unknown state */
unsigned long quirks;
/* Pipe source size (ie. panel fitter input size)
@@ -550,7 +549,6 @@ struct intel_crtc {
uint32_t cursor_size;
uint32_t cursor_base;
- struct intel_initial_plane_config plane_config;
struct intel_crtc_state *config;
bool new_enabled;
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly.
2015-07-07 7:08 ` [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly Maarten Lankhorst
@ 2015-07-07 11:16 ` Daniel Vetter
2015-07-07 14:02 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 11:16 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:18AM +0200, Maarten Lankhorst wrote:
> Make sure the primary plane is set up correctly. This is done by
> setting plane_state->src and plane_state->crtc.
>
> All non-primary planes get disabled.
Too terse commit message, fails to mention that this is about hw
readout completely. Also should mention that this removes the
initial_planes hack.
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_atomic.c | 7 --
> drivers/gpu/drm/i915/intel_display.c | 167 +++++++++++++----------------------
> drivers/gpu/drm/i915/intel_drv.h | 2 -
> 3 files changed, 60 insertions(+), 116 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 429677a111d5..b593612a917d 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -98,13 +98,6 @@ int intel_atomic_check(struct drm_device *dev,
> return -EINVAL;
> }
>
> - if (crtc_state &&
> - crtc_state->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> - ret = drm_atomic_add_affected_planes(state, &nuclear_crtc->base);
> - if (ret)
> - return ret;
> - }
> -
> ret = drm_atomic_helper_check_planes(dev, state);
> if (ret)
> return ret;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index eb7c2e2819b7..fa1102392eca 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -109,6 +109,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
> struct intel_crtc_state *crtc_state);
> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> int num_connectors);
> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
>
> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
> {
> @@ -2582,11 +2583,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> {
> struct drm_device *dev = intel_crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> - struct drm_crtc *c;
> - struct intel_crtc *i;
> struct drm_i915_gem_object *obj;
> - struct drm_plane *primary = intel_crtc->base.primary;
> struct drm_framebuffer *fb;
> + struct drm_plane *primary = intel_crtc->base.primary;
> + struct intel_plane *p;
> + struct intel_plane_state *plane_state =
> + to_intel_plane_state(primary->state);
>
> if (!plane_config->fb)
> return;
> @@ -2602,16 +2604,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> * Failed to alloc the obj, check to see if we should share
> * an fb with another CRTC instead
> */
> - for_each_crtc(dev, c) {
> - i = to_intel_crtc(c);
> -
> - if (c == &intel_crtc->base)
> - continue;
> -
> - if (!i->active)
> + for_each_intel_plane(dev, p) {
> + if (p->base.type != DRM_PLANE_TYPE_PRIMARY)
> continue;
>
> - fb = c->primary->fb;
> + fb = p->base.state->fb;
This seems to break the sharing logic completely: We want to check primary
planes of all other crtcs to see whether we could merged the fb together.
We don't even read out plane state for non-primary planes, so the below fb
check will never be non-NULL.
> if (!fb)
> continue;
>
> @@ -2622,18 +2619,28 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> }
> }
>
> + intel_pre_disable_primary(&intel_crtc->base);
> + to_intel_plane(primary)->disable_plane(primary, &intel_crtc->base);
> +
> return;
>
> valid_fb:
> + drm_framebuffer_reference(fb);
> + primary->fb = plane_state->base.fb = fb;
> + plane_state->base.crtc = primary->crtc = &intel_crtc->base;
> +
> + plane_state->base.src_x = plane_state->base.src_y = 0;
> + plane_state->base.src_w = fb->width << 16;
> + plane_state->base.src_h = fb->height << 16;
> +
> + plane_state->base.crtc_x = plane_state->base.src_y = 0;
> + plane_state->base.crtc_w = fb->width;
> + plane_state->base.crtc_h = fb->height;
> +
> + plane_state->visible = true;
> obj = intel_fb_obj(fb);
> if (obj->tiling_mode != I915_TILING_NONE)
> dev_priv->preserve_bios_swizzle = true;
> -
> - primary->fb = fb;
> - primary->crtc = primary->state->crtc = &intel_crtc->base;
> - update_state_fb(primary);
Do we still have other users of update_state_fb left?
> - intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
> - obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
> }
>
> static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> @@ -11761,34 +11768,6 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
> return true;
> }
>
> -static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
> - struct drm_crtc_state *crtc_state)
> -{
> - struct intel_crtc_state *pipe_config =
> - to_intel_crtc_state(crtc_state);
> - struct drm_plane *p;
> - unsigned visible_mask = 0;
> -
> - drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
> - struct drm_plane_state *plane_state =
> - drm_atomic_get_existing_plane_state(crtc_state->state, p);
> -
> - if (WARN_ON(!plane_state))
> - continue;
> -
> - if (!plane_state->fb)
> - crtc_state->plane_mask &=
> - ~(1 << drm_plane_index(p));
> - else if (to_intel_plane_state(plane_state)->visible)
> - visible_mask |= 1 << drm_plane_index(p);
> - }
> -
> - if (!visible_mask)
> - return;
> -
> - pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> -}
> -
> static int intel_crtc_atomic_check(struct drm_crtc *crtc,
> struct drm_crtc_state *crtc_state)
> {
> @@ -11810,10 +11789,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
> "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
> idx, crtc->state->active, intel_crtc->active);
>
> - /* plane mask is fixed up after all initial planes are calculated */
> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
> - intel_crtc_check_initial_planes(crtc, crtc_state);
> -
> if (mode_changed && !crtc_state->active)
> intel_crtc->atomic.update_wm_post = true;
>
> @@ -13155,19 +13130,6 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
> continue;
> }
>
> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> - ret = drm_atomic_add_affected_planes(state, crtc);
> - if (ret)
> - return ret;
> -
> - /*
> - * We ought to handle i915.fastboot here.
> - * If no modeset is required and the primary plane has
> - * a fb, update the members of crtc_state as needed,
> - * and run the necessary updates during vblank evasion.
> - */
> - }
> -
> if (!needs_modeset(crtc_state)) {
> if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
> continue;
> @@ -15149,25 +15111,30 @@ void intel_modeset_init(struct drm_device *dev)
> drm_modeset_unlock_all(dev);
>
> for_each_intel_crtc(dev, crtc) {
> - if (!crtc->active)
> + struct intel_initial_plane_config plane_config;
> + struct drm_plane *plane;
> +
> + if (!crtc->base.state->active)
> continue;
>
> + /* disable all non-primary planes */
> + drm_for_each_plane_mask(plane, dev,
> + crtc->base.state->plane_mask)
> + if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> + to_intel_plane(plane)->disable_plane(plane, &crtc->base);
> +
> + crtc->base.state->plane_mask &=
> + 1 << drm_plane_index(crtc->base.primary);
> +
> + plane_config.fb = NULL;
> + dev_priv->display.get_initial_plane_config(crtc,
> + &plane_config);
> +
> /*
> - * Note that reserving the BIOS fb up front prevents us
> - * from stuffing other stolen allocations like the ring
> - * on top. This prevents some ugliness at boot time, and
> - * can even allow for smooth boot transitions if the BIOS
> - * fb is large enough for the active pipe configuration.
> + * If the fb is shared between multiple heads, we'll
> + * just get the first one.
> */
> - if (dev_priv->display.get_initial_plane_config) {
> - dev_priv->display.get_initial_plane_config(crtc,
> - &crtc->plane_config);
> - /*
> - * If the fb is shared between multiple heads, we'll
> - * just get the first one.
> - */
> - intel_find_initial_plane_obj(crtc, &crtc->plane_config);
> - }
> + intel_find_initial_plane_obj(crtc, &plane_config);
> }
> }
Ok I looked at this and the readout_plane_state function and I think we
have a bit a confusion about responsibilities here. The big thing is that
only driver load cares about reconstructing plane state accurately, for
resume and lid notifier we just want to make sure that we update the
planes. And that could be achieved by unconditionally setting
crtc_state->planes_changed. We already have all the plane states when
restoring state anyway.
That means we should move readout_plane_state into the above loop. Which
then gets a bit too big, so better extract this into a
intel_reconstruct_plane_state or similar. This function should then do all
the plane state reconstruction.
That also means we don't have to play tricks with plane_mask like you do.
We simply reconstruct the primary plane (if possible) and force-disable
all the others. Since this only happens at driver load there's no need to
clear out any state for sprite/cursors since it's already fully cleared.
I think this way we should be able to have everything in one place, and
that should allow us to simplify things a lot.
>
> @@ -15404,47 +15371,30 @@ static void readout_plane_state(struct intel_crtc *crtc,
> struct intel_plane *p;
> struct drm_plane_state *drm_plane_state;
> bool active = crtc_state->base.active;
> + bool wrong_plane;
>
> - if (active) {
> - crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> -
> - /* apply to previous sw state too */
> - to_intel_crtc_state(crtc->base.state)->quirks |=
> - PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> - }
> + wrong_plane = active && !intel_check_plane_mapping(crtc);
> + if (wrong_plane)
> + crtc->pipe = !crtc->pipe;
>
> for_each_intel_plane(crtc->base.dev, p) {
> - bool visible = active;
> -
> if (crtc->pipe != p->pipe)
> continue;
>
> drm_plane_state = p->base.state;
>
> - /* Plane scaler state is not touched here. The first atomic
> - * commit will restore all plane scalers to its old state.
> - */
> -
> - if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
> - visible = primary_get_hw_state(crtc);
> - to_intel_plane_state(drm_plane_state)->visible = visible;
> - } else {
> - /*
> - * unknown state, assume it's off to force a transition
> - * to on when calculating state changes.
> - */
> + if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
> + to_intel_plane_state(drm_plane_state)->visible =
> + primary_get_hw_state(crtc);
> + else
> to_intel_plane_state(drm_plane_state)->visible = false;
> - }
>
> - if (visible) {
> - crtc_state->base.plane_mask |=
> - 1 << drm_plane_index(&p->base);
> - } else if (crtc_state->base.state) {
> - /* Make this unconditional for atomic hw readout. */
> - crtc_state->base.plane_mask &=
> - ~(1 << drm_plane_index(&p->base));
> - }
> + crtc_state->base.plane_mask |=
> + 1 << drm_plane_index(&p->base);
> }
> +
> + if (wrong_plane)
> + crtc->pipe = !crtc->pipe;
> }
>
> static void intel_modeset_readout_hw_state(struct drm_device *dev)
> @@ -15664,6 +15614,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
> update_state_fb(c->primary);
> c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
> }
> + else
> + obj->frontbuffer_bits |=
> + to_intel_plane(c->primary)->frontbuffer_bit;
This is part of plane state reconstruction, no need to move it. The only
reason we have to pin late is that gem isn't initialized yet fully when we
want to reconstruct the modeset state. And that pinning shouldn't ever
fail, it just increments pin_count and writes the ptes (again).
-Daniel
> }
>
> intel_backlight_register(dev);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 2ed618f78fe6..c3cea178c809 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -341,7 +341,6 @@ struct intel_crtc_state {
> */
> #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
> #define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
> -#define PIPE_CONFIG_QUIRK_INITIAL_PLANES (1<<2) /* planes are in unknown state */
> unsigned long quirks;
>
> /* Pipe source size (ie. panel fitter input size)
> @@ -550,7 +549,6 @@ struct intel_crtc {
> uint32_t cursor_size;
> uint32_t cursor_base;
>
> - struct intel_initial_plane_config plane_config;
> struct intel_crtc_state *config;
> bool new_enabled;
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly.
2015-07-07 11:16 ` Daniel Vetter
@ 2015-07-07 14:02 ` Maarten Lankhorst
2015-07-08 9:27 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 14:02 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 13:16 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:18AM +0200, Maarten Lankhorst wrote:
>> Make sure the primary plane is set up correctly. This is done by
>> setting plane_state->src and plane_state->crtc.
>>
>> All non-primary planes get disabled.
> Too terse commit message, fails to mention that this is about hw
> readout completely. Also should mention that this removes the
> initial_planes hack.
>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_atomic.c | 7 --
>> drivers/gpu/drm/i915/intel_display.c | 167 +++++++++++++----------------------
>> drivers/gpu/drm/i915/intel_drv.h | 2 -
>> 3 files changed, 60 insertions(+), 116 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
>> index 429677a111d5..b593612a917d 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>> @@ -98,13 +98,6 @@ int intel_atomic_check(struct drm_device *dev,
>> return -EINVAL;
>> }
>>
>> - if (crtc_state &&
>> - crtc_state->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>> - ret = drm_atomic_add_affected_planes(state, &nuclear_crtc->base);
>> - if (ret)
>> - return ret;
>> - }
>> -
>> ret = drm_atomic_helper_check_planes(dev, state);
>> if (ret)
>> return ret;
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index eb7c2e2819b7..fa1102392eca 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -109,6 +109,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
>> struct intel_crtc_state *crtc_state);
>> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
>> int num_connectors);
>> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
>>
>> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
>> {
>> @@ -2582,11 +2583,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>> {
>> struct drm_device *dev = intel_crtc->base.dev;
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> - struct drm_crtc *c;
>> - struct intel_crtc *i;
>> struct drm_i915_gem_object *obj;
>> - struct drm_plane *primary = intel_crtc->base.primary;
>> struct drm_framebuffer *fb;
>> + struct drm_plane *primary = intel_crtc->base.primary;
>> + struct intel_plane *p;
>> + struct intel_plane_state *plane_state =
>> + to_intel_plane_state(primary->state);
>>
>> if (!plane_config->fb)
>> return;
>> @@ -2602,16 +2604,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>> * Failed to alloc the obj, check to see if we should share
>> * an fb with another CRTC instead
>> */
>> - for_each_crtc(dev, c) {
>> - i = to_intel_crtc(c);
>> -
>> - if (c == &intel_crtc->base)
>> - continue;
>> -
>> - if (!i->active)
>> + for_each_intel_plane(dev, p) {
>> + if (p->base.type != DRM_PLANE_TYPE_PRIMARY)
>> continue;
>>
>> - fb = c->primary->fb;
>> + fb = p->base.state->fb;
> This seems to break the sharing logic completely: We want to check primary
> planes of all other crtcs to see whether we could merged the fb together.
> We don't even read out plane state for non-primary planes, so the below fb
> check will never be non-NULL.
I thought this was about multiple planes sharing the same fb with same offset.
And as such checking for the crtc is unnecessary, for the current crtc it will be be NULL here.
This only reads out the current fb, not different ones.
And sharing the same fb with other crtc's is done in intel_fbdev_init_bios.
>> if (!fb)
>> continue;
>>
>> @@ -2622,18 +2619,28 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>> }
>> }
>>
>> + intel_pre_disable_primary(&intel_crtc->base);
>> + to_intel_plane(primary)->disable_plane(primary, &intel_crtc->base);
>> +
>> return;
>>
>> valid_fb:
>> + drm_framebuffer_reference(fb);
>> + primary->fb = plane_state->base.fb = fb;
>> + plane_state->base.crtc = primary->crtc = &intel_crtc->base;
>> +
>> + plane_state->base.src_x = plane_state->base.src_y = 0;
>> + plane_state->base.src_w = fb->width << 16;
>> + plane_state->base.src_h = fb->height << 16;
>> +
>> + plane_state->base.crtc_x = plane_state->base.src_y = 0;
>> + plane_state->base.crtc_w = fb->width;
>> + plane_state->base.crtc_h = fb->height;
>> +
>> + plane_state->visible = true;
>> obj = intel_fb_obj(fb);
>> if (obj->tiling_mode != I915_TILING_NONE)
>> dev_priv->preserve_bios_swizzle = true;
>> -
>> - primary->fb = fb;
>> - primary->crtc = primary->state->crtc = &intel_crtc->base;
>> - update_state_fb(primary);
> Do we still have other users of update_state_fb left?
Just the page flip handler.
>> - intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
>> - obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
>> }
>>
>> static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>> @@ -11761,34 +11768,6 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
>> return true;
>> }
>>
>> -static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
>> - struct drm_crtc_state *crtc_state)
>> -{
>> - struct intel_crtc_state *pipe_config =
>> - to_intel_crtc_state(crtc_state);
>> - struct drm_plane *p;
>> - unsigned visible_mask = 0;
>> -
>> - drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
>> - struct drm_plane_state *plane_state =
>> - drm_atomic_get_existing_plane_state(crtc_state->state, p);
>> -
>> - if (WARN_ON(!plane_state))
>> - continue;
>> -
>> - if (!plane_state->fb)
>> - crtc_state->plane_mask &=
>> - ~(1 << drm_plane_index(p));
>> - else if (to_intel_plane_state(plane_state)->visible)
>> - visible_mask |= 1 << drm_plane_index(p);
>> - }
>> -
>> - if (!visible_mask)
>> - return;
>> -
>> - pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>> -}
>> -
>> static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>> struct drm_crtc_state *crtc_state)
>> {
>> @@ -11810,10 +11789,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>> "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
>> idx, crtc->state->active, intel_crtc->active);
>>
>> - /* plane mask is fixed up after all initial planes are calculated */
>> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
>> - intel_crtc_check_initial_planes(crtc, crtc_state);
>> -
>> if (mode_changed && !crtc_state->active)
>> intel_crtc->atomic.update_wm_post = true;
>>
>> @@ -13155,19 +13130,6 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
>> continue;
>> }
>>
>> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>> - ret = drm_atomic_add_affected_planes(state, crtc);
>> - if (ret)
>> - return ret;
>> -
>> - /*
>> - * We ought to handle i915.fastboot here.
>> - * If no modeset is required and the primary plane has
>> - * a fb, update the members of crtc_state as needed,
>> - * and run the necessary updates during vblank evasion.
>> - */
>> - }
>> -
>> if (!needs_modeset(crtc_state)) {
>> if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
>> continue;
>> @@ -15149,25 +15111,30 @@ void intel_modeset_init(struct drm_device *dev)
>> drm_modeset_unlock_all(dev);
>>
>> for_each_intel_crtc(dev, crtc) {
>> - if (!crtc->active)
>> + struct intel_initial_plane_config plane_config;
>> + struct drm_plane *plane;
>> +
>> + if (!crtc->base.state->active)
>> continue;
>>
>> + /* disable all non-primary planes */
>> + drm_for_each_plane_mask(plane, dev,
>> + crtc->base.state->plane_mask)
>> + if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>> + to_intel_plane(plane)->disable_plane(plane, &crtc->base);
>> +
>> + crtc->base.state->plane_mask &=
>> + 1 << drm_plane_index(crtc->base.primary);
>> +
>> + plane_config.fb = NULL;
>> + dev_priv->display.get_initial_plane_config(crtc,
>> + &plane_config);
>> +
>> /*
>> - * Note that reserving the BIOS fb up front prevents us
>> - * from stuffing other stolen allocations like the ring
>> - * on top. This prevents some ugliness at boot time, and
>> - * can even allow for smooth boot transitions if the BIOS
>> - * fb is large enough for the active pipe configuration.
>> + * If the fb is shared between multiple heads, we'll
>> + * just get the first one.
>> */
>> - if (dev_priv->display.get_initial_plane_config) {
>> - dev_priv->display.get_initial_plane_config(crtc,
>> - &crtc->plane_config);
>> - /*
>> - * If the fb is shared between multiple heads, we'll
>> - * just get the first one.
>> - */
>> - intel_find_initial_plane_obj(crtc, &crtc->plane_config);
>> - }
>> + intel_find_initial_plane_obj(crtc, &plane_config);
>> }
>> }
> Ok I looked at this and the readout_plane_state function and I think we
> have a bit a confusion about responsibilities here. The big thing is that
> only driver load cares about reconstructing plane state accurately, for
> resume and lid notifier we just want to make sure that we update the
> planes. And that could be achieved by unconditionally setting
> crtc_state->planes_changed. We already have all the plane states when
> restoring state anyway.
On resume I force a modeset for this reason, and set the plane_mask.
This makes sure any plane gets disabled.
The modeset will also add all planes, which sets planes_changed if needed.
A commit on its own doesn't do this, when a plane doesn't have a fb
it won't disable it on its own because the plane's assumed to be disabled
when old_plane_state->fb == NULL and new_plane_state->fb == NULL.
I don't know if I can call disable_plane in this loop either, because that will
update the watermarks on skylake with the call to intel_update_sprite_watermarks
calling skl_update_sprite_wm calling skl_update_wm.
We don't even have any watermarks calculated yet, so that will break.
> That means we should move readout_plane_state into the above loop. Which
> then gets a bit too big, so better extract this into a
> intel_reconstruct_plane_state or similar. This function should then do all
> the plane state reconstruction.
>
> That also means we don't have to play tricks with plane_mask like you do.
> We simply reconstruct the primary plane (if possible) and force-disable
> all the others. Since this only happens at driver load there's no need to
> clear out any state for sprite/cursors since it's already fully cleared.
>
> I think this way we should be able to have everything in one place, and
> that should allow us to simplify things a lot.
I do this trick for atomic resume, we can't allocate the original fb in that case
but I still want to sanitize everything. This either happens because
a new primary fb gets committed or the primary fb gets disabled.
>>
>> @@ -15404,47 +15371,30 @@ static void readout_plane_state(struct intel_crtc *crtc,
>> struct intel_plane *p;
>> struct drm_plane_state *drm_plane_state;
>> bool active = crtc_state->base.active;
>> + bool wrong_plane;
>>
>> - if (active) {
>> - crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>> -
>> - /* apply to previous sw state too */
>> - to_intel_crtc_state(crtc->base.state)->quirks |=
>> - PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>> - }
>> + wrong_plane = active && !intel_check_plane_mapping(crtc);
>> + if (wrong_plane)
>> + crtc->pipe = !crtc->pipe;
>>
>> for_each_intel_plane(crtc->base.dev, p) {
>> - bool visible = active;
>> -
>> if (crtc->pipe != p->pipe)
>> continue;
>>
>> drm_plane_state = p->base.state;
>>
>> - /* Plane scaler state is not touched here. The first atomic
>> - * commit will restore all plane scalers to its old state.
>> - */
>> -
>> - if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
>> - visible = primary_get_hw_state(crtc);
>> - to_intel_plane_state(drm_plane_state)->visible = visible;
>> - } else {
>> - /*
>> - * unknown state, assume it's off to force a transition
>> - * to on when calculating state changes.
>> - */
>> + if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
>> + to_intel_plane_state(drm_plane_state)->visible =
>> + primary_get_hw_state(crtc);
>> + else
>> to_intel_plane_state(drm_plane_state)->visible = false;
>> - }
>>
>> - if (visible) {
>> - crtc_state->base.plane_mask |=
>> - 1 << drm_plane_index(&p->base);
>> - } else if (crtc_state->base.state) {
>> - /* Make this unconditional for atomic hw readout. */
>> - crtc_state->base.plane_mask &=
>> - ~(1 << drm_plane_index(&p->base));
>> - }
>> + crtc_state->base.plane_mask |=
>> + 1 << drm_plane_index(&p->base);
>> }
>> +
>> + if (wrong_plane)
>> + crtc->pipe = !crtc->pipe;
>> }
>>
>> static void intel_modeset_readout_hw_state(struct drm_device *dev)
>> @@ -15664,6 +15614,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
>> update_state_fb(c->primary);
>> c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
>> }
>> + else
>> + obj->frontbuffer_bits |=
>> + to_intel_plane(c->primary)->frontbuffer_bit;
> This is part of plane state reconstruction, no need to move it. The only
> reason we have to pin late is that gem isn't initialized yet fully when we
> want to reconstruct the modeset state. And that pinning shouldn't ever
> fail, it just increments pin_count and writes the ptes (again).
Why bother handling the return value at all then?
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly.
2015-07-07 14:02 ` Maarten Lankhorst
@ 2015-07-08 9:27 ` Daniel Vetter
2015-07-08 12:36 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-08 9:27 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 04:02:32PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 13:16 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:18AM +0200, Maarten Lankhorst wrote:
> >> Make sure the primary plane is set up correctly. This is done by
> >> setting plane_state->src and plane_state->crtc.
> >>
> >> All non-primary planes get disabled.
> > Too terse commit message, fails to mention that this is about hw
> > readout completely. Also should mention that this removes the
> > initial_planes hack.
> >
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >> drivers/gpu/drm/i915/intel_atomic.c | 7 --
> >> drivers/gpu/drm/i915/intel_display.c | 167 +++++++++++++----------------------
> >> drivers/gpu/drm/i915/intel_drv.h | 2 -
> >> 3 files changed, 60 insertions(+), 116 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> >> index 429677a111d5..b593612a917d 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> >> @@ -98,13 +98,6 @@ int intel_atomic_check(struct drm_device *dev,
> >> return -EINVAL;
> >> }
> >>
> >> - if (crtc_state &&
> >> - crtc_state->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> >> - ret = drm_atomic_add_affected_planes(state, &nuclear_crtc->base);
> >> - if (ret)
> >> - return ret;
> >> - }
> >> -
> >> ret = drm_atomic_helper_check_planes(dev, state);
> >> if (ret)
> >> return ret;
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index eb7c2e2819b7..fa1102392eca 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -109,6 +109,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
> >> struct intel_crtc_state *crtc_state);
> >> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> >> int num_connectors);
> >> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
> >>
> >> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
> >> {
> >> @@ -2582,11 +2583,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> >> {
> >> struct drm_device *dev = intel_crtc->base.dev;
> >> struct drm_i915_private *dev_priv = dev->dev_private;
> >> - struct drm_crtc *c;
> >> - struct intel_crtc *i;
> >> struct drm_i915_gem_object *obj;
> >> - struct drm_plane *primary = intel_crtc->base.primary;
> >> struct drm_framebuffer *fb;
> >> + struct drm_plane *primary = intel_crtc->base.primary;
> >> + struct intel_plane *p;
> >> + struct intel_plane_state *plane_state =
> >> + to_intel_plane_state(primary->state);
> >>
> >> if (!plane_config->fb)
> >> return;
> >> @@ -2602,16 +2604,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> >> * Failed to alloc the obj, check to see if we should share
> >> * an fb with another CRTC instead
> >> */
> >> - for_each_crtc(dev, c) {
> >> - i = to_intel_crtc(c);
> >> -
> >> - if (c == &intel_crtc->base)
> >> - continue;
> >> -
> >> - if (!i->active)
> >> + for_each_intel_plane(dev, p) {
> >> + if (p->base.type != DRM_PLANE_TYPE_PRIMARY)
> >> continue;
> >>
> >> - fb = c->primary->fb;
> >> + fb = p->base.state->fb;
> > This seems to break the sharing logic completely: We want to check primary
> > planes of all other crtcs to see whether we could merged the fb together.
> > We don't even read out plane state for non-primary planes, so the below fb
> > check will never be non-NULL.
> I thought this was about multiple planes sharing the same fb with same offset.
> And as such checking for the crtc is unnecessary, for the current crtc it will be be NULL here.
>
> This only reads out the current fb, not different ones.
>
> And sharing the same fb with other crtc's is done in intel_fbdev_init_bios.
This is about sharing the same fb but across different crtcs - bios never
enables more than the primary plane anyway. And you can't rely upon
fbdev_init_bios since that's not run at all when I915_FBDEV=n.
So yes with current code this loop here reconstruct the shared between
primary planes on different crtcs (if the stolen allocator tells us that
our range is occupied already). fbdev_init_bios just tries to create a
config matching the one the bios has set up (and then pick a suitable fb
for fbcon from the ones already allocated).
Maybe we should extract this as try_to_find_shared_fb or similar to make
the code self-explanatory?
>
> >> if (!fb)
> >> continue;
> >>
> >> @@ -2622,18 +2619,28 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> >> }
> >> }
> >>
> >> + intel_pre_disable_primary(&intel_crtc->base);
> >> + to_intel_plane(primary)->disable_plane(primary, &intel_crtc->base);
> >> +
> >> return;
> >>
> >> valid_fb:
> >> + drm_framebuffer_reference(fb);
> >> + primary->fb = plane_state->base.fb = fb;
> >> + plane_state->base.crtc = primary->crtc = &intel_crtc->base;
> >> +
> >> + plane_state->base.src_x = plane_state->base.src_y = 0;
> >> + plane_state->base.src_w = fb->width << 16;
> >> + plane_state->base.src_h = fb->height << 16;
> >> +
> >> + plane_state->base.crtc_x = plane_state->base.src_y = 0;
> >> + plane_state->base.crtc_w = fb->width;
> >> + plane_state->base.crtc_h = fb->height;
> >> +
> >> + plane_state->visible = true;
> >> obj = intel_fb_obj(fb);
> >> if (obj->tiling_mode != I915_TILING_NONE)
> >> dev_priv->preserve_bios_swizzle = true;
> >> -
> >> - primary->fb = fb;
> >> - primary->crtc = primary->state->crtc = &intel_crtc->base;
> >> - update_state_fb(primary);
> > Do we still have other users of update_state_fb left?
> Just the page flip handler.
> >> - intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
> >> - obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
> >> }
> >>
> >> static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >> @@ -11761,34 +11768,6 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
> >> return true;
> >> }
> >>
> >> -static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
> >> - struct drm_crtc_state *crtc_state)
> >> -{
> >> - struct intel_crtc_state *pipe_config =
> >> - to_intel_crtc_state(crtc_state);
> >> - struct drm_plane *p;
> >> - unsigned visible_mask = 0;
> >> -
> >> - drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
> >> - struct drm_plane_state *plane_state =
> >> - drm_atomic_get_existing_plane_state(crtc_state->state, p);
> >> -
> >> - if (WARN_ON(!plane_state))
> >> - continue;
> >> -
> >> - if (!plane_state->fb)
> >> - crtc_state->plane_mask &=
> >> - ~(1 << drm_plane_index(p));
> >> - else if (to_intel_plane_state(plane_state)->visible)
> >> - visible_mask |= 1 << drm_plane_index(p);
> >> - }
> >> -
> >> - if (!visible_mask)
> >> - return;
> >> -
> >> - pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> >> -}
> >> -
> >> static int intel_crtc_atomic_check(struct drm_crtc *crtc,
> >> struct drm_crtc_state *crtc_state)
> >> {
> >> @@ -11810,10 +11789,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
> >> "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
> >> idx, crtc->state->active, intel_crtc->active);
> >>
> >> - /* plane mask is fixed up after all initial planes are calculated */
> >> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
> >> - intel_crtc_check_initial_planes(crtc, crtc_state);
> >> -
> >> if (mode_changed && !crtc_state->active)
> >> intel_crtc->atomic.update_wm_post = true;
> >>
> >> @@ -13155,19 +13130,6 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
> >> continue;
> >> }
> >>
> >> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
> >> - ret = drm_atomic_add_affected_planes(state, crtc);
> >> - if (ret)
> >> - return ret;
> >> -
> >> - /*
> >> - * We ought to handle i915.fastboot here.
> >> - * If no modeset is required and the primary plane has
> >> - * a fb, update the members of crtc_state as needed,
> >> - * and run the necessary updates during vblank evasion.
> >> - */
> >> - }
> >> -
> >> if (!needs_modeset(crtc_state)) {
> >> if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
> >> continue;
> >> @@ -15149,25 +15111,30 @@ void intel_modeset_init(struct drm_device *dev)
> >> drm_modeset_unlock_all(dev);
> >>
> >> for_each_intel_crtc(dev, crtc) {
> >> - if (!crtc->active)
> >> + struct intel_initial_plane_config plane_config;
> >> + struct drm_plane *plane;
> >> +
> >> + if (!crtc->base.state->active)
> >> continue;
> >>
> >> + /* disable all non-primary planes */
> >> + drm_for_each_plane_mask(plane, dev,
> >> + crtc->base.state->plane_mask)
> >> + if (plane->type != DRM_PLANE_TYPE_PRIMARY)
> >> + to_intel_plane(plane)->disable_plane(plane, &crtc->base);
> >> +
> >> + crtc->base.state->plane_mask &=
> >> + 1 << drm_plane_index(crtc->base.primary);
> >> +
> >> + plane_config.fb = NULL;
> >> + dev_priv->display.get_initial_plane_config(crtc,
> >> + &plane_config);
> >> +
> >> /*
> >> - * Note that reserving the BIOS fb up front prevents us
> >> - * from stuffing other stolen allocations like the ring
> >> - * on top. This prevents some ugliness at boot time, and
> >> - * can even allow for smooth boot transitions if the BIOS
> >> - * fb is large enough for the active pipe configuration.
> >> + * If the fb is shared between multiple heads, we'll
> >> + * just get the first one.
> >> */
> >> - if (dev_priv->display.get_initial_plane_config) {
> >> - dev_priv->display.get_initial_plane_config(crtc,
> >> - &crtc->plane_config);
> >> - /*
> >> - * If the fb is shared between multiple heads, we'll
> >> - * just get the first one.
> >> - */
> >> - intel_find_initial_plane_obj(crtc, &crtc->plane_config);
> >> - }
> >> + intel_find_initial_plane_obj(crtc, &plane_config);
> >> }
> >> }
> > Ok I looked at this and the readout_plane_state function and I think we
> > have a bit a confusion about responsibilities here. The big thing is that
> > only driver load cares about reconstructing plane state accurately, for
> > resume and lid notifier we just want to make sure that we update the
> > planes. And that could be achieved by unconditionally setting
> > crtc_state->planes_changed. We already have all the plane states when
> > restoring state anyway.
> On resume I force a modeset for this reason, and set the plane_mask.
> This makes sure any plane gets disabled.
>
> The modeset will also add all planes, which sets planes_changed if needed.
Yeah that's what I had in mind for resume: We need to grab all plane
states anyway (to be able to restore the old config), so at most we need
to set a planes_changed to make sure the update happens.
> A commit on its own doesn't do this, when a plane doesn't have a fb
> it won't disable it on its own because the plane's assumed to be disabled
> when old_plane_state->fb == NULL and new_plane_state->fb == NULL.
Not a problem since too many planes doesn't seem to happen in reality. At
least we didn't have code to force-disable planes on resume/lid_notify
before, which means we don't suddenly need it now. sanitize_* should only
fix up stuff that's broken for i915 on real-world machines, not what all
could be possible.
> I don't know if I can call disable_plane in this loop either, because that will
> update the watermarks on skylake with the call to intel_update_sprite_watermarks
> calling skl_update_sprite_wm calling skl_update_wm.
Hm that sounds like a bug still. Maybe just forget about disabling
non-primary planes for now on driver load? We don't seem to have any need
currently either. And for primary planes maybe we can hard-code something
which just clears the PLANE_ENABLE bit and does nothing else? Kind of a
super-low-level plane force disable. Similar to how we have a special
function to force-disable the vga plane.
> We don't even have any watermarks calculated yet, so that will break.
> > That means we should move readout_plane_state into the above loop. Which
> > then gets a bit too big, so better extract this into a
> > intel_reconstruct_plane_state or similar. This function should then do all
> > the plane state reconstruction.
> >
> > That also means we don't have to play tricks with plane_mask like you do.
> > We simply reconstruct the primary plane (if possible) and force-disable
> > all the others. Since this only happens at driver load there's no need to
> > clear out any state for sprite/cursors since it's already fully cleared.
> >
> > I think this way we should be able to have everything in one place, and
> > that should allow us to simplify things a lot.
> I do this trick for atomic resume, we can't allocate the original fb in that case
> but I still want to sanitize everything. This either happens because
> a new primary fb gets committed or the primary fb gets disabled.
Well on resume we don't care at all about the original fb for two reasons:
- Anything remotely modern resumes with everything off.
- We only recover the initial plane from the bios to ensure boot-up is
completely flicker-free. If we don't reserve that we'll allocate rings
and other gpu objects in there which isn't pretty.
I don't think we need to sanitize planes either as long as we force a full
plane update on resume (by forcing planes_changed or similar).
And for the lid_restore case the problem hasn't been that the bios changed
the plane state really, but that it just went ahead and disabled
everything on its own. That will result in a crtc_enable which will
restore everything correctly.
Imo we don't need to have a perfect sanitize for everything, this code
really just fixes up what's actually been broken in real-world machines
out there. That kind of real-world testing is also why I want to change as
little as possible in the sanitize_* functions.
> >> @@ -15404,47 +15371,30 @@ static void readout_plane_state(struct intel_crtc *crtc,
> >> struct intel_plane *p;
> >> struct drm_plane_state *drm_plane_state;
> >> bool active = crtc_state->base.active;
> >> + bool wrong_plane;
> >>
> >> - if (active) {
> >> - crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> >> -
> >> - /* apply to previous sw state too */
> >> - to_intel_crtc_state(crtc->base.state)->quirks |=
> >> - PIPE_CONFIG_QUIRK_INITIAL_PLANES;
> >> - }
> >> + wrong_plane = active && !intel_check_plane_mapping(crtc);
> >> + if (wrong_plane)
> >> + crtc->pipe = !crtc->pipe;
> >>
> >> for_each_intel_plane(crtc->base.dev, p) {
> >> - bool visible = active;
> >> -
> >> if (crtc->pipe != p->pipe)
> >> continue;
> >>
> >> drm_plane_state = p->base.state;
> >>
> >> - /* Plane scaler state is not touched here. The first atomic
> >> - * commit will restore all plane scalers to its old state.
> >> - */
> >> -
> >> - if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
> >> - visible = primary_get_hw_state(crtc);
> >> - to_intel_plane_state(drm_plane_state)->visible = visible;
> >> - } else {
> >> - /*
> >> - * unknown state, assume it's off to force a transition
> >> - * to on when calculating state changes.
> >> - */
> >> + if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
> >> + to_intel_plane_state(drm_plane_state)->visible =
> >> + primary_get_hw_state(crtc);
> >> + else
> >> to_intel_plane_state(drm_plane_state)->visible = false;
> >> - }
> >>
> >> - if (visible) {
> >> - crtc_state->base.plane_mask |=
> >> - 1 << drm_plane_index(&p->base);
> >> - } else if (crtc_state->base.state) {
> >> - /* Make this unconditional for atomic hw readout. */
> >> - crtc_state->base.plane_mask &=
> >> - ~(1 << drm_plane_index(&p->base));
> >> - }
> >> + crtc_state->base.plane_mask |=
> >> + 1 << drm_plane_index(&p->base);
> >> }
> >> +
> >> + if (wrong_plane)
> >> + crtc->pipe = !crtc->pipe;
> >> }
> >>
> >> static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >> @@ -15664,6 +15614,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
> >> update_state_fb(c->primary);
> >> c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
> >> }
> >> + else
> >> + obj->frontbuffer_bits |=
> >> + to_intel_plane(c->primary)->frontbuffer_bit;
> > This is part of plane state reconstruction, no need to move it. The only
> > reason we have to pin late is that gem isn't initialized yet fully when we
> > want to reconstruct the modeset state. And that pinning shouldn't ever
> > fail, it just increments pin_count and writes the ptes (again).
> Why bother handling the return value at all then?
To print the warning. I think even the cleanup is pointless since at worst
we'll underrun the pin count, and we have protection for that already
(again with a loud warning). If you want you can remove that code.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly.
2015-07-08 9:27 ` Daniel Vetter
@ 2015-07-08 12:36 ` Maarten Lankhorst
0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-08 12:36 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 08-07-15 om 11:27 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 04:02:32PM +0200, Maarten Lankhorst wrote:
>> Op 07-07-15 om 13:16 schreef Daniel Vetter:
>>> On Tue, Jul 07, 2015 at 09:08:18AM +0200, Maarten Lankhorst wrote:
>>>> Make sure the primary plane is set up correctly. This is done by
>>>> setting plane_state->src and plane_state->crtc.
>>>>
>>>> All non-primary planes get disabled.
>>> Too terse commit message, fails to mention that this is about hw
>>> readout completely. Also should mention that this removes the
>>> initial_planes hack.
>>>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>> ---
>>>> drivers/gpu/drm/i915/intel_atomic.c | 7 --
>>>> drivers/gpu/drm/i915/intel_display.c | 167 +++++++++++++----------------------
>>>> drivers/gpu/drm/i915/intel_drv.h | 2 -
>>>> 3 files changed, 60 insertions(+), 116 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
>>>> index 429677a111d5..b593612a917d 100644
>>>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>>>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>>>> @@ -98,13 +98,6 @@ int intel_atomic_check(struct drm_device *dev,
>>>> return -EINVAL;
>>>> }
>>>>
>>>> - if (crtc_state &&
>>>> - crtc_state->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>>>> - ret = drm_atomic_add_affected_planes(state, &nuclear_crtc->base);
>>>> - if (ret)
>>>> - return ret;
>>>> - }
>>>> -
>>>> ret = drm_atomic_helper_check_planes(dev, state);
>>>> if (ret)
>>>> return ret;
>>>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>>>> index eb7c2e2819b7..fa1102392eca 100644
>>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>>> @@ -109,6 +109,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
>>>> struct intel_crtc_state *crtc_state);
>>>> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
>>>> int num_connectors);
>>>> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
>>>>
>>>> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
>>>> {
>>>> @@ -2582,11 +2583,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>>>> {
>>>> struct drm_device *dev = intel_crtc->base.dev;
>>>> struct drm_i915_private *dev_priv = dev->dev_private;
>>>> - struct drm_crtc *c;
>>>> - struct intel_crtc *i;
>>>> struct drm_i915_gem_object *obj;
>>>> - struct drm_plane *primary = intel_crtc->base.primary;
>>>> struct drm_framebuffer *fb;
>>>> + struct drm_plane *primary = intel_crtc->base.primary;
>>>> + struct intel_plane *p;
>>>> + struct intel_plane_state *plane_state =
>>>> + to_intel_plane_state(primary->state);
>>>>
>>>> if (!plane_config->fb)
>>>> return;
>>>> @@ -2602,16 +2604,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>>>> * Failed to alloc the obj, check to see if we should share
>>>> * an fb with another CRTC instead
>>>> */
>>>> - for_each_crtc(dev, c) {
>>>> - i = to_intel_crtc(c);
>>>> -
>>>> - if (c == &intel_crtc->base)
>>>> - continue;
>>>> -
>>>> - if (!i->active)
>>>> + for_each_intel_plane(dev, p) {
>>>> + if (p->base.type != DRM_PLANE_TYPE_PRIMARY)
>>>> continue;
>>>>
>>>> - fb = c->primary->fb;
>>>> + fb = p->base.state->fb;
>>> This seems to break the sharing logic completely: We want to check primary
>>> planes of all other crtcs to see whether we could merged the fb together.
>>> We don't even read out plane state for non-primary planes, so the below fb
>>> check will never be non-NULL.
>> I thought this was about multiple planes sharing the same fb with same offset.
>> And as such checking for the crtc is unnecessary, for the current crtc it will be be NULL here.
>>
>> This only reads out the current fb, not different ones.
>>
>> And sharing the same fb with other crtc's is done in intel_fbdev_init_bios.
> This is about sharing the same fb but across different crtcs - bios never
> enables more than the primary plane anyway. And you can't rely upon
> fbdev_init_bios since that's not run at all when I915_FBDEV=n.
>
> So yes with current code this loop here reconstruct the shared between
> primary planes on different crtcs (if the stolen allocator tells us that
> our range is occupied already). fbdev_init_bios just tries to create a
> config matching the one the bios has set up (and then pick a suitable fb
> for fbcon from the ones already allocated).
>
> Maybe we should extract this as try_to_find_shared_fb or similar to make
> the code self-explanatory?
>
>>>> if (!fb)
>>>> continue;
>>>>
>>>> @@ -2622,18 +2619,28 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>>>> }
>>>> }
>>>>
>>>> + intel_pre_disable_primary(&intel_crtc->base);
>>>> + to_intel_plane(primary)->disable_plane(primary, &intel_crtc->base);
>>>> +
>>>> return;
>>>>
>>>> valid_fb:
>>>> + drm_framebuffer_reference(fb);
>>>> + primary->fb = plane_state->base.fb = fb;
>>>> + plane_state->base.crtc = primary->crtc = &intel_crtc->base;
>>>> +
>>>> + plane_state->base.src_x = plane_state->base.src_y = 0;
>>>> + plane_state->base.src_w = fb->width << 16;
>>>> + plane_state->base.src_h = fb->height << 16;
>>>> +
>>>> + plane_state->base.crtc_x = plane_state->base.src_y = 0;
>>>> + plane_state->base.crtc_w = fb->width;
>>>> + plane_state->base.crtc_h = fb->height;
>>>> +
>>>> + plane_state->visible = true;
>>>> obj = intel_fb_obj(fb);
>>>> if (obj->tiling_mode != I915_TILING_NONE)
>>>> dev_priv->preserve_bios_swizzle = true;
>>>> -
>>>> - primary->fb = fb;
>>>> - primary->crtc = primary->state->crtc = &intel_crtc->base;
>>>> - update_state_fb(primary);
>>> Do we still have other users of update_state_fb left?
>> Just the page flip handler.
>>>> - intel_crtc->base.state->plane_mask |= (1 << drm_plane_index(primary));
>>>> - obj->frontbuffer_bits |= to_intel_plane(primary)->frontbuffer_bit;
>>>> }
>>>>
>>>> static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>> @@ -11761,34 +11768,6 @@ static bool check_encoder_cloning(struct drm_atomic_state *state,
>>>> return true;
>>>> }
>>>>
>>>> -static void intel_crtc_check_initial_planes(struct drm_crtc *crtc,
>>>> - struct drm_crtc_state *crtc_state)
>>>> -{
>>>> - struct intel_crtc_state *pipe_config =
>>>> - to_intel_crtc_state(crtc_state);
>>>> - struct drm_plane *p;
>>>> - unsigned visible_mask = 0;
>>>> -
>>>> - drm_for_each_plane_mask(p, crtc->dev, crtc_state->plane_mask) {
>>>> - struct drm_plane_state *plane_state =
>>>> - drm_atomic_get_existing_plane_state(crtc_state->state, p);
>>>> -
>>>> - if (WARN_ON(!plane_state))
>>>> - continue;
>>>> -
>>>> - if (!plane_state->fb)
>>>> - crtc_state->plane_mask &=
>>>> - ~(1 << drm_plane_index(p));
>>>> - else if (to_intel_plane_state(plane_state)->visible)
>>>> - visible_mask |= 1 << drm_plane_index(p);
>>>> - }
>>>> -
>>>> - if (!visible_mask)
>>>> - return;
>>>> -
>>>> - pipe_config->quirks &= ~PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>>>> -}
>>>> -
>>>> static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>>>> struct drm_crtc_state *crtc_state)
>>>> {
>>>> @@ -11810,10 +11789,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
>>>> "[CRTC:%i] mismatch between state->active(%i) and crtc->active(%i)\n",
>>>> idx, crtc->state->active, intel_crtc->active);
>>>>
>>>> - /* plane mask is fixed up after all initial planes are calculated */
>>>> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES)
>>>> - intel_crtc_check_initial_planes(crtc, crtc_state);
>>>> -
>>>> if (mode_changed && !crtc_state->active)
>>>> intel_crtc->atomic.update_wm_post = true;
>>>>
>>>> @@ -13155,19 +13130,6 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
>>>> continue;
>>>> }
>>>>
>>>> - if (pipe_config->quirks & PIPE_CONFIG_QUIRK_INITIAL_PLANES) {
>>>> - ret = drm_atomic_add_affected_planes(state, crtc);
>>>> - if (ret)
>>>> - return ret;
>>>> -
>>>> - /*
>>>> - * We ought to handle i915.fastboot here.
>>>> - * If no modeset is required and the primary plane has
>>>> - * a fb, update the members of crtc_state as needed,
>>>> - * and run the necessary updates during vblank evasion.
>>>> - */
>>>> - }
>>>> -
>>>> if (!needs_modeset(crtc_state)) {
>>>> if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
>>>> continue;
>>>> @@ -15149,25 +15111,30 @@ void intel_modeset_init(struct drm_device *dev)
>>>> drm_modeset_unlock_all(dev);
>>>>
>>>> for_each_intel_crtc(dev, crtc) {
>>>> - if (!crtc->active)
>>>> + struct intel_initial_plane_config plane_config;
>>>> + struct drm_plane *plane;
>>>> +
>>>> + if (!crtc->base.state->active)
>>>> continue;
>>>>
>>>> + /* disable all non-primary planes */
>>>> + drm_for_each_plane_mask(plane, dev,
>>>> + crtc->base.state->plane_mask)
>>>> + if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>>>> + to_intel_plane(plane)->disable_plane(plane, &crtc->base);
>>>> +
>>>> + crtc->base.state->plane_mask &=
>>>> + 1 << drm_plane_index(crtc->base.primary);
>>>> +
>>>> + plane_config.fb = NULL;
>>>> + dev_priv->display.get_initial_plane_config(crtc,
>>>> + &plane_config);
>>>> +
>>>> /*
>>>> - * Note that reserving the BIOS fb up front prevents us
>>>> - * from stuffing other stolen allocations like the ring
>>>> - * on top. This prevents some ugliness at boot time, and
>>>> - * can even allow for smooth boot transitions if the BIOS
>>>> - * fb is large enough for the active pipe configuration.
>>>> + * If the fb is shared between multiple heads, we'll
>>>> + * just get the first one.
>>>> */
>>>> - if (dev_priv->display.get_initial_plane_config) {
>>>> - dev_priv->display.get_initial_plane_config(crtc,
>>>> - &crtc->plane_config);
>>>> - /*
>>>> - * If the fb is shared between multiple heads, we'll
>>>> - * just get the first one.
>>>> - */
>>>> - intel_find_initial_plane_obj(crtc, &crtc->plane_config);
>>>> - }
>>>> + intel_find_initial_plane_obj(crtc, &plane_config);
>>>> }
>>>> }
>>> Ok I looked at this and the readout_plane_state function and I think we
>>> have a bit a confusion about responsibilities here. The big thing is that
>>> only driver load cares about reconstructing plane state accurately, for
>>> resume and lid notifier we just want to make sure that we update the
>>> planes. And that could be achieved by unconditionally setting
>>> crtc_state->planes_changed. We already have all the plane states when
>>> restoring state anyway.
>> On resume I force a modeset for this reason, and set the plane_mask.
>> This makes sure any plane gets disabled.
>>
>> The modeset will also add all planes, which sets planes_changed if needed.
> Yeah that's what I had in mind for resume: We need to grab all plane
> states anyway (to be able to restore the old config), so at most we need
> to set a planes_changed to make sure the update happens.
>
>> A commit on its own doesn't do this, when a plane doesn't have a fb
>> it won't disable it on its own because the plane's assumed to be disabled
>> when old_plane_state->fb == NULL and new_plane_state->fb == NULL.
> Not a problem since too many planes doesn't seem to happen in reality. At
> least we didn't have code to force-disable planes on resume/lid_notify
> before, which means we don't suddenly need it now. sanitize_* should only
> fix up stuff that's broken for i915 on real-world machines, not what all
> could be possible.
>
>> I don't know if I can call disable_plane in this loop either, because that will
>> update the watermarks on skylake with the call to intel_update_sprite_watermarks
>> calling skl_update_sprite_wm calling skl_update_wm.
> Hm that sounds like a bug still. Maybe just forget about disabling
> non-primary planes for now on driver load? We don't seem to have any need
> currently either. And for primary planes maybe we can hard-code something
> which just clears the PLANE_ENABLE bit and does nothing else? Kind of a
> super-low-level plane force disable. Similar to how we have a special
> function to force-disable the vga plane.
>
>> We don't even have any watermarks calculated yet, so that will break.
>>> That means we should move readout_plane_state into the above loop. Which
>>> then gets a bit too big, so better extract this into a
>>> intel_reconstruct_plane_state or similar. This function should then do all
>>> the plane state reconstruction.
>>>
>>> That also means we don't have to play tricks with plane_mask like you do.
>>> We simply reconstruct the primary plane (if possible) and force-disable
>>> all the others. Since this only happens at driver load there's no need to
>>> clear out any state for sprite/cursors since it's already fully cleared.
>>>
>>> I think this way we should be able to have everything in one place, and
>>> that should allow us to simplify things a lot.
>> I do this trick for atomic resume, we can't allocate the original fb in that case
>> but I still want to sanitize everything. This either happens because
>> a new primary fb gets committed or the primary fb gets disabled.
> Well on resume we don't care at all about the original fb for two reasons:
> - Anything remotely modern resumes with everything off.
> - We only recover the initial plane from the bios to ensure boot-up is
> completely flicker-free. If we don't reserve that we'll allocate rings
> and other gpu objects in there which isn't pretty.
>
> I don't think we need to sanitize planes either as long as we force a full
> plane update on resume (by forcing planes_changed or similar).
This doesn't work.
If a plane has no fb in software you won't update it with commit_planes_on_crtc,
because old_state->crtc and plane_state->crtc are both NULL.
> And for the lid_restore case the problem hasn't been that the bios changed
> the plane state really, but that it just went ahead and disabled
> everything on its own. That will result in a crtc_enable which will
> restore everything correctly.
>
> Imo we don't need to have a perfect sanitize for everything, this code
> really just fixes up what's actually been broken in real-world machines
> out there. That kind of real-world testing is also why I want to change as
> little as possible in the sanitize_* functions.
>
>>>> @@ -15404,47 +15371,30 @@ static void readout_plane_state(struct intel_crtc *crtc,
>>>> struct intel_plane *p;
>>>> struct drm_plane_state *drm_plane_state;
>>>> bool active = crtc_state->base.active;
>>>> + bool wrong_plane;
>>>>
>>>> - if (active) {
>>>> - crtc_state->quirks |= PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>>>> -
>>>> - /* apply to previous sw state too */
>>>> - to_intel_crtc_state(crtc->base.state)->quirks |=
>>>> - PIPE_CONFIG_QUIRK_INITIAL_PLANES;
>>>> - }
>>>> + wrong_plane = active && !intel_check_plane_mapping(crtc);
>>>> + if (wrong_plane)
>>>> + crtc->pipe = !crtc->pipe;
>>>>
>>>> for_each_intel_plane(crtc->base.dev, p) {
>>>> - bool visible = active;
>>>> -
>>>> if (crtc->pipe != p->pipe)
>>>> continue;
>>>>
>>>> drm_plane_state = p->base.state;
>>>>
>>>> - /* Plane scaler state is not touched here. The first atomic
>>>> - * commit will restore all plane scalers to its old state.
>>>> - */
>>>> -
>>>> - if (active && p->base.type == DRM_PLANE_TYPE_PRIMARY) {
>>>> - visible = primary_get_hw_state(crtc);
>>>> - to_intel_plane_state(drm_plane_state)->visible = visible;
>>>> - } else {
>>>> - /*
>>>> - * unknown state, assume it's off to force a transition
>>>> - * to on when calculating state changes.
>>>> - */
>>>> + if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
>>>> + to_intel_plane_state(drm_plane_state)->visible =
>>>> + primary_get_hw_state(crtc);
>>>> + else
>>>> to_intel_plane_state(drm_plane_state)->visible = false;
>>>> - }
>>>>
>>>> - if (visible) {
>>>> - crtc_state->base.plane_mask |=
>>>> - 1 << drm_plane_index(&p->base);
>>>> - } else if (crtc_state->base.state) {
>>>> - /* Make this unconditional for atomic hw readout. */
>>>> - crtc_state->base.plane_mask &=
>>>> - ~(1 << drm_plane_index(&p->base));
>>>> - }
>>>> + crtc_state->base.plane_mask |=
>>>> + 1 << drm_plane_index(&p->base);
>>>> }
>>>> +
>>>> + if (wrong_plane)
>>>> + crtc->pipe = !crtc->pipe;
>>>> }
>>>>
>>>> static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>>> @@ -15664,6 +15614,9 @@ void intel_modeset_gem_init(struct drm_device *dev)
>>>> update_state_fb(c->primary);
>>>> c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
>>>> }
>>>> + else
>>>> + obj->frontbuffer_bits |=
>>>> + to_intel_plane(c->primary)->frontbuffer_bit;
>>> This is part of plane state reconstruction, no need to move it. The only
>>> reason we have to pin late is that gem isn't initialized yet fully when we
>>> want to reconstruct the modeset state. And that pinning shouldn't ever
>>> fail, it just increments pin_count and writes the ptes (again).
>> Why bother handling the return value at all then?
> To print the warning. I think even the cleanup is pointless since at worst
> we'll underrun the pin count, and we have protection for that already
> (again with a loud warning). If you want you can remove that code.
Ok.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 08/20] drm/i915: fill in more mode members
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (6 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 07/20] drm/i915: Rework primary plane stuff slightly Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2 Maarten Lankhorst
` (12 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fa1102392eca..ee543e1515f1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7743,9 +7743,14 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
mode->flags = pipe_config->base.adjusted_mode.flags;
+ mode->type = DRM_MODE_TYPE_DRIVER;
mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
mode->flags |= pipe_config->base.adjusted_mode.flags;
+
+ mode->hsync = drm_mode_hsync(mode);
+ mode->vrefresh = drm_mode_vrefresh(mode);
+ drm_mode_set_name(mode);
}
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (7 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 08/20] drm/i915: fill in more mode members Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 10:28 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic Maarten Lankhorst
` (11 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Perform a full readout of the state by making sure the mode is set
up correctly atomically.
Also there was a small memory leak by doing the memset, fix this
by calling __drm_atomic_helper_crtc_destroy_state first.
Changes since v1:
- Moved after reworking primary plane and updating mode members.
- Force a modeset calculation by changing mode->type from what the
final mode will be.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++++++-------------------
drivers/gpu/drm/i915/intel_fbdev.c | 9 ++-------
2 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ee543e1515f1..dc4bdb91ad4d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15191,6 +15191,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state);
struct intel_encoder *encoder;
u32 reg;
bool enable;
@@ -15202,6 +15203,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
/* restore vblank interrupts to correct state */
drm_crtc_vblank_reset(&crtc->base);
if (crtc->active) {
+ drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
update_scanline_offset(crtc);
drm_crtc_vblank_on(&crtc->base);
}
@@ -15254,9 +15256,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
crtc->base.state->enable ? "enabled" : "disabled",
crtc->active ? "enabled" : "disabled");
- crtc->base.state->enable = crtc->active;
- crtc->base.state->active = crtc->active;
- crtc->base.enabled = crtc->active;
+ crtc->base.enabled = crtc->base.state->active = crtc->active;
+ WARN_ON(drm_atomic_set_mode_for_crtc(&pipe_config->base, NULL) < 0);
/* Because we only establish the connector -> encoder ->
* crtc links if something is active, this means the
@@ -15412,6 +15413,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
int i;
for_each_intel_crtc(dev, crtc) {
+ __drm_atomic_helper_crtc_destroy_state(&crtc->base, crtc->base.state);
memset(crtc->config, 0, sizeof(*crtc->config));
crtc->config->base.crtc = &crtc->base;
@@ -15420,11 +15422,21 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
crtc->active = dev_priv->display.get_pipe_config(crtc,
crtc->config);
- crtc->base.state->enable = crtc->active;
crtc->base.state->active = crtc->active;
crtc->base.enabled = crtc->active;
crtc->base.hwmode = crtc->config->base.adjusted_mode;
+ if (crtc->base.enabled) {
+ memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
+ intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
+ WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode) < 0);
+
+ /* make sure a initial modeset happens by making sure
+ * mode->type will be different from the final mode
+ */
+ crtc->base.state->mode.type = 0;
+ }
+
readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
@@ -15501,21 +15513,6 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
intel_modeset_readout_hw_state(dev);
- /*
- * Now that we have the config, copy it to each CRTC struct
- * Note that this could go away if we move to using crtc_config
- * checking everywhere.
- */
- for_each_intel_crtc(dev, crtc) {
- if (crtc->active && i915.fastboot) {
- intel_mode_from_pipe_config(&crtc->base.mode,
- crtc->config);
- DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
- crtc->base.base.id);
- drm_mode_debug_printmodeline(&crtc->base.mode);
- }
- }
-
/* HW state is read out, now we need to sanitize this mess. */
for_each_intel_encoder(dev, encoder) {
intel_sanitize_encoder(encoder);
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 3d5bb56477ab..52d20cea182c 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -486,16 +486,11 @@ retry:
* config, not the input mode, which is what crtc->mode
* usually contains. But since our current fastboot
* code puts a mode derived from the post-pfit timings
- * into crtc->mode this works out correctly. We don't
- * use hwmode anywhere right now, so use it for this
- * since the fb helper layer wants a pointer to
- * something we own.
+ * into crtc->mode this works out correctly.
*/
DRM_DEBUG_KMS("looking for current mode on connector %s\n",
connector->name);
- intel_mode_from_pipe_config(&encoder->crtc->hwmode,
- to_intel_crtc(encoder->crtc)->config);
- modes[i] = &encoder->crtc->hwmode;
+ modes[i] = &encoder->crtc->mode;
}
crtcs[i] = new_crtc;
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2.
2015-07-07 7:08 ` [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2 Maarten Lankhorst
@ 2015-07-07 10:28 ` Daniel Vetter
2015-07-13 9:32 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 10:28 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:20AM +0200, Maarten Lankhorst wrote:
> Perform a full readout of the state by making sure the mode is set
> up correctly atomically.
>
> Also there was a small memory leak by doing the memset, fix this
> by calling __drm_atomic_helper_crtc_destroy_state first.
>
> Changes since v1:
> - Moved after reworking primary plane and updating mode members.
> - Force a modeset calculation by changing mode->type from what the
> final mode will be.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
tbh I don't really like mode_from_pipe_config since it goes in reverse.
With the adjust mode of config_compare we can compare different final hw
states and make a call whether they match enough for modeset avoidance or
not. mode_from_pipe_config otoh is a lie on panels where we can do
upscaling, hence I'd like to remove it to avoid confusion.
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 35 ++++++++++++++++-------------------
> drivers/gpu/drm/i915/intel_fbdev.c | 9 ++-------
> 2 files changed, 18 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ee543e1515f1..dc4bdb91ad4d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -15191,6 +15191,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> {
> struct drm_device *dev = crtc->base.dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state);
> struct intel_encoder *encoder;
> u32 reg;
> bool enable;
> @@ -15202,6 +15203,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> /* restore vblank interrupts to correct state */
> drm_crtc_vblank_reset(&crtc->base);
> if (crtc->active) {
> + drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
> update_scanline_offset(crtc);
> drm_crtc_vblank_on(&crtc->base);
> }
> @@ -15254,9 +15256,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
> crtc->base.state->enable ? "enabled" : "disabled",
> crtc->active ? "enabled" : "disabled");
>
> - crtc->base.state->enable = crtc->active;
> - crtc->base.state->active = crtc->active;
> - crtc->base.enabled = crtc->active;
> + crtc->base.enabled = crtc->base.state->active = crtc->active;
> + WARN_ON(drm_atomic_set_mode_for_crtc(&pipe_config->base, NULL) < 0);
>
> /* Because we only establish the connector -> encoder ->
> * crtc links if something is active, this means the
> @@ -15412,6 +15413,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> int i;
>
> for_each_intel_crtc(dev, crtc) {
> + __drm_atomic_helper_crtc_destroy_state(&crtc->base, crtc->base.state);
> memset(crtc->config, 0, sizeof(*crtc->config));
> crtc->config->base.crtc = &crtc->base;
>
> @@ -15420,11 +15422,21 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> crtc->active = dev_priv->display.get_pipe_config(crtc,
> crtc->config);
>
> - crtc->base.state->enable = crtc->active;
> crtc->base.state->active = crtc->active;
> crtc->base.enabled = crtc->active;
> crtc->base.hwmode = crtc->config->base.adjusted_mode;
>
> + if (crtc->base.enabled) {
> + memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
> + intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
> + WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode) < 0);
> +
> + /* make sure a initial modeset happens by making sure
> + * mode->type will be different from the final mode
> + */
> + crtc->base.state->mode.type = 0;
> + }
> +
> readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
>
> DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
> @@ -15501,21 +15513,6 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>
> intel_modeset_readout_hw_state(dev);
>
> - /*
> - * Now that we have the config, copy it to each CRTC struct
> - * Note that this could go away if we move to using crtc_config
> - * checking everywhere.
> - */
> - for_each_intel_crtc(dev, crtc) {
> - if (crtc->active && i915.fastboot) {
> - intel_mode_from_pipe_config(&crtc->base.mode,
> - crtc->config);
> - DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
> - crtc->base.base.id);
> - drm_mode_debug_printmodeline(&crtc->base.mode);
> - }
> - }
> -
> /* HW state is read out, now we need to sanitize this mess. */
> for_each_intel_encoder(dev, encoder) {
> intel_sanitize_encoder(encoder);
> diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> index 3d5bb56477ab..52d20cea182c 100644
> --- a/drivers/gpu/drm/i915/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> @@ -486,16 +486,11 @@ retry:
> * config, not the input mode, which is what crtc->mode
> * usually contains. But since our current fastboot
> * code puts a mode derived from the post-pfit timings
> - * into crtc->mode this works out correctly. We don't
> - * use hwmode anywhere right now, so use it for this
> - * since the fb helper layer wants a pointer to
> - * something we own.
> + * into crtc->mode this works out correctly.
> */
> DRM_DEBUG_KMS("looking for current mode on connector %s\n",
> connector->name);
> - intel_mode_from_pipe_config(&encoder->crtc->hwmode,
> - to_intel_crtc(encoder->crtc)->config);
> - modes[i] = &encoder->crtc->hwmode;
> + modes[i] = &encoder->crtc->mode;
> }
> crtcs[i] = new_crtc;
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2.
2015-07-07 10:28 ` Daniel Vetter
@ 2015-07-13 9:32 ` Maarten Lankhorst
2015-07-13 9:48 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-13 9:32 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 12:28 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:20AM +0200, Maarten Lankhorst wrote:
>> Perform a full readout of the state by making sure the mode is set
>> up correctly atomically.
>>
>> Also there was a small memory leak by doing the memset, fix this
>> by calling __drm_atomic_helper_crtc_destroy_state first.
>>
>> Changes since v1:
>> - Moved after reworking primary plane and updating mode members.
>> - Force a modeset calculation by changing mode->type from what the
>> final mode will be.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> tbh I don't really like mode_from_pipe_config since it goes in reverse.
> With the adjust mode of config_compare we can compare different final hw
> states and make a call whether they match enough for modeset avoidance or
> not. mode_from_pipe_config otoh is a lie on panels where we can do
> upscaling, hence I'd like to remove it to avoid confusion.
What do you want the initial mode to be then?
You need to fill in some mode to satisfy drm_atomic_crtc_check.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2.
2015-07-13 9:32 ` Maarten Lankhorst
@ 2015-07-13 9:48 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-13 9:48 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Mon, Jul 13, 2015 at 11:32:09AM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 12:28 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:20AM +0200, Maarten Lankhorst wrote:
> >> Perform a full readout of the state by making sure the mode is set
> >> up correctly atomically.
> >>
> >> Also there was a small memory leak by doing the memset, fix this
> >> by calling __drm_atomic_helper_crtc_destroy_state first.
> >>
> >> Changes since v1:
> >> - Moved after reworking primary plane and updating mode members.
> >> - Force a modeset calculation by changing mode->type from what the
> >> final mode will be.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > tbh I don't really like mode_from_pipe_config since it goes in reverse.
> > With the adjust mode of config_compare we can compare different final hw
> > states and make a call whether they match enough for modeset avoidance or
> > not. mode_from_pipe_config otoh is a lie on panels where we can do
> > upscaling, hence I'd like to remove it to avoid confusion.
> What do you want the initial mode to be then?
>
> You need to fill in some mode to satisfy drm_atomic_crtc_check.
All zeros? That would make it clear that we have a mode, and that we also
have no idea really what it is ...
Otoh I think you've convinced me now that we indeed do need a real mode
object here to avoid other troubles (i.e. the entire discussion around
initial fbcon modesets). Given that I'd guess even the slightly wrong
fill_in_modes here with the change to set DRIVER_MODE would be ok. As long
as we can guarantee that we'll get a full modeset eventually we should be
fine I hope.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (8 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 09/20] drm/i915: Fill in more crtc state, v2 Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:57 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 11/20] drm/i915: Update power domains on readout Maarten Lankhorst
` (10 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Instead of all the ad-hoc updating, duplicate the old state first before
reading out the hw state, then restore it.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/i915_drv.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 3 +-
drivers/gpu/drm/i915/intel_display.c | 153 +++++++++++++++++------------------
drivers/gpu/drm/i915/intel_drv.h | 12 ---
drivers/gpu/drm/i915/intel_lvds.c | 2 +-
5 files changed, 76 insertions(+), 96 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e44dc0d6656f..db48aee7f140 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -741,7 +741,7 @@ static int i915_drm_resume(struct drm_device *dev)
spin_unlock_irq(&dev_priv->irq_lock);
drm_modeset_lock_all(dev);
- intel_modeset_setup_hw_state(dev, true);
+ intel_display_resume(dev);
drm_modeset_unlock_all(dev);
intel_dp_mst_resume(dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 093d6421dddf..2a78a0ee0f97 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3278,8 +3278,7 @@ extern void intel_modeset_gem_init(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern void intel_connector_unregister(struct intel_connector *);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
-extern void intel_modeset_setup_hw_state(struct drm_device *dev,
- bool force_restore);
+extern void intel_display_resume(struct drm_device *dev);
extern void i915_redisable_vga(struct drm_device *dev);
extern void i915_redisable_vga_power_on(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index dc4bdb91ad4d..222d587ed4ea 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -110,6 +110,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
int num_connectors);
static void intel_pre_disable_primary(struct drm_crtc *crtc);
+static void intel_modeset_setup_hw_state(struct drm_device *dev);
static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
{
@@ -3247,7 +3248,7 @@ void intel_finish_reset(struct drm_device *dev)
dev_priv->display.hpd_irq_setup(dev);
spin_unlock_irq(&dev_priv->irq_lock);
- intel_modeset_setup_hw_state(dev, true);
+ intel_display_resume(dev);
intel_hpd_init(dev_priv);
@@ -10239,7 +10240,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
retry:
ret = drm_modeset_lock(&config->connection_mutex, ctx);
if (ret)
- goto fail_unlock;
+ goto fail;
/*
* Algorithm gets a little messy:
@@ -10257,10 +10258,10 @@ retry:
ret = drm_modeset_lock(&crtc->mutex, ctx);
if (ret)
- goto fail_unlock;
+ goto fail;
ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
if (ret)
- goto fail_unlock;
+ goto fail;
old->dpms_mode = connector->dpms;
old->load_detect_temp = false;
@@ -10279,9 +10280,6 @@ retry:
continue;
if (possible_crtc->state->enable)
continue;
- /* This can occur when applying the pipe A quirk on resume. */
- if (to_intel_crtc(possible_crtc)->new_enabled)
- continue;
crtc = possible_crtc;
break;
@@ -10292,20 +10290,17 @@ retry:
*/
if (!crtc) {
DRM_DEBUG_KMS("no pipe available for load-detect\n");
- goto fail_unlock;
+ goto fail;
}
ret = drm_modeset_lock(&crtc->mutex, ctx);
if (ret)
- goto fail_unlock;
+ goto fail;
ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
if (ret)
- goto fail_unlock;
- intel_encoder->new_crtc = to_intel_crtc(crtc);
- to_intel_connector(connector)->new_encoder = intel_encoder;
+ goto fail;
intel_crtc = to_intel_crtc(crtc);
- intel_crtc->new_enabled = true;
old->dpms_mode = connector->dpms;
old->load_detect_temp = true;
old->release_fb = NULL;
@@ -10373,9 +10368,7 @@ retry:
intel_wait_for_vblank(dev, intel_crtc->pipe);
return true;
- fail:
- intel_crtc->new_enabled = crtc->state->enable;
-fail_unlock:
+fail:
drm_atomic_state_free(state);
state = NULL;
@@ -10421,10 +10414,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
if (IS_ERR(crtc_state))
goto fail;
- to_intel_connector(connector)->new_encoder = NULL;
- intel_encoder->new_crtc = NULL;
- intel_crtc->new_enabled = false;
-
connector_state->best_encoder = NULL;
connector_state->crtc = NULL;
@@ -11827,37 +11816,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.atomic_check = intel_crtc_atomic_check,
};
-/**
- * intel_modeset_update_staged_output_state
- *
- * Updates the staged output configuration state, e.g. after we've read out the
- * current hw state.
- */
-static void intel_modeset_update_staged_output_state(struct drm_device *dev)
-{
- struct intel_crtc *crtc;
- struct intel_encoder *encoder;
- struct intel_connector *connector;
-
- for_each_intel_connector(dev, connector) {
- connector->new_encoder =
- to_intel_encoder(connector->base.encoder);
- }
-
- for_each_intel_encoder(dev, encoder) {
- encoder->new_crtc =
- to_intel_crtc(encoder->base.crtc);
- }
-
- for_each_intel_crtc(dev, crtc) {
- crtc->new_enabled = crtc->base.state->enable;
- }
-}
-
-/* Transitional helper to copy current connector/encoder state to
- * connector->state. This is needed so that code that is partially
- * converted to atomic does the right thing.
- */
static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
{
struct intel_connector *connector;
@@ -12297,7 +12255,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
}
drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
- intel_modeset_update_staged_output_state(state->dev);
/* Double check state. */
for_each_crtc(dev, crtc) {
@@ -12688,11 +12645,14 @@ check_connector_state(struct drm_device *dev)
struct intel_connector *connector;
for_each_intel_connector(dev, connector) {
+ struct drm_encoder *encoder = connector->base.encoder;
+ struct drm_connector_state *state = connector->base.state;
+
/* This also checks the encoder/connector hw state with the
* ->get_hw_state callbacks. */
intel_connector_check_state(connector);
- I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
+ I915_STATE_WARN(state->best_encoder != encoder,
"connector's staged encoder doesn't match current encoder\n");
}
}
@@ -12712,8 +12672,6 @@ check_encoder_state(struct drm_device *dev)
encoder->base.base.id,
encoder->base.name);
- I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
- "encoder's stage crtc doesn't match current crtc\n");
I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
"encoder's active_connectors set, but no crtc\n");
@@ -12723,6 +12681,10 @@ check_encoder_state(struct drm_device *dev)
enabled = true;
if (connector->base.dpms != DRM_MODE_DPMS_OFF)
active = true;
+
+ I915_STATE_WARN(connector->base.state->crtc !=
+ encoder->base.crtc,
+ "encoder's stage crtc doesn't match current crtc\n");
}
/*
* for MST connectors if we unplug the connector is gone
@@ -13282,11 +13244,12 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
* need to copy the staged config to the atomic state, otherwise the
* mode set will just reapply the state the HW is already in. */
for_each_intel_encoder(dev, encoder) {
- if (&encoder->new_crtc->base != crtc)
+ if (encoder->base.crtc != crtc)
continue;
for_each_intel_connector(dev, connector) {
- if (connector->new_encoder != encoder)
+ if (connector->base.state->best_encoder !=
+ &encoder->base)
continue;
connector_state = drm_atomic_get_connector_state(state, &connector->base);
@@ -13299,7 +13262,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
}
connector_state->crtc = crtc;
- connector_state->best_encoder = &encoder->base;
}
}
@@ -13311,9 +13273,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
return;
}
- crtc_state->base.active = crtc_state->base.enable =
- to_intel_crtc(crtc)->new_enabled;
-
drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
@@ -15112,7 +15071,7 @@ void intel_modeset_init(struct drm_device *dev)
intel_fbc_disable(dev);
drm_modeset_lock_all(dev);
- intel_modeset_setup_hw_state(dev, false);
+ intel_modeset_setup_hw_state(dev);
drm_modeset_unlock_all(dev);
for_each_intel_crtc(dev, crtc) {
@@ -15500,10 +15459,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
}
}
-/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
- * and i915 state tracking structures. */
-void intel_modeset_setup_hw_state(struct drm_device *dev,
- bool force_restore)
+/* Scan out the current hw modeset state,
+ * and sanitizes it to the current state
+ */
+static void
+intel_modeset_setup_hw_state(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe;
@@ -15545,25 +15505,58 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
skl_wm_get_hw_state(dev);
else if (HAS_PCH_SPLIT(dev))
ilk_wm_get_hw_state(dev);
+}
- if (force_restore) {
- i915_redisable_vga(dev);
+void intel_display_resume(struct drm_device *dev)
+{
+ struct drm_atomic_state *state = drm_atomic_state_alloc(dev);
+ struct intel_connector *conn;
+ struct intel_plane *plane;
+ struct drm_crtc *crtc;
+ int ret;
- /*
- * We need to use raw interfaces for restoring state to avoid
- * checking (bogus) intermediate states.
- */
- for_each_pipe(dev_priv, pipe) {
- struct drm_crtc *crtc =
- dev_priv->pipe_to_crtc_mapping[pipe];
+ if (!state)
+ return;
- intel_crtc_restore_mode(crtc);
- }
- } else {
- intel_modeset_update_staged_output_state(dev);
+ state->acquire_ctx = dev->mode_config.acquire_ctx;
+
+ /* preserve complete old state, including dpll */
+ intel_atomic_get_shared_dpll_state(state);
+
+ for_each_crtc(dev, crtc) {
+ struct drm_crtc_state *crtc_state =
+ drm_atomic_get_crtc_state(state, crtc);
+
+ ret = PTR_ERR_OR_ZERO(crtc_state);
+ if (ret)
+ goto err;
+
+ /* force a restore */
+ crtc_state->mode_changed = true;
+ }
+
+ for_each_intel_plane(dev, plane) {
+ ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(state, &plane->base));
+ if (ret)
+ goto err;
+ }
+
+ for_each_intel_connector(dev, conn) {
+ ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(state, &conn->base));
+ if (ret)
+ goto err;
}
- intel_modeset_check_state(dev);
+ intel_modeset_setup_hw_state(dev);
+
+ i915_redisable_vga(dev);
+ ret = intel_set_mode(state);
+ if (!ret)
+ return;
+
+err:
+ DRM_ERROR("Restoring old state failed with %i\n", ret);
+ drm_atomic_state_free(state);
}
void intel_modeset_gem_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c3cea178c809..97b65749f472 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -130,11 +130,6 @@ struct intel_fbdev {
struct intel_encoder {
struct drm_encoder base;
- /*
- * The new crtc this encoder will be driven from. Only differs from
- * base->crtc while a modeset is in progress.
- */
- struct intel_crtc *new_crtc;
enum intel_output_type type;
unsigned int cloneable;
@@ -195,12 +190,6 @@ struct intel_connector {
*/
struct intel_encoder *encoder;
- /*
- * The new encoder this connector will be driven. Only differs from
- * encoder while a modeset is in progress.
- */
- struct intel_encoder *new_encoder;
-
/* Reads out the current hw, returning true if the connector is enabled
* and active (i.e. dpms ON state). */
bool (*get_hw_state)(struct intel_connector *);
@@ -550,7 +539,6 @@ struct intel_crtc {
uint32_t cursor_base;
struct intel_crtc_state *config;
- bool new_enabled;
/* reset counter value when the last flip was submitted */
unsigned int reset_counter;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index ea85547611a5..a63d18680623 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -452,7 +452,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
*/
if (!HAS_PCH_SPLIT(dev)) {
drm_modeset_lock_all(dev);
- intel_modeset_setup_hw_state(dev, true);
+ intel_display_resume(dev);
drm_modeset_unlock_all(dev);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic.
2015-07-07 7:08 ` [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic Maarten Lankhorst
@ 2015-07-07 9:57 ` Daniel Vetter
2015-07-07 10:33 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:57 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:21AM +0200, Maarten Lankhorst wrote:
> Instead of all the ad-hoc updating, duplicate the old state first before
> reading out the hw state, then restore it.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.c | 2 +-
> drivers/gpu/drm/i915/i915_drv.h | 3 +-
> drivers/gpu/drm/i915/intel_display.c | 153 +++++++++++++++++------------------
> drivers/gpu/drm/i915/intel_drv.h | 12 ---
> drivers/gpu/drm/i915/intel_lvds.c | 2 +-
> 5 files changed, 76 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index e44dc0d6656f..db48aee7f140 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -741,7 +741,7 @@ static int i915_drm_resume(struct drm_device *dev)
> spin_unlock_irq(&dev_priv->irq_lock);
>
> drm_modeset_lock_all(dev);
> - intel_modeset_setup_hw_state(dev, true);
> + intel_display_resume(dev);
> drm_modeset_unlock_all(dev);
>
> intel_dp_mst_resume(dev);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 093d6421dddf..2a78a0ee0f97 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3278,8 +3278,7 @@ extern void intel_modeset_gem_init(struct drm_device *dev);
> extern void intel_modeset_cleanup(struct drm_device *dev);
> extern void intel_connector_unregister(struct intel_connector *);
> extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
> -extern void intel_modeset_setup_hw_state(struct drm_device *dev,
> - bool force_restore);
> +extern void intel_display_resume(struct drm_device *dev);
> extern void i915_redisable_vga(struct drm_device *dev);
> extern void i915_redisable_vga_power_on(struct drm_device *dev);
> extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index dc4bdb91ad4d..222d587ed4ea 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -110,6 +110,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> int num_connectors);
> static void intel_pre_disable_primary(struct drm_crtc *crtc);
> +static void intel_modeset_setup_hw_state(struct drm_device *dev);
>
> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
> {
> @@ -3247,7 +3248,7 @@ void intel_finish_reset(struct drm_device *dev)
> dev_priv->display.hpd_irq_setup(dev);
> spin_unlock_irq(&dev_priv->irq_lock);
>
> - intel_modeset_setup_hw_state(dev, true);
> + intel_display_resume(dev);
>
> intel_hpd_init(dev_priv);
>
> @@ -10239,7 +10240,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
> retry:
> ret = drm_modeset_lock(&config->connection_mutex, ctx);
> if (ret)
> - goto fail_unlock;
> + goto fail;
>
> /*
> * Algorithm gets a little messy:
> @@ -10257,10 +10258,10 @@ retry:
>
> ret = drm_modeset_lock(&crtc->mutex, ctx);
> if (ret)
> - goto fail_unlock;
> + goto fail;
> ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
> if (ret)
> - goto fail_unlock;
> + goto fail;
>
> old->dpms_mode = connector->dpms;
> old->load_detect_temp = false;
> @@ -10279,9 +10280,6 @@ retry:
> continue;
> if (possible_crtc->state->enable)
> continue;
> - /* This can occur when applying the pipe A quirk on resume. */
> - if (to_intel_crtc(possible_crtc)->new_enabled)
> - continue;
>
> crtc = possible_crtc;
> break;
> @@ -10292,20 +10290,17 @@ retry:
> */
> if (!crtc) {
> DRM_DEBUG_KMS("no pipe available for load-detect\n");
> - goto fail_unlock;
> + goto fail;
> }
>
> ret = drm_modeset_lock(&crtc->mutex, ctx);
> if (ret)
> - goto fail_unlock;
> + goto fail;
> ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
> if (ret)
> - goto fail_unlock;
> - intel_encoder->new_crtc = to_intel_crtc(crtc);
> - to_intel_connector(connector)->new_encoder = intel_encoder;
> + goto fail;
>
> intel_crtc = to_intel_crtc(crtc);
> - intel_crtc->new_enabled = true;
> old->dpms_mode = connector->dpms;
> old->load_detect_temp = true;
> old->release_fb = NULL;
> @@ -10373,9 +10368,7 @@ retry:
> intel_wait_for_vblank(dev, intel_crtc->pipe);
> return true;
>
> - fail:
> - intel_crtc->new_enabled = crtc->state->enable;
> -fail_unlock:
> +fail:
> drm_atomic_state_free(state);
> state = NULL;
>
> @@ -10421,10 +10414,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
> if (IS_ERR(crtc_state))
> goto fail;
>
> - to_intel_connector(connector)->new_encoder = NULL;
> - intel_encoder->new_crtc = NULL;
> - intel_crtc->new_enabled = false;
load_detect changes should be a separate patch. Or the commit message
needs to explain why this needs to be one.
> -
> connector_state->best_encoder = NULL;
> connector_state->crtc = NULL;
>
> @@ -11827,37 +11816,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
> .atomic_check = intel_crtc_atomic_check,
> };
>
> -/**
> - * intel_modeset_update_staged_output_state
> - *
> - * Updates the staged output configuration state, e.g. after we've read out the
> - * current hw state.
> - */
> -static void intel_modeset_update_staged_output_state(struct drm_device *dev)
> -{
> - struct intel_crtc *crtc;
> - struct intel_encoder *encoder;
> - struct intel_connector *connector;
> -
> - for_each_intel_connector(dev, connector) {
> - connector->new_encoder =
> - to_intel_encoder(connector->base.encoder);
> - }
> -
> - for_each_intel_encoder(dev, encoder) {
> - encoder->new_crtc =
> - to_intel_crtc(encoder->base.crtc);
> - }
> -
> - for_each_intel_crtc(dev, crtc) {
> - crtc->new_enabled = crtc->base.state->enable;
> - }
> -}
Hm, more stuff squashed in which can be only removed as a consequence of
the restore code rework. Separate patch again imo.
> -
> -/* Transitional helper to copy current connector/encoder state to
> - * connector->state. This is needed so that code that is partially
> - * converted to atomic does the right thing.
> - */
> static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
> {
> struct intel_connector *connector;
> @@ -12297,7 +12255,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
> }
>
> drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
> - intel_modeset_update_staged_output_state(state->dev);
>
> /* Double check state. */
> for_each_crtc(dev, crtc) {
> @@ -12688,11 +12645,14 @@ check_connector_state(struct drm_device *dev)
> struct intel_connector *connector;
>
> for_each_intel_connector(dev, connector) {
> + struct drm_encoder *encoder = connector->base.encoder;
> + struct drm_connector_state *state = connector->base.state;
> +
> /* This also checks the encoder/connector hw state with the
> * ->get_hw_state callbacks. */
> intel_connector_check_state(connector);
>
> - I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
> + I915_STATE_WARN(state->best_encoder != encoder,
> "connector's staged encoder doesn't match current encoder\n");
> }
> }
> @@ -12712,8 +12672,6 @@ check_encoder_state(struct drm_device *dev)
> encoder->base.base.id,
> encoder->base.name);
>
> - I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
> - "encoder's stage crtc doesn't match current crtc\n");
> I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
> "encoder's active_connectors set, but no crtc\n");
>
> @@ -12723,6 +12681,10 @@ check_encoder_state(struct drm_device *dev)
> enabled = true;
> if (connector->base.dpms != DRM_MODE_DPMS_OFF)
> active = true;
> +
> + I915_STATE_WARN(connector->base.state->crtc !=
> + encoder->base.crtc,
> + "encoder's stage crtc doesn't match current crtc\n");
> }
> /*
> * for MST connectors if we unplug the connector is gone
Same for adapting the check functions. Probably ok in the removeal of the
legacy new_* pointers though.
> @@ -13282,11 +13244,12 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
> * need to copy the staged config to the atomic state, otherwise the
> * mode set will just reapply the state the HW is already in. */
> for_each_intel_encoder(dev, encoder) {
> - if (&encoder->new_crtc->base != crtc)
> + if (encoder->base.crtc != crtc)
> continue;
>
> for_each_intel_connector(dev, connector) {
> - if (connector->new_encoder != encoder)
> + if (connector->base.state->best_encoder !=
> + &encoder->base)
> continue;
>
> connector_state = drm_atomic_get_connector_state(state, &connector->base);
> @@ -13299,7 +13262,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
> }
>
> connector_state->crtc = crtc;
> - connector_state->best_encoder = &encoder->base;
> }
> }
>
> @@ -13311,9 +13273,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
> return;
> }
>
> - crtc_state->base.active = crtc_state->base.enable =
> - to_intel_crtc(crtc)->new_enabled;
> -
> drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
>
> intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
Same about restore_mode & new_* state.
> @@ -15112,7 +15071,7 @@ void intel_modeset_init(struct drm_device *dev)
> intel_fbc_disable(dev);
>
> drm_modeset_lock_all(dev);
> - intel_modeset_setup_hw_state(dev, false);
> + intel_modeset_setup_hw_state(dev);
> drm_modeset_unlock_all(dev);
>
> for_each_intel_crtc(dev, crtc) {
> @@ -15500,10 +15459,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> }
> }
>
> -/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
> - * and i915 state tracking structures. */
> -void intel_modeset_setup_hw_state(struct drm_device *dev,
> - bool force_restore)
> +/* Scan out the current hw modeset state,
> + * and sanitizes it to the current state
> + */
> +static void
> +intel_modeset_setup_hw_state(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> enum pipe pipe;
> @@ -15545,25 +15505,58 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
> skl_wm_get_hw_state(dev);
> else if (HAS_PCH_SPLIT(dev))
> ilk_wm_get_hw_state(dev);
> +}
>
> - if (force_restore) {
> - i915_redisable_vga(dev);
> +void intel_display_resume(struct drm_device *dev)
> +{
> + struct drm_atomic_state *state = drm_atomic_state_alloc(dev);
Putting real functions into initializers is a bit surprising, imo better
on it's own line right before the check.
> + struct intel_connector *conn;
> + struct intel_plane *plane;
> + struct drm_crtc *crtc;
> + int ret;
>
> - /*
> - * We need to use raw interfaces for restoring state to avoid
> - * checking (bogus) intermediate states.
> - */
> - for_each_pipe(dev_priv, pipe) {
> - struct drm_crtc *crtc =
> - dev_priv->pipe_to_crtc_mapping[pipe];
> + if (!state)
debug output missing that the state alloc failed. Perhaps just goto fail;
since state_free can cope with a NULL state.
> + return;
>
> - intel_crtc_restore_mode(crtc);
> - }
> - } else {
> - intel_modeset_update_staged_output_state(dev);
> + state->acquire_ctx = dev->mode_config.acquire_ctx;
> +
> + /* preserve complete old state, including dpll */
> + intel_atomic_get_shared_dpll_state(state);
> +
> + for_each_crtc(dev, crtc) {
> + struct drm_crtc_state *crtc_state =
> + drm_atomic_get_crtc_state(state, crtc);
> +
> + ret = PTR_ERR_OR_ZERO(crtc_state);
> + if (ret)
> + goto err;
> +
> + /* force a restore */
> + crtc_state->mode_changed = true;
> + }
> +
> + for_each_intel_plane(dev, plane) {
> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(state, &plane->base));
> + if (ret)
> + goto err;
> + }
> +
> + for_each_intel_connector(dev, conn) {
> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(state, &conn->base));
> + if (ret)
> + goto err;
> }
>
> - intel_modeset_check_state(dev);
> + intel_modeset_setup_hw_state(dev);
> +
> + i915_redisable_vga(dev);
Since we've only badly bruised escape this trap I think this deserves a
comment:
/*
* WARNING: We can't do a full atomic modeset including
* compute/check phase here since especially encoder
* compute_config functions depend upon output detection state.
* And that's just not yet available at driver load. Therefore we
* must read out the entire relevant hw state (including any
* driver internal state) faithfully here and only apply the
* commit side.
*/
Hm, makes me think ... should we end up calling just dev->atomic_commit(state) here
once atomic modeset is fully working?
> + ret = intel_set_mode(state);
> + if (!ret)
> + return;
> +
> +err:
> + DRM_ERROR("Restoring old state failed with %i\n", ret);
> + drm_atomic_state_free(state);
> }
>
> void intel_modeset_gem_init(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index c3cea178c809..97b65749f472 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -130,11 +130,6 @@ struct intel_fbdev {
>
> struct intel_encoder {
> struct drm_encoder base;
> - /*
> - * The new crtc this encoder will be driven from. Only differs from
> - * base->crtc while a modeset is in progress.
> - */
> - struct intel_crtc *new_crtc;
>
> enum intel_output_type type;
> unsigned int cloneable;
> @@ -195,12 +190,6 @@ struct intel_connector {
> */
> struct intel_encoder *encoder;
>
> - /*
> - * The new encoder this connector will be driven. Only differs from
> - * encoder while a modeset is in progress.
> - */
> - struct intel_encoder *new_encoder;
> -
> /* Reads out the current hw, returning true if the connector is enabled
> * and active (i.e. dpms ON state). */
> bool (*get_hw_state)(struct intel_connector *);
> @@ -550,7 +539,6 @@ struct intel_crtc {
> uint32_t cursor_base;
>
> struct intel_crtc_state *config;
> - bool new_enabled;
>
> /* reset counter value when the last flip was submitted */
> unsigned int reset_counter;
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index ea85547611a5..a63d18680623 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -452,7 +452,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
> */
> if (!HAS_PCH_SPLIT(dev)) {
> drm_modeset_lock_all(dev);
> - intel_modeset_setup_hw_state(dev, true);
> + intel_display_resume(dev);
Would imo be nice to mention this small refactoring in the commit message.
-Daniel
> drm_modeset_unlock_all(dev);
> }
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic.
2015-07-07 9:57 ` Daniel Vetter
@ 2015-07-07 10:33 ` Maarten Lankhorst
2015-07-07 13:14 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:33 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 11:57 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:21AM +0200, Maarten Lankhorst wrote:
>> Instead of all the ad-hoc updating, duplicate the old state first before
>> reading out the hw state, then restore it.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/i915_drv.c | 2 +-
>> drivers/gpu/drm/i915/i915_drv.h | 3 +-
>> drivers/gpu/drm/i915/intel_display.c | 153 +++++++++++++++++------------------
>> drivers/gpu/drm/i915/intel_drv.h | 12 ---
>> drivers/gpu/drm/i915/intel_lvds.c | 2 +-
>> 5 files changed, 76 insertions(+), 96 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>> index e44dc0d6656f..db48aee7f140 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -741,7 +741,7 @@ static int i915_drm_resume(struct drm_device *dev)
>> spin_unlock_irq(&dev_priv->irq_lock);
>>
>> drm_modeset_lock_all(dev);
>> - intel_modeset_setup_hw_state(dev, true);
>> + intel_display_resume(dev);
>> drm_modeset_unlock_all(dev);
>>
>> intel_dp_mst_resume(dev);
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 093d6421dddf..2a78a0ee0f97 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -3278,8 +3278,7 @@ extern void intel_modeset_gem_init(struct drm_device *dev);
>> extern void intel_modeset_cleanup(struct drm_device *dev);
>> extern void intel_connector_unregister(struct intel_connector *);
>> extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
>> -extern void intel_modeset_setup_hw_state(struct drm_device *dev,
>> - bool force_restore);
>> +extern void intel_display_resume(struct drm_device *dev);
>> extern void i915_redisable_vga(struct drm_device *dev);
>> extern void i915_redisable_vga_power_on(struct drm_device *dev);
>> extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index dc4bdb91ad4d..222d587ed4ea 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -110,6 +110,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
>> static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
>> int num_connectors);
>> static void intel_pre_disable_primary(struct drm_crtc *crtc);
>> +static void intel_modeset_setup_hw_state(struct drm_device *dev);
>>
>> static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
>> {
>> @@ -3247,7 +3248,7 @@ void intel_finish_reset(struct drm_device *dev)
>> dev_priv->display.hpd_irq_setup(dev);
>> spin_unlock_irq(&dev_priv->irq_lock);
>>
>> - intel_modeset_setup_hw_state(dev, true);
>> + intel_display_resume(dev);
>>
>> intel_hpd_init(dev_priv);
>>
>> @@ -10239,7 +10240,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
>> retry:
>> ret = drm_modeset_lock(&config->connection_mutex, ctx);
>> if (ret)
>> - goto fail_unlock;
>> + goto fail;
>>
>> /*
>> * Algorithm gets a little messy:
>> @@ -10257,10 +10258,10 @@ retry:
>>
>> ret = drm_modeset_lock(&crtc->mutex, ctx);
>> if (ret)
>> - goto fail_unlock;
>> + goto fail;
>> ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
>> if (ret)
>> - goto fail_unlock;
>> + goto fail;
>>
>> old->dpms_mode = connector->dpms;
>> old->load_detect_temp = false;
>> @@ -10279,9 +10280,6 @@ retry:
>> continue;
>> if (possible_crtc->state->enable)
>> continue;
>> - /* This can occur when applying the pipe A quirk on resume. */
>> - if (to_intel_crtc(possible_crtc)->new_enabled)
>> - continue;
>>
>> crtc = possible_crtc;
>> break;
>> @@ -10292,20 +10290,17 @@ retry:
>> */
>> if (!crtc) {
>> DRM_DEBUG_KMS("no pipe available for load-detect\n");
>> - goto fail_unlock;
>> + goto fail;
>> }
>>
>> ret = drm_modeset_lock(&crtc->mutex, ctx);
>> if (ret)
>> - goto fail_unlock;
>> + goto fail;
>> ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
>> if (ret)
>> - goto fail_unlock;
>> - intel_encoder->new_crtc = to_intel_crtc(crtc);
>> - to_intel_connector(connector)->new_encoder = intel_encoder;
>> + goto fail;
>>
>> intel_crtc = to_intel_crtc(crtc);
>> - intel_crtc->new_enabled = true;
>> old->dpms_mode = connector->dpms;
>> old->load_detect_temp = true;
>> old->release_fb = NULL;
>> @@ -10373,9 +10368,7 @@ retry:
>> intel_wait_for_vblank(dev, intel_crtc->pipe);
>> return true;
>>
>> - fail:
>> - intel_crtc->new_enabled = crtc->state->enable;
>> -fail_unlock:
>> +fail:
>> drm_atomic_state_free(state);
>> state = NULL;
>>
>> @@ -10421,10 +10414,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
>> if (IS_ERR(crtc_state))
>> goto fail;
>>
>> - to_intel_connector(connector)->new_encoder = NULL;
>> - intel_encoder->new_crtc = NULL;
>> - intel_crtc->new_enabled = false;
> load_detect changes should be a separate patch. Or the commit message
> needs to explain why this needs to be one.
These members no longer exist. ;-) all the new_ stuff was to restore things pre-atomic, the atomic updates are good enough here.
Making it a separate patch's probably ok.
>> -
>> connector_state->best_encoder = NULL;
>> connector_state->crtc = NULL;
>>
>> @@ -11827,37 +11816,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
>> .atomic_check = intel_crtc_atomic_check,
>> };
>>
>> -/**
>> - * intel_modeset_update_staged_output_state
>> - *
>> - * Updates the staged output configuration state, e.g. after we've read out the
>> - * current hw state.
>> - */
>> -static void intel_modeset_update_staged_output_state(struct drm_device *dev)
>> -{
>> - struct intel_crtc *crtc;
>> - struct intel_encoder *encoder;
>> - struct intel_connector *connector;
>> -
>> - for_each_intel_connector(dev, connector) {
>> - connector->new_encoder =
>> - to_intel_encoder(connector->base.encoder);
>> - }
>> -
>> - for_each_intel_encoder(dev, encoder) {
>> - encoder->new_crtc =
>> - to_intel_crtc(encoder->base.crtc);
>> - }
>> -
>> - for_each_intel_crtc(dev, crtc) {
>> - crtc->new_enabled = crtc->base.state->enable;
>> - }
>> -}
> Hm, more stuff squashed in which can be only removed as a consequence of
> the restore code rework. Separate patch again imo.
>
>> -
>> -/* Transitional helper to copy current connector/encoder state to
>> - * connector->state. This is needed so that code that is partially
>> - * converted to atomic does the right thing.
>> - */
>> static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
>> {
>> struct intel_connector *connector;
>> @@ -12297,7 +12255,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>> }
>>
>> drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
>> - intel_modeset_update_staged_output_state(state->dev);
>>
>> /* Double check state. */
>> for_each_crtc(dev, crtc) {
>> @@ -12688,11 +12645,14 @@ check_connector_state(struct drm_device *dev)
>> struct intel_connector *connector;
>>
>> for_each_intel_connector(dev, connector) {
>> + struct drm_encoder *encoder = connector->base.encoder;
>> + struct drm_connector_state *state = connector->base.state;
>> +
>> /* This also checks the encoder/connector hw state with the
>> * ->get_hw_state callbacks. */
>> intel_connector_check_state(connector);
>>
>> - I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
>> + I915_STATE_WARN(state->best_encoder != encoder,
>> "connector's staged encoder doesn't match current encoder\n");
>> }
>> }
>> @@ -12712,8 +12672,6 @@ check_encoder_state(struct drm_device *dev)
>> encoder->base.base.id,
>> encoder->base.name);
>>
>> - I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
>> - "encoder's stage crtc doesn't match current crtc\n");
>> I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
>> "encoder's active_connectors set, but no crtc\n");
>>
>> @@ -12723,6 +12681,10 @@ check_encoder_state(struct drm_device *dev)
>> enabled = true;
>> if (connector->base.dpms != DRM_MODE_DPMS_OFF)
>> active = true;
>> +
>> + I915_STATE_WARN(connector->base.state->crtc !=
>> + encoder->base.crtc,
>> + "encoder's stage crtc doesn't match current crtc\n");
>> }
>> /*
>> * for MST connectors if we unplug the connector is gone
> Same for adapting the check functions. Probably ok in the removeal of the
> legacy new_* pointers though.
>
>> @@ -13282,11 +13244,12 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>> * need to copy the staged config to the atomic state, otherwise the
>> * mode set will just reapply the state the HW is already in. */
>> for_each_intel_encoder(dev, encoder) {
>> - if (&encoder->new_crtc->base != crtc)
>> + if (encoder->base.crtc != crtc)
>> continue;
>>
>> for_each_intel_connector(dev, connector) {
>> - if (connector->new_encoder != encoder)
>> + if (connector->base.state->best_encoder !=
>> + &encoder->base)
>> continue;
>>
>> connector_state = drm_atomic_get_connector_state(state, &connector->base);
>> @@ -13299,7 +13262,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>> }
>>
>> connector_state->crtc = crtc;
>> - connector_state->best_encoder = &encoder->base;
>> }
>> }
>>
>> @@ -13311,9 +13273,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>> return;
>> }
>>
>> - crtc_state->base.active = crtc_state->base.enable =
>> - to_intel_crtc(crtc)->new_enabled;
>> -
>> drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
>>
>> intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
> Same about restore_mode & new_* state.
They were for tracking purposes and now gone.
>> @@ -15112,7 +15071,7 @@ void intel_modeset_init(struct drm_device *dev)
>> intel_fbc_disable(dev);
>>
>> drm_modeset_lock_all(dev);
>> - intel_modeset_setup_hw_state(dev, false);
>> + intel_modeset_setup_hw_state(dev);
>> drm_modeset_unlock_all(dev);
>>
>> for_each_intel_crtc(dev, crtc) {
>> @@ -15500,10 +15459,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>> }
>> }
>>
>> -/* Scan out the current hw modeset state, sanitizes it and maps it into the drm
>> - * and i915 state tracking structures. */
>> -void intel_modeset_setup_hw_state(struct drm_device *dev,
>> - bool force_restore)
>> +/* Scan out the current hw modeset state,
>> + * and sanitizes it to the current state
>> + */
>> +static void
>> +intel_modeset_setup_hw_state(struct drm_device *dev)
>> {
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> enum pipe pipe;
>> @@ -15545,25 +15505,58 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>> skl_wm_get_hw_state(dev);
>> else if (HAS_PCH_SPLIT(dev))
>> ilk_wm_get_hw_state(dev);
>> +}
>>
>> - if (force_restore) {
>> - i915_redisable_vga(dev);
>> +void intel_display_resume(struct drm_device *dev)
>> +{
>> + struct drm_atomic_state *state = drm_atomic_state_alloc(dev);
> Putting real functions into initializers is a bit surprising, imo better
> on it's own line right before the check.
Ok.
>> + struct intel_connector *conn;
>> + struct intel_plane *plane;
>> + struct drm_crtc *crtc;
>> + int ret;
>>
>> - /*
>> - * We need to use raw interfaces for restoring state to avoid
>> - * checking (bogus) intermediate states.
>> - */
>> - for_each_pipe(dev_priv, pipe) {
>> - struct drm_crtc *crtc =
>> - dev_priv->pipe_to_crtc_mapping[pipe];
>> + if (!state)
> debug output missing that the state alloc failed. Perhaps just goto fail;
> since state_free can cope with a NULL state.
It can only fail because of kmalloc, which prints its own warnings.
>> + return;
>>
>> - intel_crtc_restore_mode(crtc);
>> - }
>> - } else {
>> - intel_modeset_update_staged_output_state(dev);
>> + state->acquire_ctx = dev->mode_config.acquire_ctx;
>> +
>> + /* preserve complete old state, including dpll */
>> + intel_atomic_get_shared_dpll_state(state);
>> +
>> + for_each_crtc(dev, crtc) {
>> + struct drm_crtc_state *crtc_state =
>> + drm_atomic_get_crtc_state(state, crtc);
>> +
>> + ret = PTR_ERR_OR_ZERO(crtc_state);
>> + if (ret)
>> + goto err;
>> +
>> + /* force a restore */
>> + crtc_state->mode_changed = true;
>> + }
>> +
>> + for_each_intel_plane(dev, plane) {
>> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(state, &plane->base));
>> + if (ret)
>> + goto err;
>> + }
>> +
>> + for_each_intel_connector(dev, conn) {
>> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(state, &conn->base));
>> + if (ret)
>> + goto err;
>> }
>>
>> - intel_modeset_check_state(dev);
>> + intel_modeset_setup_hw_state(dev);
>> +
>> + i915_redisable_vga(dev);
> Since we've only badly bruised escape this trap I think this deserves a
> comment:
>
> /*
> * WARNING: We can't do a full atomic modeset including
> * compute/check phase here since especially encoder
> * compute_config functions depend upon output detection state.
> * And that's just not yet available at driver load. Therefore we
> * must read out the entire relevant hw state (including any
> * driver internal state) faithfully here and only apply the
> * commit side.
> */
>
> Hm, makes me think ... should we end up calling just dev->atomic_commit(state) here
> once atomic modeset is fully working?
Not for initial hw readout unless you want to call detect in this function for all encoders.. resume's fine probably.
>> + ret = intel_set_mode(state);
>> + if (!ret)
>> + return;
>> +
>> +err:
>> + DRM_ERROR("Restoring old state failed with %i\n", ret);
>> + drm_atomic_state_free(state);
>> }
>>
>> void intel_modeset_gem_init(struct drm_device *dev)
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index c3cea178c809..97b65749f472 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -130,11 +130,6 @@ struct intel_fbdev {
>>
>> struct intel_encoder {
>> struct drm_encoder base;
>> - /*
>> - * The new crtc this encoder will be driven from. Only differs from
>> - * base->crtc while a modeset is in progress.
>> - */
>> - struct intel_crtc *new_crtc;
>>
>> enum intel_output_type type;
>> unsigned int cloneable;
>> @@ -195,12 +190,6 @@ struct intel_connector {
>> */
>> struct intel_encoder *encoder;
>>
>> - /*
>> - * The new encoder this connector will be driven. Only differs from
>> - * encoder while a modeset is in progress.
>> - */
>> - struct intel_encoder *new_encoder;
>> -
>> /* Reads out the current hw, returning true if the connector is enabled
>> * and active (i.e. dpms ON state). */
>> bool (*get_hw_state)(struct intel_connector *);
>> @@ -550,7 +539,6 @@ struct intel_crtc {
>> uint32_t cursor_base;
>>
>> struct intel_crtc_state *config;
>> - bool new_enabled;
>>
>> /* reset counter value when the last flip was submitted */
>> unsigned int reset_counter;
>> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
>> index ea85547611a5..a63d18680623 100644
>> --- a/drivers/gpu/drm/i915/intel_lvds.c
>> +++ b/drivers/gpu/drm/i915/intel_lvds.c
>> @@ -452,7 +452,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
>> */
>> if (!HAS_PCH_SPLIT(dev)) {
>> drm_modeset_lock_all(dev);
>> - intel_modeset_setup_hw_state(dev, true);
>> + intel_display_resume(dev);
> Would imo be nice to mention this small refactoring in the commit message.
>
Ok.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic.
2015-07-07 10:33 ` Maarten Lankhorst
@ 2015-07-07 13:14 ` Daniel Vetter
2015-07-07 13:20 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:14 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 12:33:25PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 11:57 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:21AM +0200, Maarten Lankhorst wrote:
> >> @@ -10421,10 +10414,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
> >> if (IS_ERR(crtc_state))
> >> goto fail;
> >>
> >> - to_intel_connector(connector)->new_encoder = NULL;
> >> - intel_encoder->new_crtc = NULL;
> >> - intel_crtc->new_enabled = false;
> > load_detect changes should be a separate patch. Or the commit message
> > needs to explain why this needs to be one.
> These members no longer exist. ;-) all the new_ stuff was to restore things pre-atomic, the atomic updates are good enough here.
>
> Making it a separate patch's probably ok.
Yeah I think splitting out the new_* removal would address most of my
concerns here.
[snip]
> >> + struct intel_connector *conn;
> >> + struct intel_plane *plane;
> >> + struct drm_crtc *crtc;
> >> + int ret;
> >>
> >> - /*
> >> - * We need to use raw interfaces for restoring state to avoid
> >> - * checking (bogus) intermediate states.
> >> - */
> >> - for_each_pipe(dev_priv, pipe) {
> >> - struct drm_crtc *crtc =
> >> - dev_priv->pipe_to_crtc_mapping[pipe];
> >> + if (!state)
> > debug output missing that the state alloc failed. Perhaps just goto fail;
> > since state_free can cope with a NULL state.
> It can only fail because of kmalloc, which prints its own warnings.
Might still be useful just to have unified error reporting - you need to
guess the caller otherwise which would make debug (if this ever happesn)
harder. But really just a bikeshed.
>
> >> + return;
> >>
> >> - intel_crtc_restore_mode(crtc);
> >> - }
> >> - } else {
> >> - intel_modeset_update_staged_output_state(dev);
> >> + state->acquire_ctx = dev->mode_config.acquire_ctx;
> >> +
> >> + /* preserve complete old state, including dpll */
> >> + intel_atomic_get_shared_dpll_state(state);
> >> +
> >> + for_each_crtc(dev, crtc) {
> >> + struct drm_crtc_state *crtc_state =
> >> + drm_atomic_get_crtc_state(state, crtc);
> >> +
> >> + ret = PTR_ERR_OR_ZERO(crtc_state);
> >> + if (ret)
> >> + goto err;
> >> +
> >> + /* force a restore */
> >> + crtc_state->mode_changed = true;
> >> + }
> >> +
> >> + for_each_intel_plane(dev, plane) {
> >> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_plane_state(state, &plane->base));
> >> + if (ret)
> >> + goto err;
> >> + }
> >> +
> >> + for_each_intel_connector(dev, conn) {
> >> + ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(state, &conn->base));
> >> + if (ret)
> >> + goto err;
> >> }
> >>
> >> - intel_modeset_check_state(dev);
> >> + intel_modeset_setup_hw_state(dev);
> >> +
> >> + i915_redisable_vga(dev);
> > Since we've only badly bruised escape this trap I think this deserves a
> > comment:
> >
> > /*
> > * WARNING: We can't do a full atomic modeset including
> > * compute/check phase here since especially encoder
> > * compute_config functions depend upon output detection state.
> > * And that's just not yet available at driver load. Therefore we
> > * must read out the entire relevant hw state (including any
> > * driver internal state) faithfully here and only apply the
> > * commit side.
> > */
> >
> > Hm, makes me think ... should we end up calling just dev->atomic_commit(state) here
> > once atomic modeset is fully working?
> Not for initial hw readout unless you want to call detect in this function for all encoders.. resume's fine probably.
I meant calling dev->mode_config.funcs->atomic_commit(state) directly,
without calling ->atomic_check at all. That should avoid any state
recomputation (otherwise our check/commit split is botched) and hence be
exactly what we need here. I didn't check how close intel_set_mode is
compared our ->atomic_commit implementation after this series (didn't
apply them all). But I think from a semantic pov those two should match.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic.
2015-07-07 13:14 ` Daniel Vetter
@ 2015-07-07 13:20 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:20 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 03:14:57PM +0200, Daniel Vetter wrote:
> On Tue, Jul 07, 2015 at 12:33:25PM +0200, Maarten Lankhorst wrote:
> > Op 07-07-15 om 11:57 schreef Daniel Vetter:
> > > On Tue, Jul 07, 2015 at 09:08:21AM +0200, Maarten Lankhorst wrote:
> > > Since we've only badly bruised escape this trap I think this deserves a
> > > comment:
> > >
> > > /*
> > > * WARNING: We can't do a full atomic modeset including
> > > * compute/check phase here since especially encoder
> > > * compute_config functions depend upon output detection state.
> > > * And that's just not yet available at driver load. Therefore we
> > > * must read out the entire relevant hw state (including any
> > > * driver internal state) faithfully here and only apply the
> > > * commit side.
> > > */
> > >
> > > Hm, makes me think ... should we end up calling just dev->atomic_commit(state) here
> > > once atomic modeset is fully working?
> > Not for initial hw readout unless you want to call detect in this function for all encoders.. resume's fine probably.
>
> I meant calling dev->mode_config.funcs->atomic_commit(state) directly,
> without calling ->atomic_check at all. That should avoid any state
> recomputation (otherwise our check/commit split is botched) and hence be
> exactly what we need here. I didn't check how close intel_set_mode is
> compared our ->atomic_commit implementation after this series (didn't
> apply them all). But I think from a semantic pov those two should match.
Ah I mixed up intel_set_mode with intel_crtc_set_config, which does a more
elaborate compute_config. I guess this is something we still need to
untangle when we replace all the existing legacy entry points with the
legacy2atomic helpers. Probably needs some shuffling of responsibilities
betwen atomic_check and atomic_commit.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 11/20] drm/i915: Update power domains on readout.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (9 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 10/20] drm/i915: Convert suspend/resume to atomic Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2 Maarten Lankhorst
` (9 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This allows us to get rid of the set_init_power in
modeset_update_crtc_domains. The state should be sanitized enough
after setup_hw_state to not need the init power.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 76 ++++++++++++++++++++++++------------
1 file changed, 50 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 222d587ed4ea..a887bdca53c0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5185,6 +5185,9 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
unsigned long mask;
enum transcoder transcoder;
+ if (!crtc->state->active)
+ return 0;
+
transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
mask = BIT(POWER_DOMAIN_PIPE(pipe));
@@ -5199,27 +5202,46 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
return mask;
}
-static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
+static unsigned long modeset_get_crtc_power_domains(struct drm_crtc *crtc)
{
- struct drm_device *dev = state->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
- struct intel_crtc *crtc;
+ struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ enum intel_display_power_domain domain;
+ unsigned long domains, new_domains, old_domains;
- /*
- * First get all needed power domains, then put all unneeded, to avoid
- * any unnecessary toggling of the power wells.
- */
- for_each_intel_crtc(dev, crtc) {
- enum intel_display_power_domain domain;
+ old_domains = intel_crtc->enabled_power_domains;
+ intel_crtc->enabled_power_domains = new_domains = get_crtc_power_domains(crtc);
- if (!crtc->base.state->enable)
- continue;
+ domains = new_domains & ~old_domains;
+
+ for_each_power_domain(domain, domains)
+ intel_display_power_get(dev_priv, domain);
+
+ return old_domains & ~new_domains;
+}
+
+static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
+ unsigned long domains)
+{
+ enum intel_display_power_domain domain;
+
+ for_each_power_domain(domain, domains)
+ intel_display_power_put(dev_priv, domain);
+}
- pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
+static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
+{
+ struct drm_device *dev = state->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long put_domains[I915_MAX_PIPES] = {};
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc *crtc;
+ int i;
- for_each_power_domain(domain, pipe_domains[crtc->pipe])
- intel_display_power_get(dev_priv, domain);
+ for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ if (needs_modeset(crtc->state))
+ put_domains[to_intel_crtc(crtc)->pipe] =
+ modeset_get_crtc_power_domains(crtc);
}
if (dev_priv->display.modeset_commit_cdclk) {
@@ -5230,16 +5252,9 @@ static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
dev_priv->display.modeset_commit_cdclk(state);
}
- for_each_intel_crtc(dev, crtc) {
- enum intel_display_power_domain domain;
-
- for_each_power_domain(domain, crtc->enabled_power_domains)
- intel_display_power_put(dev_priv, domain);
-
- crtc->enabled_power_domains = pipe_domains[crtc->pipe];
- }
-
- intel_display_set_init_power(dev_priv, false);
+ for (i = 0; i < I915_MAX_PIPES; i++)
+ if (put_domains[i])
+ modeset_put_power_domains(dev_priv, put_domains[i]);
}
static void intel_update_max_cdclk(struct drm_device *dev)
@@ -15505,6 +15520,15 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
skl_wm_get_hw_state(dev);
else if (HAS_PCH_SPLIT(dev))
ilk_wm_get_hw_state(dev);
+
+ for_each_intel_crtc(dev, crtc) {
+ unsigned long put_domains;
+
+ put_domains = modeset_get_crtc_power_domains(&crtc->base);
+ if (WARN_ON(put_domains))
+ modeset_put_power_domains(dev_priv, put_domains);
+ }
+ intel_display_set_init_power(dev_priv, false);
}
void intel_display_resume(struct drm_device *dev)
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (10 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 11/20] drm/i915: Update power domains on readout Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 10:14 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode Maarten Lankhorst
` (8 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Now that we read out the full atomic state we can force fastboot
without hacks. The only thing that we have to worry about is
preventing unneeded modesets. This can be easily done by calculating
if the new state matches the old state, with exception for pfit and
pipe size. Because the original fastboot code only touched pipe size
and panel fitter we can keep that as base options in
pipe_config_compare, and patch it up inside intel_update_pipe_config.
This was causing a black screen on haswell because the hw doesn't set
up csc, so make sure intel_set_pipe_csc is called during crtc
sanitization.
Changes since v1:
- Call intel_set_pipe_csc during sanitize_crtc, thanks for finding it
Daniel Stone!
- Get rid of INHERITED_MODE, the initial mode changes will force a
modeset.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/i915_params.c | 5 --
drivers/gpu/drm/i915/intel_atomic.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 157 ++++++++++++++++++++---------------
drivers/gpu/drm/i915/intel_drv.h | 3 +-
drivers/gpu/drm/i915/intel_fbdev.c | 3 -
5 files changed, 94 insertions(+), 76 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 7983fe48a654..d6f9d9a117b6 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -40,7 +40,6 @@ struct i915_params i915 __read_mostly = {
.preliminary_hw_support = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT),
.disable_power_well = 1,
.enable_ips = 1,
- .fastboot = 0,
.prefault_disable = 0,
.load_detect_test = 0,
.reset = true,
@@ -131,10 +130,6 @@ MODULE_PARM_DESC(disable_power_well,
module_param_named(enable_ips, i915.enable_ips, int, 0600);
MODULE_PARM_DESC(enable_ips, "Enable IPS (default: true)");
-module_param_named(fastboot, i915.fastboot, bool, 0600);
-MODULE_PARM_DESC(fastboot,
- "Try to skip unnecessary mode sets at boot time (default: false)");
-
module_param_named_unsafe(prefault_disable, i915.prefault_disable, bool, 0600);
MODULE_PARM_DESC(prefault_disable,
"Disable page prefaulting for pread/pwrite/reloc (default:false). "
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index b593612a917d..0bbdc2fc5298 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -221,8 +221,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
-
crtc_state->base.crtc = crtc;
+ crtc_state->update_pipe = false;
return &crtc_state->base;
}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a887bdca53c0..16373309dcae 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -110,6 +110,9 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr
static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
int num_connectors);
static void intel_pre_disable_primary(struct drm_crtc *crtc);
+static void skylake_pfit_enable(struct intel_crtc *crtc);
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
+static void ironlake_pfit_enable(struct intel_crtc *crtc);
static void intel_modeset_setup_hw_state(struct drm_device *dev);
static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
@@ -3299,14 +3302,17 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
return pending;
}
-static void intel_update_pipe_size(struct intel_crtc *crtc)
+static void intel_update_pipe_config(struct intel_crtc *crtc,
+ struct intel_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- const struct drm_display_mode *adjusted_mode;
+ struct intel_crtc_state *pipe_config =
+ to_intel_crtc_state(crtc->base.state);
- if (!i915.fastboot)
- return;
+ DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n",
+ old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h,
+ pipe_config->pipe_src_w, pipe_config->pipe_src_h);
/*
* Update pipe size and adjust fitter if needed: the reason for this is
@@ -3315,27 +3321,26 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
* fastboot case, we'll flip, but if we don't update the pipesrc and
* pfit state, we'll end up with a big fb scanned out into the wrong
* sized surface.
- *
- * To fix this properly, we need to hoist the checks up into
- * compute_mode_changes (or above), check the actual pfit state and
- * whether the platform allows pfit disable with pipe active, and only
- * then update the pipesrc and pfit state, even on the flip path.
*/
- adjusted_mode = &crtc->config->base.adjusted_mode;
-
I915_WRITE(PIPESRC(crtc->pipe),
- ((adjusted_mode->crtc_hdisplay - 1) << 16) |
- (adjusted_mode->crtc_vdisplay - 1));
- if (!crtc->config->pch_pfit.enabled &&
- (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
- intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
- I915_WRITE(PF_CTL(crtc->pipe), 0);
- I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
- I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
+ ((pipe_config->pipe_src_w - 1) << 16) |
+ (pipe_config->pipe_src_h - 1));
+
+ /* on skylake this is done by detaching scalers */
+ if (INTEL_INFO(dev)->gen == 9) {
+ skl_detach_scalers(crtc);
+
+ if (pipe_config->pch_pfit.enabled)
+ skylake_pfit_enable(crtc);
+ }
+ else if (INTEL_INFO(dev)->gen < 9 &&
+ HAS_PCH_SPLIT(dev)) {
+ if (pipe_config->pch_pfit.enabled)
+ ironlake_pfit_enable(crtc);
+ else if (old_crtc_state->pch_pfit.enabled)
+ ironlake_pfit_disable(crtc, true);
}
- crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
- crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
}
static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@ -4993,7 +4998,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
}
}
-static void ironlake_pfit_disable(struct intel_crtc *crtc)
+static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5001,7 +5006,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
/* To avoid upsetting the power well on haswell only disable the pfit if
* it's in use. The hw state code will make sure we get this right. */
- if (crtc->config->pch_pfit.enabled) {
+ if (force || crtc->config->pch_pfit.enabled) {
I915_WRITE(PF_CTL(pipe), 0);
I915_WRITE(PF_WIN_POS(pipe), 0);
I915_WRITE(PF_WIN_SZ(pipe), 0);
@@ -5028,7 +5033,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_disable_pipe(intel_crtc);
- ironlake_pfit_disable(intel_crtc);
+ ironlake_pfit_disable(intel_crtc, false);
if (intel_crtc->config->has_pch_encoder)
ironlake_fdi_disable(crtc);
@@ -5088,7 +5093,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
if (INTEL_INFO(dev)->gen == 9)
skylake_scaler_disable(intel_crtc);
else if (INTEL_INFO(dev)->gen < 9)
- ironlake_pfit_disable(intel_crtc);
+ ironlake_pfit_disable(intel_crtc, false);
else
MISSING_CASE(INTEL_INFO(dev)->gen);
@@ -5239,7 +5244,8 @@ static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
int i;
for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (needs_modeset(crtc->state))
+ if (needs_modeset(crtc->state) ||
+ to_intel_crtc_state(crtc->state)->update_pipe)
put_domains[to_intel_crtc(crtc)->pipe] =
modeset_get_crtc_power_domains(crtc);
}
@@ -12331,7 +12337,6 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
base.head) \
if (mask & (1 <<(intel_crtc)->pipe))
-
static bool
intel_compare_m_n(unsigned int m, unsigned int n,
unsigned int m2, unsigned int n2)
@@ -12553,18 +12558,21 @@ intel_pipe_config_compare(struct drm_device *dev,
* Proper atomic modesets with recomputed global state will fix this.
* Until then just don't check gmch state for inherited modes.
*/
- if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
- PIPE_CONF_CHECK_I(gmch_pfit.control);
- /* pfit ratios are autocomputed by the hw on gen4+ */
- if (INTEL_INFO(dev)->gen < 4)
- PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
- PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
- }
+ if (!adjust) {
+ PIPE_CONF_CHECK_I(pipe_src_w);
+ PIPE_CONF_CHECK_I(pipe_src_h);
- PIPE_CONF_CHECK_I(pch_pfit.enabled);
- if (current_config->pch_pfit.enabled) {
- PIPE_CONF_CHECK_I(pch_pfit.pos);
- PIPE_CONF_CHECK_I(pch_pfit.size);
+ PIPE_CONF_CHECK_I(pch_pfit.enabled);
+ if (current_config->pch_pfit.enabled) {
+ PIPE_CONF_CHECK_I(pch_pfit.pos);
+ PIPE_CONF_CHECK_I(pch_pfit.size);
+
+ PIPE_CONF_CHECK_I(gmch_pfit.control);
+ /* pfit ratios are autocomputed by the hw on gen4+ */
+ if (INTEL_INFO(dev)->gen < 4)
+ PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+ PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+ }
}
PIPE_CONF_CHECK_I(scaler_state.scaler_id);
@@ -13048,6 +13056,29 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state)
return ret;
}
+static bool intel_modeset_calc_update_pipe(struct drm_crtc *crtc,
+ struct drm_crtc_state *crtc_state)
+{
+ struct drm_device *dev = crtc->dev;
+ struct intel_crtc_state *pipe_config =
+ to_intel_crtc_state(crtc_state);
+ struct intel_crtc_state *old_state =
+ to_intel_crtc_state(crtc->state);
+
+ if (crtc_state->active_changed || crtc_state->connectors_changed)
+ return false;
+
+ pipe_config->quirks = 0;
+ if (!intel_pipe_config_compare(dev, pipe_config, old_state, true)) {
+ DRM_DEBUG_ATOMIC("[CRTC:%i] new state incompatible, forcing modeset\n",
+ crtc->base.id);
+ return false;
+ }
+ pipe_config->quirks = old_state->quirks & PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
+ DRM_DEBUG_ATOMIC("[CRTC:%i] new state compatible, skipping modeset\n",
+ crtc->base.id);
+ return true;
+}
/* Code that should eventually be part of atomic_check() */
static int intel_modeset_checks(struct drm_atomic_state *state)
@@ -13106,36 +13137,26 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
struct intel_crtc_state *pipe_config =
to_intel_crtc_state(crtc_state);
+ if (!needs_modeset(crtc_state))
+ continue;
+
if (!crtc_state->enable) {
if (needs_modeset(crtc_state))
any_ms = true;
continue;
}
- if (!needs_modeset(crtc_state)) {
- if (!(pipe_config->quirks & PIPE_CONFIG_QUIRK_INHERITED_MODE))
- continue;
-
- ret = drm_atomic_add_affected_connectors(state, crtc);
- if (ret)
- return ret;
- }
-
ret = intel_modeset_pipe_config(crtc, pipe_config);
if (ret)
return ret;
- if (!intel_pipe_config_compare(state->dev,
- to_intel_crtc_state(crtc->state),
- pipe_config, true))
- crtc_state->mode_changed = true;
- else if (!needs_modeset(crtc_state))
- continue;
-
any_ms = true;
+ pipe_config->update_pipe =
+ intel_modeset_calc_update_pipe(crtc, crtc_state);
+ pipe_config->base.mode_changed = !pipe_config->update_pipe;
+
intel_dump_pipe_config(to_intel_crtc(crtc),
- pipe_config,
- "[modeset]");
+ pipe_config, "[modeset]");
}
if (any_ms) {
@@ -13169,6 +13190,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
for_each_crtc_in_state(state, crtc, crtc_state, i) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ any_ms |= to_intel_crtc_state(crtc->state)->update_pipe;
if (!needs_modeset(crtc->state))
continue;
@@ -13478,8 +13500,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
if (ret)
goto out;
- intel_update_pipe_size(to_intel_crtc(set->crtc));
-
ret = intel_set_mode_checked(state);
if (ret) {
DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
@@ -13752,10 +13772,6 @@ intel_commit_primary_plane(struct drm_plane *plane,
if (!crtc->state->active)
return;
- if (state->visible)
- /* FIXME: kill this fastboot hack */
- intel_update_pipe_size(intel_crtc);
-
dev_priv->display.update_primary_plane(crtc, fb, crtc->x, crtc->y);
}
@@ -13775,8 +13791,11 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc_state *old_intel_state =
+ to_intel_crtc_state(old_crtc_state);
+ bool modeset = needs_modeset(crtc->state);
- if (!needs_modeset(crtc->state))
+ if (!modeset)
intel_pre_plane_update(intel_crtc);
if (intel_crtc->atomic.update_wm_pre)
@@ -13790,7 +13809,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
intel_pipe_update_start(intel_crtc,
&intel_crtc->atomic.start_vbl_count);
- if (!needs_modeset(crtc->state) && INTEL_INFO(dev)->gen >= 9)
+ if (modeset)
+ return;
+
+ if (to_intel_crtc_state(crtc->state)->update_pipe)
+ intel_update_pipe_config(intel_crtc, old_intel_state);
+ else if (INTEL_INFO(dev)->gen >= 9)
skl_detach_scalers(intel_crtc);
}
@@ -15180,6 +15204,9 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
update_scanline_offset(crtc);
drm_crtc_vblank_on(&crtc->base);
+
+ if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen > 7)
+ intel_set_pipe_csc(&crtc->base);
}
/* We need to sanitize the plane -> pipe mapping first because this will
@@ -15391,8 +15418,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
memset(crtc->config, 0, sizeof(*crtc->config));
crtc->config->base.crtc = &crtc->base;
- crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
-
crtc->active = dev_priv->display.get_pipe_config(crtc,
crtc->config);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 97b65749f472..525b4137521c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -329,9 +329,10 @@ struct intel_crtc_state {
* accordingly.
*/
#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
-#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */
unsigned long quirks;
+ bool update_pipe;
+
/* Pipe source size (ie. panel fitter input size)
* All planes will be positioned inside this space,
* and get clipped at the edges. */
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 52d20cea182c..220370161aac 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -579,9 +579,6 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
struct intel_crtc *intel_crtc;
unsigned int max_size = 0;
- if (!i915.fastboot)
- return false;
-
/* Find the largest fb */
for_each_crtc(dev, crtc) {
struct drm_i915_gem_object *obj =
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2.
2015-07-07 7:08 ` [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2 Maarten Lankhorst
@ 2015-07-07 10:14 ` Daniel Vetter
2015-07-07 10:34 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 10:14 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:23AM +0200, Maarten Lankhorst wrote:
> @@ -12331,7 +12337,6 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
> base.head) \
> if (mask & (1 <<(intel_crtc)->pipe))
>
> -
> static bool
> intel_compare_m_n(unsigned int m, unsigned int n,
> unsigned int m2, unsigned int n2)
> @@ -12553,18 +12558,21 @@ intel_pipe_config_compare(struct drm_device *dev,
> * Proper atomic modesets with recomputed global state will fix this.
> * Until then just don't check gmch state for inherited modes.
> */
> - if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
> - PIPE_CONF_CHECK_I(gmch_pfit.control);
> - /* pfit ratios are autocomputed by the hw on gen4+ */
> - if (INTEL_INFO(dev)->gen < 4)
> - PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
> - PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
> - }
> + if (!adjust) {
> + PIPE_CONF_CHECK_I(pipe_src_w);
> + PIPE_CONF_CHECK_I(pipe_src_h);
>
> - PIPE_CONF_CHECK_I(pch_pfit.enabled);
> - if (current_config->pch_pfit.enabled) {
> - PIPE_CONF_CHECK_I(pch_pfit.pos);
> - PIPE_CONF_CHECK_I(pch_pfit.size);
> + PIPE_CONF_CHECK_I(pch_pfit.enabled);
> + if (current_config->pch_pfit.enabled) {
> + PIPE_CONF_CHECK_I(pch_pfit.pos);
> + PIPE_CONF_CHECK_I(pch_pfit.size);
> +
> + PIPE_CONF_CHECK_I(gmch_pfit.control);
> + /* pfit ratios are autocomputed by the hw on gen4+ */
> + if (INTEL_INFO(dev)->gen < 4)
> + PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
> + PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
> + }
> }
The above hunk should be indenpendent of fastboot changes, it only
requires us to recompute the pipe config for all crtcs in an update. And
we do that now: When we steal an encoder we add the crtc that encoder was
on, and then also recompute it's config.
Can you please split this out and submit as its own patch. And please
remove the comment too since there's no conditional check any more now.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2.
2015-07-07 10:14 ` Daniel Vetter
@ 2015-07-07 10:34 ` Maarten Lankhorst
0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:34 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 12:14 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:23AM +0200, Maarten Lankhorst wrote:
>> @@ -12331,7 +12337,6 @@ static bool intel_fuzzy_clock_check(int clock1, int clock2)
>> base.head) \
>> if (mask & (1 <<(intel_crtc)->pipe))
>>
>> -
>> static bool
>> intel_compare_m_n(unsigned int m, unsigned int n,
>> unsigned int m2, unsigned int n2)
>> @@ -12553,18 +12558,21 @@ intel_pipe_config_compare(struct drm_device *dev,
>> * Proper atomic modesets with recomputed global state will fix this.
>> * Until then just don't check gmch state for inherited modes.
>> */
>> - if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
>> - PIPE_CONF_CHECK_I(gmch_pfit.control);
>> - /* pfit ratios are autocomputed by the hw on gen4+ */
>> - if (INTEL_INFO(dev)->gen < 4)
>> - PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
>> - PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
>> - }
>> + if (!adjust) {
>> + PIPE_CONF_CHECK_I(pipe_src_w);
>> + PIPE_CONF_CHECK_I(pipe_src_h);
>>
>> - PIPE_CONF_CHECK_I(pch_pfit.enabled);
>> - if (current_config->pch_pfit.enabled) {
>> - PIPE_CONF_CHECK_I(pch_pfit.pos);
>> - PIPE_CONF_CHECK_I(pch_pfit.size);
>> + PIPE_CONF_CHECK_I(pch_pfit.enabled);
>> + if (current_config->pch_pfit.enabled) {
>> + PIPE_CONF_CHECK_I(pch_pfit.pos);
>> + PIPE_CONF_CHECK_I(pch_pfit.size);
>> +
>> + PIPE_CONF_CHECK_I(gmch_pfit.control);
>> + /* pfit ratios are autocomputed by the hw on gen4+ */
>> + if (INTEL_INFO(dev)->gen < 4)
>> + PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
>> + PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
>> + }
>> }
> The above hunk should be indenpendent of fastboot changes, it only
> requires us to recompute the pipe config for all crtcs in an update. And
> we do that now: When we steal an encoder we add the crtc that encoder was
> on, and then also recompute it's config.
>
> Can you please split this out and submit as its own patch. And please
> remove the comment too since there's no conditional check any more now.
> -Daniel
Ok.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (11 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 12/20] drm/i915: skip modeset if compatible, and enable fastboot for everyone, v2 Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 10:17 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2 Maarten Lankhorst
` (7 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
And get rid of things that are no longer true. This function is only
used for forcing a modeset when encoder properties are changed.
All the existing state is fine in this case, only setting mode_changed
will force a full recalculation here, and take all the state needed.
The previous commit will prevent unneeded modesets anyway.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 58 ++++++++++--------------------------
1 file changed, 16 insertions(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 16373309dcae..f7b1fc28142c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13260,63 +13260,37 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
struct drm_atomic_state *state;
- struct intel_encoder *encoder;
- struct intel_connector *connector;
- struct drm_connector_state *connector_state;
- struct intel_crtc_state *crtc_state;
+ struct drm_crtc_state *crtc_state;
int ret;
state = drm_atomic_state_alloc(dev);
if (!state) {
- DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
+ DRM_DEBUG_KMS("[CRTC:%d] crtc restore failed, out of memory",
crtc->base.id);
return;
}
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-
- /* The force restore path in the HW readout code relies on the staged
- * config still keeping the user requested config while the actual
- * state has been overwritten by the configuration read from HW. We
- * need to copy the staged config to the atomic state, otherwise the
- * mode set will just reapply the state the HW is already in. */
- for_each_intel_encoder(dev, encoder) {
- if (encoder->base.crtc != crtc)
- continue;
+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
- for_each_intel_connector(dev, connector) {
- if (connector->base.state->best_encoder !=
- &encoder->base)
- continue;
-
- connector_state = drm_atomic_get_connector_state(state, &connector->base);
- if (IS_ERR(connector_state)) {
- DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
- connector->base.base.id,
- connector->base.name,
- PTR_ERR(connector_state));
- continue;
- }
+retry:
+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
+ ret = PTR_ERR_OR_ZERO(crtc_state);
+ if (!ret) {
+ if (!crtc_state->active)
+ goto out;
- connector_state->crtc = crtc;
- }
+ crtc_state->mode_changed = true;
+ ret = intel_set_mode(state);
}
- crtc_state = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
- if (IS_ERR(crtc_state)) {
- DRM_DEBUG_KMS("Failed to add [CRTC:%d] to state: %ld\n",
- crtc->base.id, PTR_ERR(crtc_state));
- drm_atomic_state_free(state);
- return;
+ if (ret == -EDEADLK) {
+ drm_atomic_state_clear(state);
+ drm_modeset_backoff(state->acquire_ctx);
+ goto retry;
}
- drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
-
- intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
- crtc->primary->fb, crtc->x, crtc->y);
-
- ret = intel_set_mode(state);
if (ret)
+out:
drm_atomic_state_free(state);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode
2015-07-07 7:08 ` [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode Maarten Lankhorst
@ 2015-07-07 10:17 ` Daniel Vetter
2015-07-07 10:48 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 10:17 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:24AM +0200, Maarten Lankhorst wrote:
> And get rid of things that are no longer true. This function is only
> used for forcing a modeset when encoder properties are changed.
>
> All the existing state is fine in this case, only setting mode_changed
> will force a full recalculation here, and take all the state needed.
>
> The previous commit will prevent unneeded modesets anyway.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 58 ++++++++++--------------------------
> 1 file changed, 16 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 16373309dcae..f7b1fc28142c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13260,63 +13260,37 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
> {
> struct drm_device *dev = crtc->dev;
> struct drm_atomic_state *state;
> - struct intel_encoder *encoder;
> - struct intel_connector *connector;
> - struct drm_connector_state *connector_state;
> - struct intel_crtc_state *crtc_state;
> + struct drm_crtc_state *crtc_state;
> int ret;
>
> state = drm_atomic_state_alloc(dev);
> if (!state) {
> - DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
> + DRM_DEBUG_KMS("[CRTC:%d] crtc restore failed, out of memory",
> crtc->base.id);
> return;
> }
>
> - state->acquire_ctx = dev->mode_config.acquire_ctx;
> -
> - /* The force restore path in the HW readout code relies on the staged
> - * config still keeping the user requested config while the actual
> - * state has been overwritten by the configuration read from HW. We
> - * need to copy the staged config to the atomic state, otherwise the
> - * mode set will just reapply the state the HW is already in. */
> - for_each_intel_encoder(dev, encoder) {
> - if (encoder->base.crtc != crtc)
> - continue;
> + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
>
> - for_each_intel_connector(dev, connector) {
> - if (connector->base.state->best_encoder !=
> - &encoder->base)
> - continue;
> -
> - connector_state = drm_atomic_get_connector_state(state, &connector->base);
> - if (IS_ERR(connector_state)) {
> - DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
> - connector->base.base.id,
> - connector->base.name,
> - PTR_ERR(connector_state));
> - continue;
> - }
> +retry:
> + crtc_state = drm_atomic_get_crtc_state(state, crtc);
> + ret = PTR_ERR_OR_ZERO(crtc_state);
> + if (!ret) {
> + if (!crtc_state->active)
> + goto out;
>
> - connector_state->crtc = crtc;
> - }
> + crtc_state->mode_changed = true;
> + ret = intel_set_mode(state);
I think here (instead of the hw state readout/restore code) we must do a
full compute config of the pipe state - most of the connector properties
need that to get reflected. Should be easy to test by changing the panel
upscaling property. Hence I think we should be able to run a full-blown
drm_atomic_commit here.
-Daniel
> }
>
> - crtc_state = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> - if (IS_ERR(crtc_state)) {
> - DRM_DEBUG_KMS("Failed to add [CRTC:%d] to state: %ld\n",
> - crtc->base.id, PTR_ERR(crtc_state));
> - drm_atomic_state_free(state);
> - return;
> + if (ret == -EDEADLK) {
> + drm_atomic_state_clear(state);
> + drm_modeset_backoff(state->acquire_ctx);
> + goto retry;
> }
>
> - drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
> -
> - intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
> - crtc->primary->fb, crtc->x, crtc->y);
> -
> - ret = intel_set_mode(state);
> if (ret)
> +out:
> drm_atomic_state_free(state);
> }
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode
2015-07-07 10:17 ` Daniel Vetter
@ 2015-07-07 10:48 ` Maarten Lankhorst
2015-07-07 13:16 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:48 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 12:17 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:24AM +0200, Maarten Lankhorst wrote:
>> And get rid of things that are no longer true. This function is only
>> used for forcing a modeset when encoder properties are changed.
>>
>> All the existing state is fine in this case, only setting mode_changed
>> will force a full recalculation here, and take all the state needed.
>>
>> The previous commit will prevent unneeded modesets anyway.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_display.c | 58 ++++++++++--------------------------
>> 1 file changed, 16 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 16373309dcae..f7b1fc28142c 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -13260,63 +13260,37 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>> {
>> struct drm_device *dev = crtc->dev;
>> struct drm_atomic_state *state;
>> - struct intel_encoder *encoder;
>> - struct intel_connector *connector;
>> - struct drm_connector_state *connector_state;
>> - struct intel_crtc_state *crtc_state;
>> + struct drm_crtc_state *crtc_state;
>> int ret;
>>
>> state = drm_atomic_state_alloc(dev);
>> if (!state) {
>> - DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
>> + DRM_DEBUG_KMS("[CRTC:%d] crtc restore failed, out of memory",
>> crtc->base.id);
>> return;
>> }
>>
>> - state->acquire_ctx = dev->mode_config.acquire_ctx;
>> -
>> - /* The force restore path in the HW readout code relies on the staged
>> - * config still keeping the user requested config while the actual
>> - * state has been overwritten by the configuration read from HW. We
>> - * need to copy the staged config to the atomic state, otherwise the
>> - * mode set will just reapply the state the HW is already in. */
>> - for_each_intel_encoder(dev, encoder) {
>> - if (encoder->base.crtc != crtc)
>> - continue;
>> + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
>>
>> - for_each_intel_connector(dev, connector) {
>> - if (connector->base.state->best_encoder !=
>> - &encoder->base)
>> - continue;
>> -
>> - connector_state = drm_atomic_get_connector_state(state, &connector->base);
>> - if (IS_ERR(connector_state)) {
>> - DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
>> - connector->base.base.id,
>> - connector->base.name,
>> - PTR_ERR(connector_state));
>> - continue;
>> - }
>> +retry:
>> + crtc_state = drm_atomic_get_crtc_state(state, crtc);
>> + ret = PTR_ERR_OR_ZERO(crtc_state);
>> + if (!ret) {
>> + if (!crtc_state->active)
>> + goto out;
>>
>> - connector_state->crtc = crtc;
>> - }
>> + crtc_state->mode_changed = true;
>> + ret = intel_set_mode(state);
> I think here (instead of the hw state readout/restore code) we must do a
> full compute config of the pipe state - most of the connector properties
> need that to get reflected. Should be easy to test by changing the panel
> upscaling property. Hence I think we should be able to run a full-blown
> drm_atomic_commit here.
Which is what this code does?
Together with the previous commit at least, without it it just performs a full modeset and recalculation.
>> }
>>
>> - crtc_state = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
>> - if (IS_ERR(crtc_state)) {
>> - DRM_DEBUG_KMS("Failed to add [CRTC:%d] to state: %ld\n",
>> - crtc->base.id, PTR_ERR(crtc_state));
>> - drm_atomic_state_free(state);
>> - return;
>> + if (ret == -EDEADLK) {
>> + drm_atomic_state_clear(state);
>> + drm_modeset_backoff(state->acquire_ctx);
>> + goto retry;
>> }
>>
>> - drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
>> -
>> - intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
>> - crtc->primary->fb, crtc->x, crtc->y);
>> -
>> - ret = intel_set_mode(state);
>> if (ret)
>> +out:
>> drm_atomic_state_free(state);
>> }
>>
>> --
>> 2.1.0
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode
2015-07-07 10:48 ` Maarten Lankhorst
@ 2015-07-07 13:16 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:16 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 12:48:36PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 12:17 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:24AM +0200, Maarten Lankhorst wrote:
> >> And get rid of things that are no longer true. This function is only
> >> used for forcing a modeset when encoder properties are changed.
> >>
> >> All the existing state is fine in this case, only setting mode_changed
> >> will force a full recalculation here, and take all the state needed.
> >>
> >> The previous commit will prevent unneeded modesets anyway.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >> drivers/gpu/drm/i915/intel_display.c | 58 ++++++++++--------------------------
> >> 1 file changed, 16 insertions(+), 42 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 16373309dcae..f7b1fc28142c 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -13260,63 +13260,37 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
> >> {
> >> struct drm_device *dev = crtc->dev;
> >> struct drm_atomic_state *state;
> >> - struct intel_encoder *encoder;
> >> - struct intel_connector *connector;
> >> - struct drm_connector_state *connector_state;
> >> - struct intel_crtc_state *crtc_state;
> >> + struct drm_crtc_state *crtc_state;
> >> int ret;
> >>
> >> state = drm_atomic_state_alloc(dev);
> >> if (!state) {
> >> - DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
> >> + DRM_DEBUG_KMS("[CRTC:%d] crtc restore failed, out of memory",
> >> crtc->base.id);
> >> return;
> >> }
> >>
> >> - state->acquire_ctx = dev->mode_config.acquire_ctx;
> >> -
> >> - /* The force restore path in the HW readout code relies on the staged
> >> - * config still keeping the user requested config while the actual
> >> - * state has been overwritten by the configuration read from HW. We
> >> - * need to copy the staged config to the atomic state, otherwise the
> >> - * mode set will just reapply the state the HW is already in. */
> >> - for_each_intel_encoder(dev, encoder) {
> >> - if (encoder->base.crtc != crtc)
> >> - continue;
> >> + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
> >>
> >> - for_each_intel_connector(dev, connector) {
> >> - if (connector->base.state->best_encoder !=
> >> - &encoder->base)
> >> - continue;
> >> -
> >> - connector_state = drm_atomic_get_connector_state(state, &connector->base);
> >> - if (IS_ERR(connector_state)) {
> >> - DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
> >> - connector->base.base.id,
> >> - connector->base.name,
> >> - PTR_ERR(connector_state));
> >> - continue;
> >> - }
> >> +retry:
> >> + crtc_state = drm_atomic_get_crtc_state(state, crtc);
> >> + ret = PTR_ERR_OR_ZERO(crtc_state);
> >> + if (!ret) {
> >> + if (!crtc_state->active)
> >> + goto out;
> >>
> >> - connector_state->crtc = crtc;
> >> - }
> >> + crtc_state->mode_changed = true;
> >> + ret = intel_set_mode(state);
> > I think here (instead of the hw state readout/restore code) we must do a
> > full compute config of the pipe state - most of the connector properties
> > need that to get reflected. Should be easy to test by changing the panel
> > upscaling property. Hence I think we should be able to run a full-blown
> > drm_atomic_commit here.
> Which is what this code does?
> Together with the previous commit at least, without it it just performs a full modeset and recalculation.
Oh I had a confusion about what intel_set_mode does, I thought it only
does the commit side of things and doesn't do all the compute_config
stuff. I guess this is something to clean up once we have it all landed,
but I'd have expected that a drm_atomic_commit(state) would exactly do
what we want to do here.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (12 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 13/20] drm/i915: Always reset in intel_crtc_restore_mode Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:48 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 15/20] drm/i915: Use full atomic modeset Maarten Lankhorst
` (6 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Calculate all state using a normal transition, but afterwards fudge
crtc->state->active back to its old value. This should still allow
state restore in setup_hw_state to work properly.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90396
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 52 +++++++++++++++++++++++++++++++++---
drivers/gpu/drm/i915/intel_drv.h | 2 +-
2 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f7b1fc28142c..9c461ea84d77 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6219,12 +6219,58 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
* turn all crtc's off, but do not adjust state
* This has to be paired with a call to intel_modeset_setup_hw_state.
*/
-void intel_display_suspend(struct drm_device *dev)
+int intel_display_suspend(struct drm_device *dev)
{
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
+ struct drm_atomic_state *state;
struct drm_crtc *crtc;
+ unsigned crtc_mask = 0;
+ int ret = 0;
+
+ if (WARN_ON(!ctx))
+ return 0;
+
+ lockdep_assert_held(&ctx->ww_ctx);
+ state = drm_atomic_state_alloc(dev);
+ if (WARN_ON(!state))
+ return -ENOMEM;
+
+ state->acquire_ctx = ctx;
+ state->allow_modeset = true;
+
+ for_each_crtc(dev, crtc) {
+ struct drm_crtc_state *crtc_state =
+ drm_atomic_get_crtc_state(state, crtc);
- for_each_crtc(dev, crtc)
- intel_crtc_disable_noatomic(crtc);
+ ret = PTR_ERR_OR_ZERO(crtc_state);
+ if (ret)
+ goto free;
+
+ if (!crtc_state->active)
+ continue;
+
+ crtc_state->active = false;
+ crtc_mask |= 1 << drm_crtc_index(crtc);
+ }
+
+ if (crtc_mask) {
+ ret = intel_set_mode(state);
+
+ if (!ret) {
+ for_each_crtc(dev, crtc)
+ if (crtc_mask & (1 << drm_crtc_index(crtc)))
+ crtc->state->active = true;
+
+ return ret;
+ }
+ }
+
+free:
+ if (ret)
+ DRM_ERROR("Suspending crtc's failed with %i\n", ret);
+ drm_atomic_state_free(state);
+ return ret;
}
/* Master function to enable/disable CRTC and corresponding power wells */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 525b4137521c..66e2016e0a96 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -992,7 +992,7 @@ int intel_pch_rawclk(struct drm_device *dev);
void intel_mark_busy(struct drm_device *dev);
void intel_mark_idle(struct drm_device *dev);
void intel_crtc_restore_mode(struct drm_crtc *crtc);
-void intel_display_suspend(struct drm_device *dev);
+int intel_display_suspend(struct drm_device *dev);
int intel_crtc_control(struct drm_crtc *crtc, bool enable);
void intel_crtc_update_dpms(struct drm_crtc *crtc);
void intel_encoder_destroy(struct drm_encoder *encoder);
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2.
2015-07-07 7:08 ` [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2 Maarten Lankhorst
@ 2015-07-07 9:48 ` Daniel Vetter
2015-07-07 10:50 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:48 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:25AM +0200, Maarten Lankhorst wrote:
> Calculate all state using a normal transition, but afterwards fudge
> crtc->state->active back to its old value. This should still allow
> state restore in setup_hw_state to work properly.
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90396
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
What we could do here (just as an experiment really, I haven't thought
through the implications for locking) is duplicate the state here _before_
we suspend everything. Then on force_restore we just use the saved state
from here for resuming. Would get rid of the failures on resume.
Otoh we need that code for the lid notifier still, so probably meh.
-Daniel
> ---
> drivers/gpu/drm/i915/intel_display.c | 52 +++++++++++++++++++++++++++++++++---
> drivers/gpu/drm/i915/intel_drv.h | 2 +-
> 2 files changed, 50 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index f7b1fc28142c..9c461ea84d77 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6219,12 +6219,58 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
> * turn all crtc's off, but do not adjust state
> * This has to be paired with a call to intel_modeset_setup_hw_state.
> */
> -void intel_display_suspend(struct drm_device *dev)
> +int intel_display_suspend(struct drm_device *dev)
> {
> + struct drm_mode_config *config = &dev->mode_config;
> + struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
> + struct drm_atomic_state *state;
> struct drm_crtc *crtc;
> + unsigned crtc_mask = 0;
> + int ret = 0;
> +
> + if (WARN_ON(!ctx))
> + return 0;
> +
> + lockdep_assert_held(&ctx->ww_ctx);
> + state = drm_atomic_state_alloc(dev);
> + if (WARN_ON(!state))
> + return -ENOMEM;
> +
> + state->acquire_ctx = ctx;
> + state->allow_modeset = true;
> +
> + for_each_crtc(dev, crtc) {
> + struct drm_crtc_state *crtc_state =
> + drm_atomic_get_crtc_state(state, crtc);
>
> - for_each_crtc(dev, crtc)
> - intel_crtc_disable_noatomic(crtc);
> + ret = PTR_ERR_OR_ZERO(crtc_state);
> + if (ret)
> + goto free;
> +
> + if (!crtc_state->active)
> + continue;
> +
> + crtc_state->active = false;
> + crtc_mask |= 1 << drm_crtc_index(crtc);
> + }
> +
> + if (crtc_mask) {
> + ret = intel_set_mode(state);
> +
> + if (!ret) {
> + for_each_crtc(dev, crtc)
> + if (crtc_mask & (1 << drm_crtc_index(crtc)))
> + crtc->state->active = true;
> +
> + return ret;
> + }
> + }
> +
> +free:
> + if (ret)
> + DRM_ERROR("Suspending crtc's failed with %i\n", ret);
> + drm_atomic_state_free(state);
> + return ret;
> }
>
> /* Master function to enable/disable CRTC and corresponding power wells */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 525b4137521c..66e2016e0a96 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -992,7 +992,7 @@ int intel_pch_rawclk(struct drm_device *dev);
> void intel_mark_busy(struct drm_device *dev);
> void intel_mark_idle(struct drm_device *dev);
> void intel_crtc_restore_mode(struct drm_crtc *crtc);
> -void intel_display_suspend(struct drm_device *dev);
> +int intel_display_suspend(struct drm_device *dev);
> int intel_crtc_control(struct drm_crtc *crtc, bool enable);
> void intel_crtc_update_dpms(struct drm_crtc *crtc);
> void intel_encoder_destroy(struct drm_encoder *encoder);
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread* Re: [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2.
2015-07-07 9:48 ` Daniel Vetter
@ 2015-07-07 10:50 ` Maarten Lankhorst
2015-07-07 13:21 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:50 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 11:48 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:25AM +0200, Maarten Lankhorst wrote:
>> Calculate all state using a normal transition, but afterwards fudge
>> crtc->state->active back to its old value. This should still allow
>> state restore in setup_hw_state to work properly.
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90396
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> What we could do here (just as an experiment really, I haven't thought
> through the implications for locking) is duplicate the state here _before_
> we suspend everything. Then on force_restore we just use the saved state
> from here for resuming. Would get rid of the failures on resume.
>
> Otoh we need that code for the lid notifier still, so probably meh.
>
Or make a intel_duplicate_state helper and then swap the sw state back.
I think that might be overkill and just patching up crtc_state->active afterwards
is fine. The restore on resume performs a full recheck anyway.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2.
2015-07-07 10:50 ` Maarten Lankhorst
@ 2015-07-07 13:21 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:21 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 12:50:39PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 11:48 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:25AM +0200, Maarten Lankhorst wrote:
> >> Calculate all state using a normal transition, but afterwards fudge
> >> crtc->state->active back to its old value. This should still allow
> >> state restore in setup_hw_state to work properly.
> >>
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90396
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > What we could do here (just as an experiment really, I haven't thought
> > through the implications for locking) is duplicate the state here _before_
> > we suspend everything. Then on force_restore we just use the saved state
> > from here for resuming. Would get rid of the failures on resume.
> >
> > Otoh we need that code for the lid notifier still, so probably meh.
> >
> Or make a intel_duplicate_state helper and then swap the sw state back.
> I think that might be overkill and just patching up crtc_state->active afterwards
> is fine. The restore on resume performs a full recheck anyway.
Yeah was really just an idea, current patch looks fine.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 15/20] drm/i915: Use full atomic modeset.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (13 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 14/20] drm/i915: Make intel_display_suspend atomic, try 2 Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 16/20] drm/i915: Call plane update functions directly from intel_atomic_commit Maarten Lankhorst
` (5 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Huzzah! \o/
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/i915_drv.c | 2 +-
drivers/gpu/drm/i915/i915_drv.h | 1 -
drivers/gpu/drm/i915/i915_params.c | 5 -
drivers/gpu/drm/i915/intel_atomic.c | 123 ----------------
drivers/gpu/drm/i915/intel_display.c | 277 ++++++-----------------------------
drivers/gpu/drm/i915/intel_drv.h | 5 -
6 files changed, 43 insertions(+), 370 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index db48aee7f140..f13ed1ef6641 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1731,7 +1731,7 @@ static int __init i915_init(void)
* to the atomic ioctl and the atomic properties. Only plane operations on
* a single CRTC will actually work.
*/
- if (i915.nuclear_pageflip)
+ if (driver.driver_features & DRIVER_MODESET)
driver.driver_features |= DRIVER_ATOMIC;
return drm_pci_init(&driver, &i915_pci_driver);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2a78a0ee0f97..806a7966e5ed 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2612,7 +2612,6 @@ struct i915_params {
int use_mmio_flip;
int mmio_debug;
bool verbose_state_checks;
- bool nuclear_pageflip;
int edp_vswing;
};
extern struct i915_params i915 __read_mostly;
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index d6f9d9a117b6..72439773f2df 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -50,7 +50,6 @@ struct i915_params i915 __read_mostly = {
.use_mmio_flip = 0,
.mmio_debug = 0,
.verbose_state_checks = 1,
- .nuclear_pageflip = 0,
.edp_vswing = 0,
};
@@ -171,10 +170,6 @@ module_param_named(verbose_state_checks, i915.verbose_state_checks, bool, 0600);
MODULE_PARM_DESC(verbose_state_checks,
"Enable verbose logs (ie. WARN_ON()) in case of unexpected hw state conditions.");
-module_param_named_unsafe(nuclear_pageflip, i915.nuclear_pageflip, bool, 0600);
-MODULE_PARM_DESC(nuclear_pageflip,
- "Force atomic modeset functionality; only planes work for now (default: false).");
-
/* WA to get away with the default setting in VBT for early platforms.Will be removed */
module_param_named_unsafe(edp_vswing, i915.edp_vswing, int, 0400);
MODULE_PARM_DESC(edp_vswing,
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 0bbdc2fc5298..8f148d0112c8 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -35,129 +35,6 @@
#include <drm/drm_plane_helper.h>
#include "intel_drv.h"
-
-/**
- * intel_atomic_check - validate state object
- * @dev: drm device
- * @state: state to validate
- */
-int intel_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state)
-{
- int nplanes = dev->mode_config.num_total_plane;
- int ncrtcs = dev->mode_config.num_crtc;
- int nconnectors = dev->mode_config.num_connector;
- enum pipe nuclear_pipe = INVALID_PIPE;
- struct intel_crtc *nuclear_crtc = NULL;
- struct intel_crtc_state *crtc_state = NULL;
- int ret;
- int i;
- bool not_nuclear = false;
-
- to_intel_atomic_state(state)->cdclk = to_i915(dev)->cdclk_freq;
-
- /*
- * FIXME: At the moment, we only support "nuclear pageflip" on a
- * single CRTC. Cross-crtc updates will be added later.
- */
- for (i = 0; i < nplanes; i++) {
- struct intel_plane *plane = to_intel_plane(state->planes[i]);
- if (!plane)
- continue;
-
- if (nuclear_pipe == INVALID_PIPE) {
- nuclear_pipe = plane->pipe;
- } else if (nuclear_pipe != plane->pipe) {
- DRM_DEBUG_KMS("i915 only support atomic plane operations on a single CRTC at the moment\n");
- return -EINVAL;
- }
- }
-
- /*
- * FIXME: We only handle planes for now; make sure there are no CRTC's
- * or connectors involved.
- */
- state->allow_modeset = false;
- for (i = 0; i < ncrtcs; i++) {
- struct intel_crtc *crtc = to_intel_crtc(state->crtcs[i]);
- if (crtc)
- memset(&crtc->atomic, 0, sizeof(crtc->atomic));
- if (crtc && crtc->pipe != nuclear_pipe)
- not_nuclear = true;
- if (crtc && crtc->pipe == nuclear_pipe) {
- nuclear_crtc = crtc;
- crtc_state = to_intel_crtc_state(state->crtc_states[i]);
- }
- }
- for (i = 0; i < nconnectors; i++)
- if (state->connectors[i] != NULL)
- not_nuclear = true;
-
- if (not_nuclear) {
- DRM_DEBUG_KMS("i915 only supports atomic plane operations at the moment\n");
- return -EINVAL;
- }
-
- ret = drm_atomic_helper_check_planes(dev, state);
- if (ret)
- return ret;
-
- return ret;
-}
-
-
-/**
- * intel_atomic_commit - commit validated state object
- * @dev: DRM device
- * @state: the top-level driver state object
- * @async: asynchronous commit
- *
- * This function commits a top-level state object that has been validated
- * with drm_atomic_helper_check().
- *
- * FIXME: Atomic modeset support for i915 is not yet complete. At the moment
- * we can only handle plane-related operations and do not yet support
- * asynchronous commit.
- *
- * RETURNS
- * Zero for success or -errno.
- */
-int intel_atomic_commit(struct drm_device *dev,
- struct drm_atomic_state *state,
- bool async)
-{
- struct drm_crtc_state *crtc_state;
- struct drm_crtc *crtc;
- int ret;
- int i;
-
- if (async) {
- DRM_DEBUG_KMS("i915 does not yet support async commit\n");
- return -EINVAL;
- }
-
- ret = drm_atomic_helper_prepare_planes(dev, state);
- if (ret)
- return ret;
-
- /* Point of no return */
- drm_atomic_helper_swap_state(dev, state);
-
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
-
- drm_atomic_helper_commit_planes_on_crtc(crtc_state);
- }
-
- /* FIXME: This function should eventually call __intel_set_mode when needed */
-
- drm_atomic_helper_wait_for_vblanks(dev, state);
- drm_atomic_helper_cleanup_planes(dev, state);
- drm_atomic_state_free(state);
-
- return 0;
-}
-
/**
* intel_connector_atomic_get_property - fetch connector property value
* @connector: connector to fetch property for
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9c461ea84d77..44fa189e9f88 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -86,7 +86,6 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
static void ironlake_pch_clock_get(struct intel_crtc *crtc,
struct intel_crtc_state *pipe_config);
-static int intel_set_mode(struct drm_atomic_state *state);
static int intel_framebuffer_init(struct drm_device *dev,
struct intel_framebuffer *ifb,
struct drm_mode_fb_cmd2 *mode_cmd,
@@ -115,14 +114,6 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force);
static void ironlake_pfit_enable(struct intel_crtc *crtc);
static void intel_modeset_setup_hw_state(struct drm_device *dev);
-static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
-{
- if (!connector->mst_port)
- return connector->encoder;
- else
- return &connector->mst_port->mst_encoders[pipe]->base;
-}
-
typedef struct {
int min, max;
} intel_range_t;
@@ -6255,7 +6246,7 @@ int intel_display_suspend(struct drm_device *dev)
}
if (crtc_mask) {
- ret = intel_set_mode(state);
+ ret = drm_atomic_commit(state);
if (!ret) {
for_each_crtc(dev, crtc)
@@ -6309,7 +6300,7 @@ int intel_crtc_control(struct drm_crtc *crtc, bool enable)
}
pipe_config->base.active = enable;
- ret = intel_set_mode(state);
+ ret = drm_atomic_commit(state);
if (!ret)
return ret;
@@ -10423,7 +10414,7 @@ retry:
drm_mode_copy(&crtc_state->base.mode, mode);
- if (intel_set_mode(state)) {
+ if (drm_atomic_commit(state)) {
DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
if (old->release_fb)
old->release_fb->funcs->destroy(old->release_fb);
@@ -10491,7 +10482,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
if (ret)
goto fail;
- ret = intel_set_mode(state);
+ ret = drm_atomic_commit(state);
if (ret)
goto fail;
@@ -13126,7 +13117,6 @@ static bool intel_modeset_calc_update_pipe(struct drm_crtc *crtc,
return true;
}
-/* Code that should eventually be part of atomic_check() */
static int intel_modeset_checks(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
@@ -13167,15 +13157,20 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
return 0;
}
-static int
-intel_modeset_compute_config(struct drm_atomic_state *state)
+/**
+ * intel_atomic_check - validate state object
+ * @dev: drm device
+ * @state: state to validate
+ */
+static int intel_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
int ret, i;
bool any_ms = false;
- ret = drm_atomic_helper_check_modeset(state->dev, state);
+ ret = drm_atomic_helper_check_modeset(dev, state);
if (ret)
return ret;
@@ -13217,9 +13212,26 @@ intel_modeset_compute_config(struct drm_atomic_state *state)
return drm_atomic_helper_check_planes(state->dev, state);
}
-static int __intel_set_mode(struct drm_atomic_state *state)
+/**
+ * intel_atomic_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the top-level driver state object
+ * @async: asynchronous commit
+ *
+ * This function commits a top-level state object that has been validated
+ * with drm_atomic_helper_check().
+ *
+ * FIXME: Atomic modeset support for i915 is not yet complete. At the moment
+ * we can only handle plane-related operations and do not yet support
+ * asynchronous commit.
+ *
+ * RETURNS
+ * Zero for success or -errno.
+ */
+static int intel_atomic_commit(struct drm_device *dev,
+ struct drm_atomic_state *state,
+ bool async)
{
- struct drm_device *dev = state->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
@@ -13227,6 +13239,11 @@ static int __intel_set_mode(struct drm_atomic_state *state)
int i;
bool any_ms = false;
+ if (async) {
+ DRM_DEBUG_KMS("i915 does not yet support async commit\n");
+ return -EINVAL;
+ }
+
ret = drm_atomic_helper_prepare_planes(dev, state);
if (ret)
return ret;
@@ -13272,34 +13289,14 @@ static int __intel_set_mode(struct drm_atomic_state *state)
/* FIXME: add subpixel order */
+ drm_atomic_helper_wait_for_vblanks(dev, state);
drm_atomic_helper_cleanup_planes(dev, state);
-
drm_atomic_state_free(state);
- return 0;
-}
-
-static int intel_set_mode_checked(struct drm_atomic_state *state)
-{
- struct drm_device *dev = state->dev;
- int ret;
-
- ret = __intel_set_mode(state);
- if (ret == 0)
+ if (any_ms)
intel_modeset_check_state(dev);
- return ret;
-}
-
-static int intel_set_mode(struct drm_atomic_state *state)
-{
- int ret;
-
- ret = intel_modeset_compute_config(state);
- if (ret)
- return ret;
-
- return intel_set_mode_checked(state);
+ return 0;
}
void intel_crtc_restore_mode(struct drm_crtc *crtc)
@@ -13326,7 +13323,7 @@ retry:
goto out;
crtc_state->mode_changed = true;
- ret = intel_set_mode(state);
+ ret = drm_atomic_commit(state);
}
if (ret == -EDEADLK) {
@@ -13342,199 +13339,9 @@ out:
#undef for_each_intel_crtc_masked
-static bool intel_connector_in_mode_set(struct intel_connector *connector,
- struct drm_mode_set *set)
-{
- int ro;
-
- for (ro = 0; ro < set->num_connectors; ro++)
- if (set->connectors[ro] == &connector->base)
- return true;
-
- return false;
-}
-
-static int
-intel_modeset_stage_output_state(struct drm_device *dev,
- struct drm_mode_set *set,
- struct drm_atomic_state *state)
-{
- struct intel_connector *connector;
- struct drm_connector *drm_connector;
- struct drm_connector_state *connector_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. */
- WARN_ON(!set->fb && (set->num_connectors != 0));
- WARN_ON(set->fb && (set->num_connectors == 0));
-
- 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_state->best_encoder =
- &intel_find_encoder(connector, pipe)->base;
- }
-
- 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_state->best_encoder = NULL;
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
- connector->base.base.id,
- connector->base.name);
- }
- }
- /* connector->new_encoder is now updated for all connectors. */
-
- 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;
-
- continue;
- }
-
- 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_state->best_encoder,
- connector_state->crtc)) {
- return -EINVAL;
- }
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
- connector->base.base.id,
- connector->base.name,
- connector_state->crtc->base.id);
-
- if (connector_state->best_encoder != &connector->encoder->base)
- connector->encoder =
- to_intel_encoder(connector_state->best_encoder);
- }
-
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- bool has_connectors;
-
- ret = drm_atomic_add_affected_connectors(state, crtc);
- if (ret)
- return ret;
-
- has_connectors = !!drm_atomic_connectors_for_crtc(state, crtc);
- if (has_connectors != crtc_state->enable)
- crtc_state->enable =
- crtc_state->active = has_connectors;
- }
-
- ret = intel_modeset_setup_plane_state(state, set->crtc, set->mode,
- set->fb, set->x, set->y);
- if (ret)
- return ret;
-
- crtc_state = drm_atomic_get_crtc_state(state, set->crtc);
- if (IS_ERR(crtc_state))
- return PTR_ERR(crtc_state);
-
- ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
- if (ret)
- return ret;
-
- if (set->num_connectors)
- crtc_state->active = true;
-
- return 0;
-}
-
-static int intel_crtc_set_config(struct drm_mode_set *set)
-{
- struct drm_device *dev;
- struct drm_atomic_state *state = NULL;
- int ret;
-
- BUG_ON(!set);
- BUG_ON(!set->crtc);
- BUG_ON(!set->crtc->helper_private);
-
- /* Enforce sane interface api - has been abused by the fb helper. */
- BUG_ON(!set->mode && set->fb);
- BUG_ON(set->fb && set->num_connectors == 0);
-
- if (set->fb) {
- DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n",
- set->crtc->base.id, set->fb->base.id,
- (int)set->num_connectors, set->x, set->y);
- } else {
- DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
- }
-
- dev = set->crtc->dev;
-
- state = drm_atomic_state_alloc(dev);
- if (!state)
- return -ENOMEM;
-
- state->acquire_ctx = dev->mode_config.acquire_ctx;
-
- ret = intel_modeset_stage_output_state(dev, set, state);
- if (ret)
- goto out;
-
- ret = intel_modeset_compute_config(state);
- if (ret)
- goto out;
-
- ret = intel_set_mode_checked(state);
- if (ret) {
- DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
- set->crtc->base.id, ret);
- }
-
-out:
- if (ret)
- drm_atomic_state_free(state);
- return ret;
-}
-
static const struct drm_crtc_funcs intel_crtc_funcs = {
.gamma_set = intel_crtc_gamma_set,
- .set_config = intel_crtc_set_config,
+ .set_config = drm_atomic_helper_set_config,
.destroy = intel_crtc_destroy,
.page_flip = intel_crtc_page_flip,
.atomic_duplicate_state = intel_crtc_duplicate_state,
@@ -15619,7 +15426,7 @@ void intel_display_resume(struct drm_device *dev)
intel_modeset_setup_hw_state(dev);
i915_redisable_vga(dev);
- ret = intel_set_mode(state);
+ ret = drm_atomic_commit(state);
if (!ret)
return;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 66e2016e0a96..4f73dc4d6fd4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1396,11 +1396,6 @@ void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
void intel_tv_init(struct drm_device *dev);
/* intel_atomic.c */
-int intel_atomic_check(struct drm_device *dev,
- struct drm_atomic_state *state);
-int intel_atomic_commit(struct drm_device *dev,
- struct drm_atomic_state *state,
- bool async);
int intel_connector_atomic_get_property(struct drm_connector *connector,
const struct drm_connector_state *state,
struct drm_property *property,
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 16/20] drm/i915: Call plane update functions directly from intel_atomic_commit.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (14 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 15/20] drm/i915: Use full atomic modeset Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 17/20] drm/i915: always disable irqs in intel_pipe_update_start Maarten Lankhorst
` (4 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
Now that there's only a single path for all atomic updates we can call
intel_(pre/post)_plane_update from intel_atomic_commit directly. This
makes the intention more clear.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 44fa189e9f88..9bfabbf84ab1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13279,12 +13279,19 @@ static int intel_atomic_commit(struct drm_device *dev,
/* Now enable the clocks, plane, pipe, and connectors that we set up. */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
- if (needs_modeset(crtc->state) && crtc->state->active) {
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ bool modeset = needs_modeset(crtc->state);
+
+ if (modeset && crtc->state->active) {
update_scanline_offset(to_intel_crtc(crtc));
dev_priv->display.crtc_enable(crtc);
}
+ if (!modeset)
+ intel_pre_plane_update(intel_crtc);
+
drm_atomic_helper_commit_planes_on_crtc(crtc_state);
+ intel_post_plane_update(intel_crtc);
}
/* FIXME: add subpixel order */
@@ -13620,10 +13627,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *old_intel_state =
to_intel_crtc_state(old_crtc_state);
- bool modeset = needs_modeset(crtc->state);
-
- if (!modeset)
- intel_pre_plane_update(intel_crtc);
if (intel_crtc->atomic.update_wm_pre)
intel_update_watermarks(crtc);
@@ -13636,7 +13639,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
intel_pipe_update_start(intel_crtc,
&intel_crtc->atomic.start_vbl_count);
- if (modeset)
+ if (needs_modeset(crtc->state))
return;
if (to_intel_crtc_state(crtc->state)->update_pipe)
@@ -13657,8 +13660,6 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
intel_crtc->atomic.start_vbl_count);
intel_runtime_pm_put(dev_priv);
-
- intel_post_plane_update(intel_crtc);
}
/**
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 17/20] drm/i915: always disable irqs in intel_pipe_update_start
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (15 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 16/20] drm/i915: Call plane update functions directly from intel_atomic_commit Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 7:08 ` [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes Maarten Lankhorst
` (3 subsequent siblings)
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This can only fail because of a bug in the code.
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 15 +++++----------
drivers/gpu/drm/i915/intel_drv.h | 2 +-
drivers/gpu/drm/i915/intel_sprite.c | 17 +++++++----------
3 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9bfabbf84ab1..71fc35d814d1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11239,12 +11239,11 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc)
static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
{
struct drm_device *dev = intel_crtc->base.dev;
- bool atomic_update;
u32 start_vbl_count;
intel_mark_page_flip_active(intel_crtc);
- atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
+ intel_pipe_update_start(intel_crtc, &start_vbl_count);
if (INTEL_INFO(dev)->gen >= 9)
skl_do_mmio_flip(intel_crtc);
@@ -11252,8 +11251,7 @@ static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)
/* use_mmio_flip() retricts MMIO flips to ilk+ */
ilk_do_mmio_flip(intel_crtc);
- if (atomic_update)
- intel_pipe_update_end(intel_crtc, start_vbl_count);
+ intel_pipe_update_end(intel_crtc, start_vbl_count);
}
static void intel_mmio_flip_work_func(struct work_struct *work)
@@ -13635,9 +13633,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
/* Perform vblank evasion around commit operation */
if (crtc->state->active)
- intel_crtc->atomic.evade =
- intel_pipe_update_start(intel_crtc,
- &intel_crtc->atomic.start_vbl_count);
+ intel_pipe_update_start(intel_crtc, &intel_crtc->atomic.start_vbl_count);
if (needs_modeset(crtc->state))
return;
@@ -13655,9 +13651,8 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- if (intel_crtc->atomic.evade)
- intel_pipe_update_end(intel_crtc,
- intel_crtc->atomic.start_vbl_count);
+ if (crtc->state->active)
+ intel_pipe_update_end(intel_crtc, intel_crtc->atomic.start_vbl_count);
intel_runtime_pm_put(dev_priv);
}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4f73dc4d6fd4..6a29393918ce 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1388,7 +1388,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-bool intel_pipe_update_start(struct intel_crtc *crtc,
+void intel_pipe_update_start(struct intel_crtc *crtc,
uint32_t *start_vbl_count);
void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index cd21525df352..9d8af2f8a875 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -75,10 +75,8 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
* until a subsequent call to intel_pipe_update_end(). That is done to
* avoid random delays. The value written to @start_vbl_count should be
* supplied to intel_pipe_update_end() for error checking.
- *
- * Return: true if the call was successful
*/
-bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
+void intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
{
struct drm_device *dev = crtc->base.dev;
const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
@@ -96,13 +94,14 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
min = vblank_start - usecs_to_scanlines(mode, 100);
max = vblank_start - 1;
+ local_irq_disable();
+ *start_vbl_count = 0;
+
if (min <= 0 || max <= 0)
- return false;
+ return;
if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
- return false;
-
- local_irq_disable();
+ return;
trace_i915_pipe_update_start(crtc, min, max);
@@ -138,8 +137,6 @@ bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
*start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
-
- return true;
}
/**
@@ -161,7 +158,7 @@ void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
local_irq_enable();
- if (start_vbl_count != end_vbl_count)
+ if (start_vbl_count && start_vbl_count != end_vbl_count)
DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
pipe_name(pipe), start_vbl_count, end_vbl_count);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (16 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 17/20] drm/i915: always disable irqs in intel_pipe_update_start Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 9:33 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 19/20] drm/i915: Remove use of runtime pm in atomic commit functions Maarten Lankhorst
` (2 subsequent siblings)
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
No point in applying vblank evasion if there's nothing to evade.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 71fc35d814d1..2eaccdc59a9a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13288,7 +13288,10 @@ static int intel_atomic_commit(struct drm_device *dev,
if (!modeset)
intel_pre_plane_update(intel_crtc);
- drm_atomic_helper_commit_planes_on_crtc(crtc_state);
+ if (crtc->state->planes_changed ||
+ to_intel_crtc_state(crtc->state)->update_pipe)
+ drm_atomic_helper_commit_planes_on_crtc(crtc_state);
+
intel_post_plane_update(intel_crtc);
}
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes.
2015-07-07 7:08 ` [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes Maarten Lankhorst
@ 2015-07-07 9:33 ` Daniel Vetter
2015-07-07 10:51 ` Maarten Lankhorst
0 siblings, 1 reply; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 9:33 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:29AM +0200, Maarten Lankhorst wrote:
> No point in applying vblank evasion if there's nothing to evade.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 71fc35d814d1..2eaccdc59a9a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13288,7 +13288,10 @@ static int intel_atomic_commit(struct drm_device *dev,
> if (!modeset)
> intel_pre_plane_update(intel_crtc);
>
> - drm_atomic_helper_commit_planes_on_crtc(crtc_state);
> + if (crtc->state->planes_changed ||
> + to_intel_crtc_state(crtc->state)->update_pipe)
> + drm_atomic_helper_commit_planes_on_crtc(crtc_state);
What if we change some crtc property which is updated under vblank
evasion, but no plane state? e.g. background color. Imo trying to optimize
this doesn't speed up any common case, but makes things more fragile.
-Daniel
> +
> intel_post_plane_update(intel_crtc);
> }
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes.
2015-07-07 9:33 ` Daniel Vetter
@ 2015-07-07 10:51 ` Maarten Lankhorst
2015-07-07 13:22 ` Daniel Vetter
0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 10:51 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
Op 07-07-15 om 11:33 schreef Daniel Vetter:
> On Tue, Jul 07, 2015 at 09:08:29AM +0200, Maarten Lankhorst wrote:
>> No point in applying vblank evasion if there's nothing to evade.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_display.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 71fc35d814d1..2eaccdc59a9a 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -13288,7 +13288,10 @@ static int intel_atomic_commit(struct drm_device *dev,
>> if (!modeset)
>> intel_pre_plane_update(intel_crtc);
>>
>> - drm_atomic_helper_commit_planes_on_crtc(crtc_state);
>> + if (crtc->state->planes_changed ||
>> + to_intel_crtc_state(crtc->state)->update_pipe)
>> + drm_atomic_helper_commit_planes_on_crtc(crtc_state);
> What if we change some crtc property which is updated under vblank
> evasion, but no plane state? e.g. background color. Imo trying to optimize
> this doesn't speed up any common case, but makes things more fragile.
>
update_pipe = true.
~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* Re: [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes.
2015-07-07 10:51 ` Maarten Lankhorst
@ 2015-07-07 13:22 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:22 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 12:51:06PM +0200, Maarten Lankhorst wrote:
> Op 07-07-15 om 11:33 schreef Daniel Vetter:
> > On Tue, Jul 07, 2015 at 09:08:29AM +0200, Maarten Lankhorst wrote:
> >> No point in applying vblank evasion if there's nothing to evade.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >> drivers/gpu/drm/i915/intel_display.c | 5 ++++-
> >> 1 file changed, 4 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 71fc35d814d1..2eaccdc59a9a 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -13288,7 +13288,10 @@ static int intel_atomic_commit(struct drm_device *dev,
> >> if (!modeset)
> >> intel_pre_plane_update(intel_crtc);
> >>
> >> - drm_atomic_helper_commit_planes_on_crtc(crtc_state);
> >> + if (crtc->state->planes_changed ||
> >> + to_intel_crtc_state(crtc->state)->update_pipe)
> >> + drm_atomic_helper_commit_planes_on_crtc(crtc_state);
> > What if we change some crtc property which is updated under vblank
> > evasion, but no plane state? e.g. background color. Imo trying to optimize
> > this doesn't speed up any common case, but makes things more fragile.
> >
> update_pipe = true.
Ah that's added in patch 12, which I've ignored a bit. I guess means we
need to hold off on this one too until fastboot has settled more.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 19/20] drm/i915: Remove use of runtime pm in atomic commit functions
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (17 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 18/20] drm/i915: Only commit planes on crtc's that have changed planes Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 10:19 ` Daniel Vetter
2015-07-07 7:08 ` [PATCH v2 20/20] drm/i915: Skip modeset checks when modeset is prevented Maarten Lankhorst
2015-07-07 13:42 ` [PATCH v2 00/20] Convert to atomic, part 4 Daniel Vetter
20 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This shouldn't be explicitly required here.
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2eaccdc59a9a..38334fdfc649 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13624,7 +13624,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_crtc_state *old_intel_state =
to_intel_crtc_state(old_crtc_state);
@@ -13632,8 +13631,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
if (intel_crtc->atomic.update_wm_pre)
intel_update_watermarks(crtc);
- intel_runtime_pm_get(dev_priv);
-
/* Perform vblank evasion around commit operation */
if (crtc->state->active)
intel_pipe_update_start(intel_crtc, &intel_crtc->atomic.start_vbl_count);
@@ -13650,14 +13647,10 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
static void intel_finish_crtc_commit(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state)
{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (crtc->state->active)
intel_pipe_update_end(intel_crtc, intel_crtc->atomic.start_vbl_count);
-
- intel_runtime_pm_put(dev_priv);
}
/**
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 19/20] drm/i915: Remove use of runtime pm in atomic commit functions
2015-07-07 7:08 ` [PATCH v2 19/20] drm/i915: Remove use of runtime pm in atomic commit functions Maarten Lankhorst
@ 2015-07-07 10:19 ` Daniel Vetter
0 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 10:19 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:30AM +0200, Maarten Lankhorst wrote:
> This shouldn't be explicitly required here.
Would be good to explain why: We needed this originally for updating
pagetables in plane commit functions. But that's extracted into
prepare/cleanup now. The other issue was running updates when the pipe was
off. That's also now fixed (commit reference for that would be nice if we
have one).
-Daniel
>
> Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
> drivers/gpu/drm/i915/intel_display.c | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 2eaccdc59a9a..38334fdfc649 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13624,7 +13624,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
> struct drm_crtc_state *old_crtc_state)
> {
> struct drm_device *dev = crtc->dev;
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_crtc_state *old_intel_state =
> to_intel_crtc_state(old_crtc_state);
> @@ -13632,8 +13631,6 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
> if (intel_crtc->atomic.update_wm_pre)
> intel_update_watermarks(crtc);
>
> - intel_runtime_pm_get(dev_priv);
> -
> /* Perform vblank evasion around commit operation */
> if (crtc->state->active)
> intel_pipe_update_start(intel_crtc, &intel_crtc->atomic.start_vbl_count);
> @@ -13650,14 +13647,10 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
> static void intel_finish_crtc_commit(struct drm_crtc *crtc,
> struct drm_crtc_state *old_crtc_state)
> {
> - struct drm_device *dev = crtc->dev;
> - struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>
> if (crtc->state->active)
> intel_pipe_update_end(intel_crtc, intel_crtc->atomic.start_vbl_count);
> -
> - intel_runtime_pm_put(dev_priv);
> }
>
> /**
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread
* [PATCH v2 20/20] drm/i915: Skip modeset checks when modeset is prevented.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (18 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 19/20] drm/i915: Remove use of runtime pm in atomic commit functions Maarten Lankhorst
@ 2015-07-07 7:08 ` Maarten Lankhorst
2015-07-07 13:42 ` [PATCH v2 00/20] Convert to atomic, part 4 Daniel Vetter
20 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2015-07-07 7:08 UTC (permalink / raw)
To: intel-gfx
This will keep the cdclk at boot speed if it's fast enough to drive
the crtc's, and will make init faster.
If this commit causes bugs it's probably a bug related to keeping the
initial mode, because all it does is resetting crtc's.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_display.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 38334fdfc649..33687af30f6b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13189,10 +13189,10 @@ static int intel_atomic_check(struct drm_device *dev,
if (ret)
return ret;
- any_ms = true;
pipe_config->update_pipe =
intel_modeset_calc_update_pipe(crtc, crtc_state);
pipe_config->base.mode_changed = !pipe_config->update_pipe;
+ any_ms |= pipe_config->base.mode_changed;
intel_dump_pipe_config(to_intel_crtc(crtc),
pipe_config, "[modeset]");
--
2.1.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 80+ messages in thread* Re: [PATCH v2 00/20] Convert to atomic, part 4.
2015-07-07 7:08 [PATCH v2 00/20] Convert to atomic, part 4 Maarten Lankhorst
` (19 preceding siblings ...)
2015-07-07 7:08 ` [PATCH v2 20/20] drm/i915: Skip modeset checks when modeset is prevented Maarten Lankhorst
@ 2015-07-07 13:42 ` Daniel Vetter
20 siblings, 0 replies; 80+ messages in thread
From: Daniel Vetter @ 2015-07-07 13:42 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: intel-gfx
On Tue, Jul 07, 2015 at 09:08:11AM +0200, Maarten Lankhorst wrote:
> This patch series requires
> [PATCH] drm/atomic: pass old crtc state to atomic_begin/flush.
> and highly recommends, but optional:
> [PATCH 2/2] drm/atomic: Cleanup on error properly in the atomic ioctl.
>
> This series adds full atomic ioctl support, allows for decreased boot
> times by inheriting the boot state, adds support for atomic
> suspend/resume and will skip modesets if there's no need for it.
>
> Maarten Lankhorst (20):
> drm/atomic: add connectors_changed to separate it from mode_changed
> drm: Don't update plane properties for atomic planes if it stays the
> same
> drm/i915: Fix noatomic crtc disabling.
> drm/i915: Do not update pfit state when toggling crtc enabled.
> drm/i915: Do not use plane_config in intel_fbdev.c
> drm/i915: Allow fuzzy matching in pipe_config_compare.
> drm/i915: Rework primary plane stuff slightly.
> drm/i915: fill in more mode members
> drm/i915: Fill in more crtc state, v2.
> drm/i915: Convert suspend/resume to atomic.
> drm/i915: Update power domains on readout.
> drm/i915: skip modeset if compatible, and enable fastboot for
> everyone, v2.
> drm/i915: Always reset in intel_crtc_restore_mode
> drm/i915: Make intel_display_suspend atomic, try 2.
> drm/i915: Use full atomic modeset.
> drm/i915: Call plane update functions directly from
> intel_atomic_commit.
> drm/i915: always disable irqs in intel_pipe_update_start
> drm/i915: Only commit planes on crtc's that have changed planes.
> drm/i915: Remove use of runtime pm in atomic commit functions
> drm/i915: Skip modeset checks when modeset is prevented.
Ok went through the patches an made comments. My main concern is really
about the fastboot work, that has the risk of introducing another pile of
issues. Hence I'd like to get just the atomic modeset in and rolled out
every. For that the missing bit seems to be rolling out
drm_atomic_helper_dpms to all connectors (and a bit more garbage
collecting of dead code afterwards). Once that's in and stabilized a bit
we can look at fastboot.
But I'd really like not to pull in fastboot and full-blown atomic at the
same time, I fear that would destabilize the driver a bit too much. This
would affect patches 8&9, parts of patch 12 (the one split-out I
commented about should land) and probably also patch 19&20.
Overall looks good I think.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 80+ messages in thread