@@ -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 ;
3113
+
3114
+ intel_modeset_setup_hw_state (dev );
3115
+ i915_redisable_vga (dev );
3105
3116
3106
- drm_modeset_unlock_crtc (crtc );
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 )
@@ -16174,9 +16249,10 @@ void intel_display_resume(struct drm_device *dev)
16174
16249
struct drm_atomic_state * state = dev_priv -> modeset_restore_state ;
16175
16250
struct drm_modeset_acquire_ctx ctx ;
16176
16251
int ret ;
16177
- bool setup = false;
16178
16252
16179
16253
dev_priv -> modeset_restore_state = NULL ;
16254
+ if (state )
16255
+ state -> acquire_ctx = & ctx ;
16180
16256
16181
16257
/*
16182
16258
* This is a cludge because with real atomic modeset mode_config.mutex
@@ -16187,43 +16263,17 @@ void intel_display_resume(struct drm_device *dev)
16187
16263
mutex_lock (& dev -> mode_config .mutex );
16188
16264
drm_modeset_acquire_init (& ctx , 0 );
16189
16265
16190
- retry :
16191
- ret = drm_modeset_lock_all_ctx (dev , & ctx );
16192
-
16193
- if (ret == 0 && !setup ) {
16194
- setup = true;
16195
-
16196
- intel_modeset_setup_hw_state (dev );
16197
- i915_redisable_vga (dev );
16198
- }
16199
-
16200
- if (ret == 0 && state ) {
16201
- struct drm_crtc_state * crtc_state ;
16202
- struct drm_crtc * crtc ;
16203
- int i ;
16204
-
16205
- state -> acquire_ctx = & ctx ;
16206
-
16207
- /* ignore any reset values/BIOS leftovers in the WM registers */
16208
- to_intel_atomic_state (state )-> skip_intermediate_wm = true;
16209
-
16210
- for_each_crtc_in_state (state , crtc , crtc_state , i ) {
16211
- /*
16212
- * Force recalculation even if we restore
16213
- * current state. With fast modeset this may not result
16214
- * in a modeset when the state is compatible.
16215
- */
16216
- crtc_state -> mode_changed = true;
16217
- }
16218
-
16219
- ret = drm_atomic_commit (state );
16220
- }
16266
+ while (1 ) {
16267
+ ret = drm_modeset_lock_all_ctx (dev , & ctx );
16268
+ if (ret != - EDEADLK )
16269
+ break ;
16221
16270
16222
- if (ret == - EDEADLK ) {
16223
16271
drm_modeset_backoff (& ctx );
16224
- goto retry ;
16225
16272
}
16226
16273
16274
+ if (!ret )
16275
+ ret = __intel_display_resume (dev , state );
16276
+
16227
16277
drm_modeset_drop_locks (& ctx );
16228
16278
drm_modeset_acquire_fini (& ctx );
16229
16279
mutex_unlock (& dev -> mode_config .mutex );
0 commit comments