diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 181 |
1 files changed, 121 insertions, 60 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dcf93b3d4fb6..175595fc3e45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3093,40 +3093,110 @@ static void intel_update_primary_planes(struct drm_device *dev) | |||
3093 | 3093 | ||
3094 | for_each_crtc(dev, crtc) { | 3094 | for_each_crtc(dev, crtc) { |
3095 | struct intel_plane *plane = to_intel_plane(crtc->primary); | 3095 | struct intel_plane *plane = to_intel_plane(crtc->primary); |
3096 | struct intel_plane_state *plane_state; | 3096 | struct intel_plane_state *plane_state = |
3097 | 3097 | to_intel_plane_state(plane->base.state); | |
3098 | drm_modeset_lock_crtc(crtc, &plane->base); | ||
3099 | plane_state = to_intel_plane_state(plane->base.state); | ||
3100 | 3098 | ||
3101 | if (plane_state->visible) | 3099 | if (plane_state->visible) |
3102 | plane->update_plane(&plane->base, | 3100 | plane->update_plane(&plane->base, |
3103 | to_intel_crtc_state(crtc->state), | 3101 | to_intel_crtc_state(crtc->state), |
3104 | plane_state); | 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 | void intel_prepare_reset(struct drm_i915_private *dev_priv) | 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 | /* no reset support for gen2 */ | 3145 | /* no reset support for gen2 */ |
3113 | if (IS_GEN2(dev_priv)) | 3146 | if (IS_GEN2(dev_priv)) |
3114 | return; | 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 | if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) | 3164 | if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) |
3118 | return; | 3165 | return; |
3119 | 3166 | ||
3120 | drm_modeset_lock_all(&dev_priv->drm); | ||
3121 | /* | 3167 | /* |
3122 | * Disabling the crtcs gracefully seems nicer. Also the | 3168 | * Disabling the crtcs gracefully seems nicer. Also the |
3123 | * g33 docs say we should at least disable all the planes. | 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 | void intel_finish_reset(struct drm_i915_private *dev_priv) | 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 | * Flips in the rings will be nuked by the reset, | 3201 | * Flips in the rings will be nuked by the reset, |
3132 | * so complete all pending flips so that user space | 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 | if (IS_GEN2(dev_priv)) | 3208 | if (IS_GEN2(dev_priv)) |
3139 | return; | 3209 | return; |
3140 | 3210 | ||
3211 | dev_priv->modeset_restore_state = NULL; | ||
3212 | |||
3141 | /* reset doesn't touch the display */ | 3213 | /* reset doesn't touch the display */ |
3142 | if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) { | 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 | * FIXME: Atomic will make this obsolete since we won't schedule | 3221 | * FIXME: Atomic will make this obsolete since we won't schedule |
3150 | * CS-based flips (which might get lost in gpu resets) any more. | 3222 | * CS-based flips (which might get lost in gpu resets) any more. |
3151 | */ | 3223 | */ |
3152 | intel_update_primary_planes(&dev_priv->drm); | 3224 | intel_update_primary_planes(dev); |
3153 | return; | 3225 | } else { |
3154 | } | 3226 | /* |
3155 | 3227 | * The display has been reset as well, | |
3156 | /* | 3228 | * so need a full re-initialization. |
3157 | * The display has been reset as well, | 3229 | */ |
3158 | * so need a full re-initialization. | 3230 | intel_runtime_pm_disable_interrupts(dev_priv); |
3159 | */ | 3231 | intel_runtime_pm_enable_interrupts(dev_priv); |
3160 | intel_runtime_pm_disable_interrupts(dev_priv); | ||
3161 | 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); | 3235 | spin_lock_irq(&dev_priv->irq_lock); |
3166 | if (dev_priv->display.hpd_irq_setup) | 3236 | if (dev_priv->display.hpd_irq_setup) |
3167 | dev_priv->display.hpd_irq_setup(dev_priv); | 3237 | dev_priv->display.hpd_irq_setup(dev_priv); |
3168 | spin_unlock_irq(&dev_priv->irq_lock); | 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 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) | 3252 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) |
@@ -13684,6 +13759,13 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13684 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) | 13759 | intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco)) |
13685 | dev_priv->display.modeset_commit_cdclk(state); | 13760 | dev_priv->display.modeset_commit_cdclk(state); |
13686 | 13761 | ||
13762 | /* | ||
13763 | * SKL workaround: bspec recommends we disable the SAGV when we | ||
13764 | * have more then one pipe enabled | ||
13765 | */ | ||
13766 | if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state)) | ||
13767 | skl_disable_sagv(dev_priv); | ||
13768 | |||
13687 | intel_modeset_verify_disabled(dev); | 13769 | intel_modeset_verify_disabled(dev); |
13688 | } | 13770 | } |
13689 | 13771 | ||
@@ -13757,6 +13839,10 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
13757 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); | 13839 | intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state); |
13758 | } | 13840 | } |
13759 | 13841 | ||
13842 | if (IS_SKYLAKE(dev_priv) && intel_state->modeset && | ||
13843 | skl_can_enable_sagv(state)) | ||
13844 | skl_enable_sagv(dev_priv); | ||
13845 | |||
13760 | drm_atomic_helper_commit_hw_done(state); | 13846 | drm_atomic_helper_commit_hw_done(state); |
13761 | 13847 | ||
13762 | if (intel_state->modeset) | 13848 | if (intel_state->modeset) |
@@ -16156,9 +16242,10 @@ void intel_display_resume(struct drm_device *dev) | |||
16156 | struct drm_atomic_state *state = dev_priv->modeset_restore_state; | 16242 | struct drm_atomic_state *state = dev_priv->modeset_restore_state; |
16157 | struct drm_modeset_acquire_ctx ctx; | 16243 | struct drm_modeset_acquire_ctx ctx; |
16158 | int ret; | 16244 | int ret; |
16159 | bool setup = false; | ||
16160 | 16245 | ||
16161 | dev_priv->modeset_restore_state = NULL; | 16246 | dev_priv->modeset_restore_state = NULL; |
16247 | if (state) | ||
16248 | state->acquire_ctx = &ctx; | ||
16162 | 16249 | ||
16163 | /* | 16250 | /* |
16164 | * This is a cludge because with real atomic modeset mode_config.mutex | 16251 | * This is a cludge because with real atomic modeset mode_config.mutex |
@@ -16169,43 +16256,17 @@ void intel_display_resume(struct drm_device *dev) | |||
16169 | mutex_lock(&dev->mode_config.mutex); | 16256 | mutex_lock(&dev->mode_config.mutex); |
16170 | drm_modeset_acquire_init(&ctx, 0); | 16257 | drm_modeset_acquire_init(&ctx, 0); |
16171 | 16258 | ||
16172 | retry: | 16259 | while (1) { |
16173 | ret = drm_modeset_lock_all_ctx(dev, &ctx); | 16260 | ret = drm_modeset_lock_all_ctx(dev, &ctx); |
16174 | 16261 | if (ret != -EDEADLK) | |
16175 | if (ret == 0 && !setup) { | 16262 | break; |
16176 | setup = true; | ||
16177 | |||
16178 | intel_modeset_setup_hw_state(dev); | ||
16179 | i915_redisable_vga(dev); | ||
16180 | } | ||
16181 | |||
16182 | if (ret == 0 && state) { | ||
16183 | struct drm_crtc_state *crtc_state; | ||
16184 | struct drm_crtc *crtc; | ||
16185 | int i; | ||
16186 | |||
16187 | state->acquire_ctx = &ctx; | ||
16188 | |||
16189 | /* ignore any reset values/BIOS leftovers in the WM registers */ | ||
16190 | to_intel_atomic_state(state)->skip_intermediate_wm = true; | ||
16191 | |||
16192 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | ||
16193 | /* | ||
16194 | * Force recalculation even if we restore | ||
16195 | * current state. With fast modeset this may not result | ||
16196 | * in a modeset when the state is compatible. | ||
16197 | */ | ||
16198 | crtc_state->mode_changed = true; | ||
16199 | } | ||
16200 | |||
16201 | ret = drm_atomic_commit(state); | ||
16202 | } | ||
16203 | 16263 | ||
16204 | if (ret == -EDEADLK) { | ||
16205 | drm_modeset_backoff(&ctx); | 16264 | drm_modeset_backoff(&ctx); |
16206 | goto retry; | ||
16207 | } | 16265 | } |
16208 | 16266 | ||
16267 | if (!ret) | ||
16268 | ret = __intel_display_resume(dev, state); | ||
16269 | |||
16209 | drm_modeset_drop_locks(&ctx); | 16270 | drm_modeset_drop_locks(&ctx); |
16210 | drm_modeset_acquire_fini(&ctx); | 16271 | drm_modeset_acquire_fini(&ctx); |
16211 | mutex_unlock(&dev->mode_config.mutex); | 16272 | mutex_unlock(&dev->mode_config.mutex); |