diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 125 |
1 files changed, 42 insertions, 83 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f0b9aa7a0483..f1e4a21d4664 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2235,27 +2235,22 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) | |||
2235 | i915_vma_pin_fence(vma); | 2235 | i915_vma_pin_fence(vma); |
2236 | } | 2236 | } |
2237 | 2237 | ||
2238 | i915_vma_get(vma); | ||
2238 | err: | 2239 | err: |
2239 | intel_runtime_pm_put(dev_priv); | 2240 | intel_runtime_pm_put(dev_priv); |
2240 | return vma; | 2241 | return vma; |
2241 | } | 2242 | } |
2242 | 2243 | ||
2243 | void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) | 2244 | void intel_unpin_fb_vma(struct i915_vma *vma) |
2244 | { | 2245 | { |
2245 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 2246 | lockdep_assert_held(&vma->vm->dev->struct_mutex); |
2246 | struct i915_ggtt_view view; | ||
2247 | struct i915_vma *vma; | ||
2248 | |||
2249 | WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex)); | ||
2250 | |||
2251 | intel_fill_fb_ggtt_view(&view, fb, rotation); | ||
2252 | vma = i915_gem_object_to_ggtt(obj, &view); | ||
2253 | 2247 | ||
2254 | if (WARN_ON_ONCE(!vma)) | 2248 | if (WARN_ON_ONCE(!vma)) |
2255 | return; | 2249 | return; |
2256 | 2250 | ||
2257 | i915_vma_unpin_fence(vma); | 2251 | i915_vma_unpin_fence(vma); |
2258 | i915_gem_object_unpin_from_display_plane(vma); | 2252 | i915_gem_object_unpin_from_display_plane(vma); |
2253 | i915_vma_put(vma); | ||
2259 | } | 2254 | } |
2260 | 2255 | ||
2261 | static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, | 2256 | static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, |
@@ -2750,7 +2745,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, | |||
2750 | struct drm_device *dev = intel_crtc->base.dev; | 2745 | struct drm_device *dev = intel_crtc->base.dev; |
2751 | struct drm_i915_private *dev_priv = to_i915(dev); | 2746 | struct drm_i915_private *dev_priv = to_i915(dev); |
2752 | struct drm_crtc *c; | 2747 | struct drm_crtc *c; |
2753 | struct intel_crtc *i; | ||
2754 | struct drm_i915_gem_object *obj; | 2748 | struct drm_i915_gem_object *obj; |
2755 | struct drm_plane *primary = intel_crtc->base.primary; | 2749 | struct drm_plane *primary = intel_crtc->base.primary; |
2756 | struct drm_plane_state *plane_state = primary->state; | 2750 | struct drm_plane_state *plane_state = primary->state; |
@@ -2775,20 +2769,20 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, | |||
2775 | * an fb with another CRTC instead | 2769 | * an fb with another CRTC instead |
2776 | */ | 2770 | */ |
2777 | for_each_crtc(dev, c) { | 2771 | for_each_crtc(dev, c) { |
2778 | i = to_intel_crtc(c); | 2772 | struct intel_plane_state *state; |
2779 | 2773 | ||
2780 | if (c == &intel_crtc->base) | 2774 | if (c == &intel_crtc->base) |
2781 | continue; | 2775 | continue; |
2782 | 2776 | ||
2783 | if (!i->active) | 2777 | if (!to_intel_crtc(c)->active) |
2784 | continue; | 2778 | continue; |
2785 | 2779 | ||
2786 | fb = c->primary->fb; | 2780 | state = to_intel_plane_state(c->primary->state); |
2787 | if (!fb) | 2781 | if (!state->vma) |
2788 | continue; | 2782 | continue; |
2789 | 2783 | ||
2790 | obj = intel_fb_obj(fb); | 2784 | if (intel_plane_ggtt_offset(state) == plane_config->base) { |
2791 | if (i915_gem_object_ggtt_offset(obj, NULL) == plane_config->base) { | 2785 | fb = c->primary->fb; |
2792 | drm_framebuffer_reference(fb); | 2786 | drm_framebuffer_reference(fb); |
2793 | goto valid_fb; | 2787 | goto valid_fb; |
2794 | } | 2788 | } |
@@ -2809,6 +2803,19 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, | |||
2809 | return; | 2803 | return; |
2810 | 2804 | ||
2811 | valid_fb: | 2805 | valid_fb: |
2806 | mutex_lock(&dev->struct_mutex); | ||
2807 | intel_state->vma = | ||
2808 | intel_pin_and_fence_fb_obj(fb, primary->state->rotation); | ||
2809 | mutex_unlock(&dev->struct_mutex); | ||
2810 | if (IS_ERR(intel_state->vma)) { | ||
2811 | DRM_ERROR("failed to pin boot fb on pipe %d: %li\n", | ||
2812 | intel_crtc->pipe, PTR_ERR(intel_state->vma)); | ||
2813 | |||
2814 | intel_state->vma = NULL; | ||
2815 | drm_framebuffer_unreference(fb); | ||
2816 | return; | ||
2817 | } | ||
2818 | |||
2812 | plane_state->src_x = 0; | 2819 | plane_state->src_x = 0; |
2813 | plane_state->src_y = 0; | 2820 | plane_state->src_y = 0; |
2814 | plane_state->src_w = fb->width << 16; | 2821 | plane_state->src_w = fb->width << 16; |
@@ -3104,13 +3111,13 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, | |||
3104 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 3111 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
3105 | if (INTEL_GEN(dev_priv) >= 4) { | 3112 | if (INTEL_GEN(dev_priv) >= 4) { |
3106 | I915_WRITE(DSPSURF(plane), | 3113 | I915_WRITE(DSPSURF(plane), |
3107 | intel_fb_gtt_offset(fb, rotation) + | 3114 | intel_plane_ggtt_offset(plane_state) + |
3108 | intel_crtc->dspaddr_offset); | 3115 | intel_crtc->dspaddr_offset); |
3109 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 3116 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
3110 | I915_WRITE(DSPLINOFF(plane), linear_offset); | 3117 | I915_WRITE(DSPLINOFF(plane), linear_offset); |
3111 | } else { | 3118 | } else { |
3112 | I915_WRITE(DSPADDR(plane), | 3119 | I915_WRITE(DSPADDR(plane), |
3113 | intel_fb_gtt_offset(fb, rotation) + | 3120 | intel_plane_ggtt_offset(plane_state) + |
3114 | intel_crtc->dspaddr_offset); | 3121 | intel_crtc->dspaddr_offset); |
3115 | } | 3122 | } |
3116 | POSTING_READ(reg); | 3123 | POSTING_READ(reg); |
@@ -3207,7 +3214,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, | |||
3207 | 3214 | ||
3208 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 3215 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
3209 | I915_WRITE(DSPSURF(plane), | 3216 | I915_WRITE(DSPSURF(plane), |
3210 | intel_fb_gtt_offset(fb, rotation) + | 3217 | intel_plane_ggtt_offset(plane_state) + |
3211 | intel_crtc->dspaddr_offset); | 3218 | intel_crtc->dspaddr_offset); |
3212 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { | 3219 | if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { |
3213 | I915_WRITE(DSPOFFSET(plane), (y << 16) | x); | 3220 | I915_WRITE(DSPOFFSET(plane), (y << 16) | x); |
@@ -3230,23 +3237,6 @@ u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv, | |||
3230 | } | 3237 | } |
3231 | } | 3238 | } |
3232 | 3239 | ||
3233 | u32 intel_fb_gtt_offset(struct drm_framebuffer *fb, | ||
3234 | unsigned int rotation) | ||
3235 | { | ||
3236 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | ||
3237 | struct i915_ggtt_view view; | ||
3238 | struct i915_vma *vma; | ||
3239 | |||
3240 | intel_fill_fb_ggtt_view(&view, fb, rotation); | ||
3241 | |||
3242 | vma = i915_gem_object_to_ggtt(obj, &view); | ||
3243 | if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n", | ||
3244 | view.type)) | ||
3245 | return -1; | ||
3246 | |||
3247 | return i915_ggtt_offset(vma); | ||
3248 | } | ||
3249 | |||
3250 | static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) | 3240 | static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) |
3251 | { | 3241 | { |
3252 | struct drm_device *dev = intel_crtc->base.dev; | 3242 | struct drm_device *dev = intel_crtc->base.dev; |
@@ -3441,7 +3431,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane, | |||
3441 | } | 3431 | } |
3442 | 3432 | ||
3443 | I915_WRITE(PLANE_SURF(pipe, 0), | 3433 | I915_WRITE(PLANE_SURF(pipe, 0), |
3444 | intel_fb_gtt_offset(fb, rotation) + surf_addr); | 3434 | intel_plane_ggtt_offset(plane_state) + surf_addr); |
3445 | 3435 | ||
3446 | POSTING_READ(PLANE_SURF(pipe, 0)); | 3436 | POSTING_READ(PLANE_SURF(pipe, 0)); |
3447 | } | 3437 | } |
@@ -11536,7 +11526,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
11536 | flush_work(&work->mmio_work); | 11526 | flush_work(&work->mmio_work); |
11537 | 11527 | ||
11538 | mutex_lock(&dev->struct_mutex); | 11528 | mutex_lock(&dev->struct_mutex); |
11539 | intel_unpin_fb_obj(work->old_fb, primary->state->rotation); | 11529 | intel_unpin_fb_vma(work->old_vma); |
11540 | i915_gem_object_put(work->pending_flip_obj); | 11530 | i915_gem_object_put(work->pending_flip_obj); |
11541 | mutex_unlock(&dev->struct_mutex); | 11531 | mutex_unlock(&dev->struct_mutex); |
11542 | 11532 | ||
@@ -12246,8 +12236,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
12246 | goto cleanup_pending; | 12236 | goto cleanup_pending; |
12247 | } | 12237 | } |
12248 | 12238 | ||
12249 | work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation); | 12239 | work->old_vma = to_intel_plane_state(primary->state)->vma; |
12250 | work->gtt_offset += intel_crtc->dspaddr_offset; | 12240 | to_intel_plane_state(primary->state)->vma = vma; |
12241 | |||
12242 | work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset; | ||
12251 | work->rotation = crtc->primary->state->rotation; | 12243 | work->rotation = crtc->primary->state->rotation; |
12252 | 12244 | ||
12253 | /* | 12245 | /* |
@@ -12301,7 +12293,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
12301 | cleanup_request: | 12293 | cleanup_request: |
12302 | i915_add_request_no_flush(request); | 12294 | i915_add_request_no_flush(request); |
12303 | cleanup_unpin: | 12295 | cleanup_unpin: |
12304 | intel_unpin_fb_obj(fb, crtc->primary->state->rotation); | 12296 | to_intel_plane_state(primary->state)->vma = work->old_vma; |
12297 | intel_unpin_fb_vma(vma); | ||
12305 | cleanup_pending: | 12298 | cleanup_pending: |
12306 | atomic_dec(&intel_crtc->unpin_work_count); | 12299 | atomic_dec(&intel_crtc->unpin_work_count); |
12307 | unlock: | 12300 | unlock: |
@@ -14794,6 +14787,8 @@ intel_prepare_plane_fb(struct drm_plane *plane, | |||
14794 | DRM_DEBUG_KMS("failed to pin object\n"); | 14787 | DRM_DEBUG_KMS("failed to pin object\n"); |
14795 | return PTR_ERR(vma); | 14788 | return PTR_ERR(vma); |
14796 | } | 14789 | } |
14790 | |||
14791 | to_intel_plane_state(new_state)->vma = vma; | ||
14797 | } | 14792 | } |
14798 | 14793 | ||
14799 | return 0; | 14794 | return 0; |
@@ -14812,19 +14807,12 @@ void | |||
14812 | intel_cleanup_plane_fb(struct drm_plane *plane, | 14807 | intel_cleanup_plane_fb(struct drm_plane *plane, |
14813 | struct drm_plane_state *old_state) | 14808 | struct drm_plane_state *old_state) |
14814 | { | 14809 | { |
14815 | struct drm_i915_private *dev_priv = to_i915(plane->dev); | 14810 | struct i915_vma *vma; |
14816 | struct intel_plane_state *old_intel_state; | ||
14817 | struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); | ||
14818 | struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); | ||
14819 | |||
14820 | old_intel_state = to_intel_plane_state(old_state); | ||
14821 | |||
14822 | if (!obj && !old_obj) | ||
14823 | return; | ||
14824 | 14811 | ||
14825 | if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR || | 14812 | /* Should only be called after a successful intel_prepare_plane_fb()! */ |
14826 | !INTEL_INFO(dev_priv)->cursor_needs_physical)) | 14813 | vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma); |
14827 | intel_unpin_fb_obj(old_state->fb, old_state->rotation); | 14814 | if (vma) |
14815 | intel_unpin_fb_vma(vma); | ||
14828 | } | 14816 | } |
14829 | 14817 | ||
14830 | int | 14818 | int |
@@ -15166,7 +15154,7 @@ intel_update_cursor_plane(struct drm_plane *plane, | |||
15166 | if (!obj) | 15154 | if (!obj) |
15167 | addr = 0; | 15155 | addr = 0; |
15168 | else if (!INTEL_INFO(dev_priv)->cursor_needs_physical) | 15156 | else if (!INTEL_INFO(dev_priv)->cursor_needs_physical) |
15169 | addr = i915_gem_object_ggtt_offset(obj, NULL); | 15157 | addr = intel_plane_ggtt_offset(state); |
15170 | else | 15158 | else |
15171 | addr = obj->phys_handle->busaddr; | 15159 | addr = obj->phys_handle->busaddr; |
15172 | 15160 | ||
@@ -17066,41 +17054,12 @@ void intel_display_resume(struct drm_device *dev) | |||
17066 | void intel_modeset_gem_init(struct drm_device *dev) | 17054 | void intel_modeset_gem_init(struct drm_device *dev) |
17067 | { | 17055 | { |
17068 | struct drm_i915_private *dev_priv = to_i915(dev); | 17056 | struct drm_i915_private *dev_priv = to_i915(dev); |
17069 | struct drm_crtc *c; | ||
17070 | struct drm_i915_gem_object *obj; | ||
17071 | 17057 | ||
17072 | intel_init_gt_powersave(dev_priv); | 17058 | intel_init_gt_powersave(dev_priv); |
17073 | 17059 | ||
17074 | intel_modeset_init_hw(dev); | 17060 | intel_modeset_init_hw(dev); |
17075 | 17061 | ||
17076 | intel_setup_overlay(dev_priv); | 17062 | intel_setup_overlay(dev_priv); |
17077 | |||
17078 | /* | ||
17079 | * Make sure any fbs we allocated at startup are properly | ||
17080 | * pinned & fenced. When we do the allocation it's too early | ||
17081 | * for this. | ||
17082 | */ | ||
17083 | for_each_crtc(dev, c) { | ||
17084 | struct i915_vma *vma; | ||
17085 | |||
17086 | obj = intel_fb_obj(c->primary->fb); | ||
17087 | if (obj == NULL) | ||
17088 | continue; | ||
17089 | |||
17090 | mutex_lock(&dev->struct_mutex); | ||
17091 | vma = intel_pin_and_fence_fb_obj(c->primary->fb, | ||
17092 | c->primary->state->rotation); | ||
17093 | mutex_unlock(&dev->struct_mutex); | ||
17094 | if (IS_ERR(vma)) { | ||
17095 | DRM_ERROR("failed to pin boot fb on pipe %d\n", | ||
17096 | to_intel_crtc(c)->pipe); | ||
17097 | drm_framebuffer_unreference(c->primary->fb); | ||
17098 | c->primary->fb = NULL; | ||
17099 | c->primary->crtc = c->primary->state->crtc = NULL; | ||
17100 | update_state_fb(c->primary); | ||
17101 | c->state->plane_mask &= ~(1 << drm_plane_index(c->primary)); | ||
17102 | } | ||
17103 | } | ||
17104 | } | 17063 | } |
17105 | 17064 | ||
17106 | int intel_connector_register(struct drm_connector *connector) | 17065 | int intel_connector_register(struct drm_connector *connector) |