|
@@ -2235,27 +2235,22 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
|
|
|
i915_vma_pin_fence(vma);
|
|
|
}
|
|
|
|
|
|
+ i915_vma_get(vma);
|
|
|
err:
|
|
|
intel_runtime_pm_put(dev_priv);
|
|
|
return vma;
|
|
|
}
|
|
|
|
|
|
-void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
|
|
|
+void intel_unpin_fb_vma(struct i915_vma *vma)
|
|
|
{
|
|
|
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
|
|
|
- struct i915_ggtt_view view;
|
|
|
- struct i915_vma *vma;
|
|
|
-
|
|
|
- WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
|
|
|
-
|
|
|
- intel_fill_fb_ggtt_view(&view, fb, rotation);
|
|
|
- vma = i915_gem_object_to_ggtt(obj, &view);
|
|
|
+ lockdep_assert_held(&vma->vm->dev->struct_mutex);
|
|
|
|
|
|
if (WARN_ON_ONCE(!vma))
|
|
|
return;
|
|
|
|
|
|
i915_vma_unpin_fence(vma);
|
|
|
i915_gem_object_unpin_from_display_plane(vma);
|
|
|
+ i915_vma_put(vma);
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
|
struct drm_crtc *c;
|
|
|
- struct intel_crtc *i;
|
|
|
struct drm_i915_gem_object *obj;
|
|
|
struct drm_plane *primary = intel_crtc->base.primary;
|
|
|
struct drm_plane_state *plane_state = primary->state;
|
|
@@ -2775,20 +2769,20 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
|
|
|
* an fb with another CRTC instead
|
|
|
*/
|
|
|
for_each_crtc(dev, c) {
|
|
|
- i = to_intel_crtc(c);
|
|
|
+ struct intel_plane_state *state;
|
|
|
|
|
|
if (c == &intel_crtc->base)
|
|
|
continue;
|
|
|
|
|
|
- if (!i->active)
|
|
|
+ if (!to_intel_crtc(c)->active)
|
|
|
continue;
|
|
|
|
|
|
- fb = c->primary->fb;
|
|
|
- if (!fb)
|
|
|
+ state = to_intel_plane_state(c->primary->state);
|
|
|
+ if (!state->vma)
|
|
|
continue;
|
|
|
|
|
|
- obj = intel_fb_obj(fb);
|
|
|
- if (i915_gem_object_ggtt_offset(obj, NULL) == plane_config->base) {
|
|
|
+ if (intel_plane_ggtt_offset(state) == plane_config->base) {
|
|
|
+ fb = c->primary->fb;
|
|
|
drm_framebuffer_reference(fb);
|
|
|
goto valid_fb;
|
|
|
}
|
|
@@ -2809,6 +2803,19 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
|
|
|
return;
|
|
|
|
|
|
valid_fb:
|
|
|
+ mutex_lock(&dev->struct_mutex);
|
|
|
+ intel_state->vma =
|
|
|
+ intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
+ if (IS_ERR(intel_state->vma)) {
|
|
|
+ DRM_ERROR("failed to pin boot fb on pipe %d: %li\n",
|
|
|
+ intel_crtc->pipe, PTR_ERR(intel_state->vma));
|
|
|
+
|
|
|
+ intel_state->vma = NULL;
|
|
|
+ drm_framebuffer_unreference(fb);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
plane_state->src_x = 0;
|
|
|
plane_state->src_y = 0;
|
|
|
plane_state->src_w = fb->width << 16;
|
|
@@ -3104,13 +3111,13 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
|
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
|
if (INTEL_GEN(dev_priv) >= 4) {
|
|
|
I915_WRITE(DSPSURF(plane),
|
|
|
- intel_fb_gtt_offset(fb, rotation) +
|
|
|
+ intel_plane_ggtt_offset(plane_state) +
|
|
|
intel_crtc->dspaddr_offset);
|
|
|
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
|
|
|
I915_WRITE(DSPLINOFF(plane), linear_offset);
|
|
|
} else {
|
|
|
I915_WRITE(DSPADDR(plane),
|
|
|
- intel_fb_gtt_offset(fb, rotation) +
|
|
|
+ intel_plane_ggtt_offset(plane_state) +
|
|
|
intel_crtc->dspaddr_offset);
|
|
|
}
|
|
|
POSTING_READ(reg);
|
|
@@ -3207,7 +3214,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
|
|
|
|
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
|
I915_WRITE(DSPSURF(plane),
|
|
|
- intel_fb_gtt_offset(fb, rotation) +
|
|
|
+ intel_plane_ggtt_offset(plane_state) +
|
|
|
intel_crtc->dspaddr_offset);
|
|
|
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
|
|
|
I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
|
|
@@ -3230,23 +3237,6 @@ u32 intel_fb_stride_alignment(const struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-u32 intel_fb_gtt_offset(struct drm_framebuffer *fb,
|
|
|
- unsigned int rotation)
|
|
|
-{
|
|
|
- struct drm_i915_gem_object *obj = intel_fb_obj(fb);
|
|
|
- struct i915_ggtt_view view;
|
|
|
- struct i915_vma *vma;
|
|
|
-
|
|
|
- intel_fill_fb_ggtt_view(&view, fb, rotation);
|
|
|
-
|
|
|
- vma = i915_gem_object_to_ggtt(obj, &view);
|
|
|
- if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
|
|
|
- view.type))
|
|
|
- return -1;
|
|
|
-
|
|
|
- return i915_ggtt_offset(vma);
|
|
|
-}
|
|
|
-
|
|
|
static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
|
|
|
{
|
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
|
@@ -3441,7 +3431,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
|
|
|
}
|
|
|
|
|
|
I915_WRITE(PLANE_SURF(pipe, 0),
|
|
|
- intel_fb_gtt_offset(fb, rotation) + surf_addr);
|
|
|
+ intel_plane_ggtt_offset(plane_state) + surf_addr);
|
|
|
|
|
|
POSTING_READ(PLANE_SURF(pipe, 0));
|
|
|
}
|
|
@@ -11536,7 +11526,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
|
|
|
flush_work(&work->mmio_work);
|
|
|
|
|
|
mutex_lock(&dev->struct_mutex);
|
|
|
- intel_unpin_fb_obj(work->old_fb, primary->state->rotation);
|
|
|
+ intel_unpin_fb_vma(work->old_vma);
|
|
|
i915_gem_object_put(work->pending_flip_obj);
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
@@ -12246,8 +12236,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|
|
goto cleanup_pending;
|
|
|
}
|
|
|
|
|
|
- work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation);
|
|
|
- work->gtt_offset += intel_crtc->dspaddr_offset;
|
|
|
+ work->old_vma = to_intel_plane_state(primary->state)->vma;
|
|
|
+ to_intel_plane_state(primary->state)->vma = vma;
|
|
|
+
|
|
|
+ work->gtt_offset = i915_ggtt_offset(vma) + intel_crtc->dspaddr_offset;
|
|
|
work->rotation = crtc->primary->state->rotation;
|
|
|
|
|
|
/*
|
|
@@ -12301,7 +12293,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
|
|
|
cleanup_request:
|
|
|
i915_add_request_no_flush(request);
|
|
|
cleanup_unpin:
|
|
|
- intel_unpin_fb_obj(fb, crtc->primary->state->rotation);
|
|
|
+ to_intel_plane_state(primary->state)->vma = work->old_vma;
|
|
|
+ intel_unpin_fb_vma(vma);
|
|
|
cleanup_pending:
|
|
|
atomic_dec(&intel_crtc->unpin_work_count);
|
|
|
unlock:
|
|
@@ -14794,6 +14787,8 @@ intel_prepare_plane_fb(struct drm_plane *plane,
|
|
|
DRM_DEBUG_KMS("failed to pin object\n");
|
|
|
return PTR_ERR(vma);
|
|
|
}
|
|
|
+
|
|
|
+ to_intel_plane_state(new_state)->vma = vma;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -14812,19 +14807,12 @@ void
|
|
|
intel_cleanup_plane_fb(struct drm_plane *plane,
|
|
|
struct drm_plane_state *old_state)
|
|
|
{
|
|
|
- struct drm_i915_private *dev_priv = to_i915(plane->dev);
|
|
|
- struct intel_plane_state *old_intel_state;
|
|
|
- struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
|
|
|
- struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
|
|
|
-
|
|
|
- old_intel_state = to_intel_plane_state(old_state);
|
|
|
-
|
|
|
- if (!obj && !old_obj)
|
|
|
- return;
|
|
|
+ struct i915_vma *vma;
|
|
|
|
|
|
- if (old_obj && (plane->type != DRM_PLANE_TYPE_CURSOR ||
|
|
|
- !INTEL_INFO(dev_priv)->cursor_needs_physical))
|
|
|
- intel_unpin_fb_obj(old_state->fb, old_state->rotation);
|
|
|
+ /* Should only be called after a successful intel_prepare_plane_fb()! */
|
|
|
+ vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma);
|
|
|
+ if (vma)
|
|
|
+ intel_unpin_fb_vma(vma);
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -15166,7 +15154,7 @@ intel_update_cursor_plane(struct drm_plane *plane,
|
|
|
if (!obj)
|
|
|
addr = 0;
|
|
|
else if (!INTEL_INFO(dev_priv)->cursor_needs_physical)
|
|
|
- addr = i915_gem_object_ggtt_offset(obj, NULL);
|
|
|
+ addr = intel_plane_ggtt_offset(state);
|
|
|
else
|
|
|
addr = obj->phys_handle->busaddr;
|
|
|
|
|
@@ -17066,41 +17054,12 @@ void intel_display_resume(struct drm_device *dev)
|
|
|
void intel_modeset_gem_init(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = to_i915(dev);
|
|
|
- struct drm_crtc *c;
|
|
|
- struct drm_i915_gem_object *obj;
|
|
|
|
|
|
intel_init_gt_powersave(dev_priv);
|
|
|
|
|
|
intel_modeset_init_hw(dev);
|
|
|
|
|
|
intel_setup_overlay(dev_priv);
|
|
|
-
|
|
|
- /*
|
|
|
- * Make sure any fbs we allocated at startup are properly
|
|
|
- * pinned & fenced. When we do the allocation it's too early
|
|
|
- * for this.
|
|
|
- */
|
|
|
- for_each_crtc(dev, c) {
|
|
|
- struct i915_vma *vma;
|
|
|
-
|
|
|
- obj = intel_fb_obj(c->primary->fb);
|
|
|
- if (obj == NULL)
|
|
|
- continue;
|
|
|
-
|
|
|
- mutex_lock(&dev->struct_mutex);
|
|
|
- vma = intel_pin_and_fence_fb_obj(c->primary->fb,
|
|
|
- c->primary->state->rotation);
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
- if (IS_ERR(vma)) {
|
|
|
- DRM_ERROR("failed to pin boot fb on pipe %d\n",
|
|
|
- to_intel_crtc(c)->pipe);
|
|
|
- drm_framebuffer_unreference(c->primary->fb);
|
|
|
- c->primary->fb = NULL;
|
|
|
- c->primary->crtc = c->primary->state->crtc = NULL;
|
|
|
- update_state_fb(c->primary);
|
|
|
- c->state->plane_mask &= ~(1 << drm_plane_index(c->primary));
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
int intel_connector_register(struct drm_connector *connector)
|