diff options
author | Dave Airlie <airlied@redhat.com> | 2017-11-01 21:33:57 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-11-01 21:33:57 -0400 |
commit | 96ffbbf936298cad0df289ed1c09052493095b7f (patch) | |
tree | 47548e12527c8843c7b4d3e4158a7ce7350af7e7 | |
parent | 25dd1aa3b4cf0c361147aa45ff4dd1d335259ac1 (diff) | |
parent | bb5cf3386327c9cb5ca3fbb85242e940751649c8 (diff) |
Merge tag 'drm-intel-fixes-2017-11-01' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes
Fixes for Stable:
- Fix KBL Blank Screen (Jani)
- Fix FIFO Underrun on SNB (Maarten)
Other fixes:
- Fix GPU Hang on i915gm (Chris)
- Fix gem_tiled_pread_pwrite IGT case (Chris)
- Cancel modeset retry work during modeset clean-up (Manasi)
* tag 'drm-intel-fixes-2017-11-01' of git://anongit.freedesktop.org/drm/drm-intel:
drm/i915: Check incoming alignment for unfenced buffers (on i915gm)
drm/i915: Hold rcu_read_lock when iterating over the radixtree (vma idr)
drm/i915: Hold rcu_read_lock when iterating over the radixtree (objects)
drm/i915/edp: read edp display control registers unconditionally
drm/i915: Do not rely on wm preservation for ILK watermarks
drm/i915: Cancel the modeset retry work during modeset cleanup
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 51 |
7 files changed, 57 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 32e857dc507c..dc1faa49687d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2214,8 +2214,10 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj) | |||
2214 | struct radix_tree_iter iter; | 2214 | struct radix_tree_iter iter; |
2215 | void __rcu **slot; | 2215 | void __rcu **slot; |
2216 | 2216 | ||
2217 | rcu_read_lock(); | ||
2217 | radix_tree_for_each_slot(slot, &obj->mm.get_page.radix, &iter, 0) | 2218 | radix_tree_for_each_slot(slot, &obj->mm.get_page.radix, &iter, 0) |
2218 | radix_tree_delete(&obj->mm.get_page.radix, iter.index); | 2219 | radix_tree_delete(&obj->mm.get_page.radix, iter.index); |
2220 | rcu_read_unlock(); | ||
2219 | } | 2221 | } |
2220 | 2222 | ||
2221 | void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, | 2223 | void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 58a2a44f88bd..8afd2ce59b8d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -104,6 +104,7 @@ static void lut_close(struct i915_gem_context *ctx) | |||
104 | kmem_cache_free(ctx->i915->luts, lut); | 104 | kmem_cache_free(ctx->i915->luts, lut); |
105 | } | 105 | } |
106 | 106 | ||
107 | rcu_read_lock(); | ||
107 | radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) { | 108 | radix_tree_for_each_slot(slot, &ctx->handles_vma, &iter, 0) { |
108 | struct i915_vma *vma = rcu_dereference_raw(*slot); | 109 | struct i915_vma *vma = rcu_dereference_raw(*slot); |
109 | struct drm_i915_gem_object *obj = vma->obj; | 110 | struct drm_i915_gem_object *obj = vma->obj; |
@@ -115,6 +116,7 @@ static void lut_close(struct i915_gem_context *ctx) | |||
115 | 116 | ||
116 | __i915_gem_object_release_unless_active(obj); | 117 | __i915_gem_object_release_unless_active(obj); |
117 | } | 118 | } |
119 | rcu_read_unlock(); | ||
118 | } | 120 | } |
119 | 121 | ||
120 | static void i915_gem_context_free(struct i915_gem_context *ctx) | 122 | static void i915_gem_context_free(struct i915_gem_context *ctx) |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 92437f455b43..4ac454ae54d7 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -337,6 +337,10 @@ eb_vma_misplaced(const struct drm_i915_gem_exec_object2 *entry, | |||
337 | (vma->node.start + vma->node.size - 1) >> 32) | 337 | (vma->node.start + vma->node.size - 1) >> 32) |
338 | return true; | 338 | return true; |
339 | 339 | ||
340 | if (flags & __EXEC_OBJECT_NEEDS_MAP && | ||
341 | !i915_vma_is_map_and_fenceable(vma)) | ||
342 | return true; | ||
343 | |||
340 | return false; | 344 | return false; |
341 | } | 345 | } |
342 | 346 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5c7828c52d12..5ebdb63330dd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -15227,6 +15227,23 @@ void intel_connector_unregister(struct drm_connector *connector) | |||
15227 | intel_panel_destroy_backlight(connector); | 15227 | intel_panel_destroy_backlight(connector); |
15228 | } | 15228 | } |
15229 | 15229 | ||
15230 | static void intel_hpd_poll_fini(struct drm_device *dev) | ||
15231 | { | ||
15232 | struct intel_connector *connector; | ||
15233 | struct drm_connector_list_iter conn_iter; | ||
15234 | |||
15235 | /* First disable polling... */ | ||
15236 | drm_kms_helper_poll_fini(dev); | ||
15237 | |||
15238 | /* Then kill the work that may have been queued by hpd. */ | ||
15239 | drm_connector_list_iter_begin(dev, &conn_iter); | ||
15240 | for_each_intel_connector_iter(connector, &conn_iter) { | ||
15241 | if (connector->modeset_retry_work.func) | ||
15242 | cancel_work_sync(&connector->modeset_retry_work); | ||
15243 | } | ||
15244 | drm_connector_list_iter_end(&conn_iter); | ||
15245 | } | ||
15246 | |||
15230 | void intel_modeset_cleanup(struct drm_device *dev) | 15247 | void intel_modeset_cleanup(struct drm_device *dev) |
15231 | { | 15248 | { |
15232 | struct drm_i915_private *dev_priv = to_i915(dev); | 15249 | struct drm_i915_private *dev_priv = to_i915(dev); |
@@ -15247,7 +15264,7 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
15247 | * Due to the hpd irq storm handling the hotplug work can re-arm the | 15264 | * Due to the hpd irq storm handling the hotplug work can re-arm the |
15248 | * poll handlers. Hence disable polling after hpd handling is shut down. | 15265 | * poll handlers. Hence disable polling after hpd handling is shut down. |
15249 | */ | 15266 | */ |
15250 | drm_kms_helper_poll_fini(dev); | 15267 | intel_hpd_poll_fini(dev); |
15251 | 15268 | ||
15252 | /* poll work can call into fbdev, hence clean that up afterwards */ | 15269 | /* poll work can call into fbdev, hence clean that up afterwards */ |
15253 | intel_fbdev_fini(dev_priv); | 15270 | intel_fbdev_fini(dev_priv); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 203198659ab2..09f274419eea 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -3731,9 +3731,16 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp) | |||
3731 | 3731 | ||
3732 | } | 3732 | } |
3733 | 3733 | ||
3734 | /* Read the eDP Display control capabilities registers */ | 3734 | /* |
3735 | if ((intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & DP_DPCD_DISPLAY_CONTROL_CAPABLE) && | 3735 | * Read the eDP display control registers. |
3736 | drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, | 3736 | * |
3737 | * Do this independent of DP_DPCD_DISPLAY_CONTROL_CAPABLE bit in | ||
3738 | * DP_EDP_CONFIGURATION_CAP, because some buggy displays do not have it | ||
3739 | * set, but require eDP 1.4+ detection (e.g. for supported link rates | ||
3740 | * method). The display control registers should read zero if they're | ||
3741 | * not supported anyway. | ||
3742 | */ | ||
3743 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_DPCD_REV, | ||
3737 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == | 3744 | intel_dp->edp_dpcd, sizeof(intel_dp->edp_dpcd)) == |
3738 | sizeof(intel_dp->edp_dpcd)) | 3745 | sizeof(intel_dp->edp_dpcd)) |
3739 | DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd), | 3746 | DRM_DEBUG_KMS("EDP DPCD : %*ph\n", (int) sizeof(intel_dp->edp_dpcd), |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index fa47285918f4..79fbaf78f604 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -496,7 +496,6 @@ struct intel_crtc_scaler_state { | |||
496 | 496 | ||
497 | struct intel_pipe_wm { | 497 | struct intel_pipe_wm { |
498 | struct intel_wm_level wm[5]; | 498 | struct intel_wm_level wm[5]; |
499 | struct intel_wm_level raw_wm[5]; | ||
500 | uint32_t linetime; | 499 | uint32_t linetime; |
501 | bool fbc_wm_enabled; | 500 | bool fbc_wm_enabled; |
502 | bool pipe_enabled; | 501 | bool pipe_enabled; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0a09f8ff6aff..cb950752c346 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2716,9 +2716,9 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, | |||
2716 | const struct intel_crtc *intel_crtc, | 2716 | const struct intel_crtc *intel_crtc, |
2717 | int level, | 2717 | int level, |
2718 | struct intel_crtc_state *cstate, | 2718 | struct intel_crtc_state *cstate, |
2719 | struct intel_plane_state *pristate, | 2719 | const struct intel_plane_state *pristate, |
2720 | struct intel_plane_state *sprstate, | 2720 | const struct intel_plane_state *sprstate, |
2721 | struct intel_plane_state *curstate, | 2721 | const struct intel_plane_state *curstate, |
2722 | struct intel_wm_level *result) | 2722 | struct intel_wm_level *result) |
2723 | { | 2723 | { |
2724 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; | 2724 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
@@ -3038,28 +3038,24 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) | |||
3038 | struct intel_pipe_wm *pipe_wm; | 3038 | struct intel_pipe_wm *pipe_wm; |
3039 | struct drm_device *dev = state->dev; | 3039 | struct drm_device *dev = state->dev; |
3040 | const struct drm_i915_private *dev_priv = to_i915(dev); | 3040 | const struct drm_i915_private *dev_priv = to_i915(dev); |
3041 | struct intel_plane *intel_plane; | 3041 | struct drm_plane *plane; |
3042 | struct intel_plane_state *pristate = NULL; | 3042 | const struct drm_plane_state *plane_state; |
3043 | struct intel_plane_state *sprstate = NULL; | 3043 | const struct intel_plane_state *pristate = NULL; |
3044 | struct intel_plane_state *curstate = NULL; | 3044 | const struct intel_plane_state *sprstate = NULL; |
3045 | const struct intel_plane_state *curstate = NULL; | ||
3045 | int level, max_level = ilk_wm_max_level(dev_priv), usable_level; | 3046 | int level, max_level = ilk_wm_max_level(dev_priv), usable_level; |
3046 | struct ilk_wm_maximums max; | 3047 | struct ilk_wm_maximums max; |
3047 | 3048 | ||
3048 | pipe_wm = &cstate->wm.ilk.optimal; | 3049 | pipe_wm = &cstate->wm.ilk.optimal; |
3049 | 3050 | ||
3050 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 3051 | drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &cstate->base) { |
3051 | struct intel_plane_state *ps; | 3052 | const struct intel_plane_state *ps = to_intel_plane_state(plane_state); |
3052 | |||
3053 | ps = intel_atomic_get_existing_plane_state(state, | ||
3054 | intel_plane); | ||
3055 | if (!ps) | ||
3056 | continue; | ||
3057 | 3053 | ||
3058 | if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) | 3054 | if (plane->type == DRM_PLANE_TYPE_PRIMARY) |
3059 | pristate = ps; | 3055 | pristate = ps; |
3060 | else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) | 3056 | else if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
3061 | sprstate = ps; | 3057 | sprstate = ps; |
3062 | else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) | 3058 | else if (plane->type == DRM_PLANE_TYPE_CURSOR) |
3063 | curstate = ps; | 3059 | curstate = ps; |
3064 | } | 3060 | } |
3065 | 3061 | ||
@@ -3081,11 +3077,9 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) | |||
3081 | if (pipe_wm->sprites_scaled) | 3077 | if (pipe_wm->sprites_scaled) |
3082 | usable_level = 0; | 3078 | usable_level = 0; |
3083 | 3079 | ||
3084 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, | ||
3085 | pristate, sprstate, curstate, &pipe_wm->raw_wm[0]); | ||
3086 | |||
3087 | memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); | 3080 | memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); |
3088 | pipe_wm->wm[0] = pipe_wm->raw_wm[0]; | 3081 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, |
3082 | pristate, sprstate, curstate, &pipe_wm->wm[0]); | ||
3089 | 3083 | ||
3090 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) | 3084 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) |
3091 | pipe_wm->linetime = hsw_compute_linetime_wm(cstate); | 3085 | pipe_wm->linetime = hsw_compute_linetime_wm(cstate); |
@@ -3095,8 +3089,8 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) | |||
3095 | 3089 | ||
3096 | ilk_compute_wm_reg_maximums(dev_priv, 1, &max); | 3090 | ilk_compute_wm_reg_maximums(dev_priv, 1, &max); |
3097 | 3091 | ||
3098 | for (level = 1; level <= max_level; level++) { | 3092 | for (level = 1; level <= usable_level; level++) { |
3099 | struct intel_wm_level *wm = &pipe_wm->raw_wm[level]; | 3093 | struct intel_wm_level *wm = &pipe_wm->wm[level]; |
3100 | 3094 | ||
3101 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, | 3095 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, |
3102 | pristate, sprstate, curstate, wm); | 3096 | pristate, sprstate, curstate, wm); |
@@ -3106,13 +3100,10 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) | |||
3106 | * register maximums since such watermarks are | 3100 | * register maximums since such watermarks are |
3107 | * always invalid. | 3101 | * always invalid. |
3108 | */ | 3102 | */ |
3109 | if (level > usable_level) | 3103 | if (!ilk_validate_wm_level(level, &max, wm)) { |
3110 | continue; | 3104 | memset(wm, 0, sizeof(*wm)); |
3111 | 3105 | break; | |
3112 | if (ilk_validate_wm_level(level, &max, wm)) | 3106 | } |
3113 | pipe_wm->wm[level] = *wm; | ||
3114 | else | ||
3115 | usable_level = level; | ||
3116 | } | 3107 | } |
3117 | 3108 | ||
3118 | return 0; | 3109 | return 0; |