@@ -3093,40 +3093,110 @@ static void intel_update_primary_planes(struct drm_device *dev)
3093
3093
3094
3094
for_each_crtc (dev , crtc ) {
3095
3095
struct intel_plane * plane = to_intel_plane (crtc -> primary );
3096
- struct intel_plane_state * plane_state ;
3097
-
3098
- drm_modeset_lock_crtc (crtc , & plane -> base );
3099
- plane_state = to_intel_plane_state (plane -> base .state );
3096
+ struct intel_plane_state * plane_state =
3097
+ to_intel_plane_state (plane -> base .state );
3100
3098
3101
3099
if (plane_state -> visible )
3102
3100
plane -> update_plane (& plane -> base ,
3103
3101
to_intel_crtc_state (crtc -> state ),
3104
3102
plane_state );
3103
+ }
3104
+ }
3105
+
3106
+ static int
3107
+ __intel_display_resume (struct drm_device * dev ,
3108
+ struct drm_atomic_state * state )
3109
+ {
3110
+ struct drm_crtc_state * crtc_state ;
3111
+ struct drm_crtc * crtc ;
3112
+ int i , ret ;
3105
3113
3106
- drm_modeset_unlock_crtc (crtc );
3114
+ intel_modeset_setup_hw_state (dev );
3115
+ i915_redisable_vga (dev );
3116
+
3117
+ if (!state )
3118
+ return 0 ;
3119
+
3120
+ for_each_crtc_in_state (state , crtc , crtc_state , i ) {
3121
+ /*
3122
+ * Force recalculation even if we restore
3123
+ * current state. With fast modeset this may not result
3124
+ * in a modeset when the state is compatible.
3125
+ */
3126
+ crtc_state -> mode_changed = true;
3107
3127
}
3128
+
3129
+ /* ignore any reset values/BIOS leftovers in the WM registers */
3130
+ to_intel_atomic_state (state )-> skip_intermediate_wm = true;
3131
+
3132
+ ret = drm_atomic_commit (state );
3133
+
3134
+ WARN_ON (ret == - EDEADLK );
3135
+ return ret ;
3108
3136
}
3109
3137
3110
3138
void intel_prepare_reset (struct drm_i915_private * dev_priv )
3111
3139
{
3140
+ struct drm_device * dev = & dev_priv -> drm ;
3141
+ struct drm_modeset_acquire_ctx * ctx = & dev_priv -> reset_ctx ;
3142
+ struct drm_atomic_state * state ;
3143
+ int ret ;
3144
+
3112
3145
/* no reset support for gen2 */
3113
3146
if (IS_GEN2 (dev_priv ))
3114
3147
return ;
3115
3148
3116
- /* reset doesn't touch the display */
3149
+ /*
3150
+ * Need mode_config.mutex so that we don't
3151
+ * trample ongoing ->detect() and whatnot.
3152
+ */
3153
+ mutex_lock (& dev -> mode_config .mutex );
3154
+ drm_modeset_acquire_init (ctx , 0 );
3155
+ while (1 ) {
3156
+ ret = drm_modeset_lock_all_ctx (dev , ctx );
3157
+ if (ret != - EDEADLK )
3158
+ break ;
3159
+
3160
+ drm_modeset_backoff (ctx );
3161
+ }
3162
+
3163
+ /* reset doesn't touch the display, but flips might get nuked anyway, */
3117
3164
if (INTEL_GEN (dev_priv ) >= 5 || IS_G4X (dev_priv ))
3118
3165
return ;
3119
3166
3120
- drm_modeset_lock_all (& dev_priv -> drm );
3121
3167
/*
3122
3168
* Disabling the crtcs gracefully seems nicer. Also the
3123
3169
* g33 docs say we should at least disable all the planes.
3124
3170
*/
3125
- intel_display_suspend (& dev_priv -> drm );
3171
+ state = drm_atomic_helper_duplicate_state (dev , ctx );
3172
+ if (IS_ERR (state )) {
3173
+ ret = PTR_ERR (state );
3174
+ state = NULL ;
3175
+ DRM_ERROR ("Duplicating state failed with %i\n" , ret );
3176
+ goto err ;
3177
+ }
3178
+
3179
+ ret = drm_atomic_helper_disable_all (dev , ctx );
3180
+ if (ret ) {
3181
+ DRM_ERROR ("Suspending crtc's failed with %i\n" , ret );
3182
+ goto err ;
3183
+ }
3184
+
3185
+ dev_priv -> modeset_restore_state = state ;
3186
+ state -> acquire_ctx = ctx ;
3187
+ return ;
3188
+
3189
+ err :
3190
+ drm_atomic_state_free (state );
3126
3191
}
3127
3192
3128
3193
void intel_finish_reset (struct drm_i915_private * dev_priv )
3129
3194
{
3195
+ struct drm_device * dev = & dev_priv -> drm ;
3196
+ struct drm_modeset_acquire_ctx * ctx = & dev_priv -> reset_ctx ;
3197
+ struct drm_atomic_state * state = dev_priv -> modeset_restore_state ;
3198
+ int ret ;
3199
+
3130
3200
/*
3131
3201
* Flips in the rings will be nuked by the reset,
3132
3202
* so complete all pending flips so that user space
@@ -3138,6 +3208,8 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3138
3208
if (IS_GEN2 (dev_priv ))
3139
3209
return ;
3140
3210
3211
+ dev_priv -> modeset_restore_state = NULL ;
3212
+
3141
3213
/* reset doesn't touch the display */
3142
3214
if (INTEL_GEN (dev_priv ) >= 5 || IS_G4X (dev_priv )) {
3143
3215
/*
@@ -3149,29 +3221,32 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
3149
3221
* FIXME: Atomic will make this obsolete since we won't schedule
3150
3222
* CS-based flips (which might get lost in gpu resets) any more.
3151
3223
*/
3152
- intel_update_primary_planes (& dev_priv -> drm );
3153
- return ;
3154
- }
3155
-
3156
- /*
3157
- * The display has been reset as well,
3158
- * so need a full re-initialization.
3159
- */
3160
- intel_runtime_pm_disable_interrupts (dev_priv );
3161
- intel_runtime_pm_enable_interrupts (dev_priv );
3224
+ intel_update_primary_planes (dev );
3225
+ } else {
3226
+ /*
3227
+ * The display has been reset as well,
3228
+ * so need a full re-initialization.
3229
+ */
3230
+ intel_runtime_pm_disable_interrupts (dev_priv );
3231
+ intel_runtime_pm_enable_interrupts (dev_priv );
3162
3232
3163
- intel_modeset_init_hw (& dev_priv -> drm );
3233
+ intel_modeset_init_hw (dev );
3164
3234
3165
- spin_lock_irq (& dev_priv -> irq_lock );
3166
- if (dev_priv -> display .hpd_irq_setup )
3167
- dev_priv -> display .hpd_irq_setup (dev_priv );
3168
- spin_unlock_irq (& dev_priv -> irq_lock );
3235
+ spin_lock_irq (& dev_priv -> irq_lock );
3236
+ if (dev_priv -> display .hpd_irq_setup )
3237
+ dev_priv -> display .hpd_irq_setup (dev_priv );
3238
+ spin_unlock_irq (& dev_priv -> irq_lock );
3169
3239
3170
- intel_display_resume (& dev_priv -> drm );
3240
+ ret = __intel_display_resume (dev , state );
3241
+ if (ret )
3242
+ DRM_ERROR ("Restoring old state failed with %i\n" , ret );
3171
3243
3172
- intel_hpd_init (dev_priv );
3244
+ intel_hpd_init (dev_priv );
3245
+ }
3173
3246
3174
- drm_modeset_unlock_all (& dev_priv -> drm );
3247
+ drm_modeset_drop_locks (ctx );
3248
+ drm_modeset_acquire_fini (ctx );
3249
+ mutex_unlock (& dev -> mode_config .mutex );
3175
3250
}
3176
3251
3177
3252
static bool intel_crtc_has_pending_flip (struct drm_crtc * crtc )
@@ -16180,9 +16255,10 @@ void intel_display_resume(struct drm_device *dev)
16180
16255
struct drm_atomic_state * state = dev_priv -> modeset_restore_state ;
16181
16256
struct drm_modeset_acquire_ctx ctx ;
16182
16257
int ret ;
16183
- bool setup = false;
16184
16258
16185
16259
dev_priv -> modeset_restore_state = NULL ;
16260
+ if (state )
16261
+ state -> acquire_ctx = & ctx ;
16186
16262
16187
16263
/*
16188
16264
* This is a cludge because with real atomic modeset mode_config.mutex
@@ -16193,43 +16269,17 @@ void intel_display_resume(struct drm_device *dev)
16193
16269
mutex_lock (& dev -> mode_config .mutex );
16194
16270
drm_modeset_acquire_init (& ctx , 0 );
16195
16271
16196
- retry :
16197
- ret = drm_modeset_lock_all_ctx (dev , & ctx );
16198
-
16199
- if (ret == 0 && !setup ) {
16200
- setup = true;
16201
-
16202
- intel_modeset_setup_hw_state (dev );
16203
- i915_redisable_vga (dev );
16204
- }
16205
-
16206
- if (ret == 0 && state ) {
16207
- struct drm_crtc_state * crtc_state ;
16208
- struct drm_crtc * crtc ;
16209
- int i ;
16210
-
16211
- state -> acquire_ctx = & ctx ;
16212
-
16213
- /* ignore any reset values/BIOS leftovers in the WM registers */
16214
- to_intel_atomic_state (state )-> skip_intermediate_wm = true;
16215
-
16216
- for_each_crtc_in_state (state , crtc , crtc_state , i ) {
16217
- /*
16218
- * Force recalculation even if we restore
16219
- * current state. With fast modeset this may not result
16220
- * in a modeset when the state is compatible.
16221
- */
16222
- crtc_state -> mode_changed = true;
16223
- }
16224
-
16225
- ret = drm_atomic_commit (state );
16226
- }
16272
+ while (1 ) {
16273
+ ret = drm_modeset_lock_all_ctx (dev , & ctx );
16274
+ if (ret != - EDEADLK )
16275
+ break ;
16227
16276
16228
- if (ret == - EDEADLK ) {
16229
16277
drm_modeset_backoff (& ctx );
16230
- goto retry ;
16231
16278
}
16232
16279
16280
+ if (!ret )
16281
+ ret = __intel_display_resume (dev , state );
16282
+
16233
16283
drm_modeset_drop_locks (& ctx );
16234
16284
drm_modeset_acquire_fini (& ctx );
16235
16285
mutex_unlock (& dev -> mode_config .mutex );
0 commit comments