Merge tag 'drm-intel-next-2018-06-06' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Fri, 22 Jun 2018 01:34:41 +0000 (11:34 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 22 Jun 2018 01:34:53 +0000 (11:34 +1000)
- Ice Lake's display enabling patches (Jose, Mahesh, Dhinakaran, Paulo, Manasi, Anusha, Arkadiusz)
- Ice Lake's workarounds (Oscar and Yunwei)
- Ice Lake interrupt registers fixes (Oscar)
- Context switch timeline fixes and improvements (Chris)
- Spelling fixes (Colin)
- GPU reset fixes and improvements (Chris)
  - Including fixes on execlist and preemption for a proper GPU reset (Chris)
- Clean-up the port pipe select bits (Ville)
- Other execlist improvements (Chris)
- Remove unused enable_cmd_parser parameter (Chris)
- Fix order of enabling pipe/transcoder/planes on HSW+ to avoid hang on ICL (Paulo)
- Simplification and changes on intel_context (Chris)
- Disable LVDS on Radiant P845 (Ondrej)
- Improve HSW/BDW voltage swing handling (Ville)
- Cleanup and renames on few parts of intel_dp code to make code clear and less confusing (Ville)
- Move acpi lid notification code for fixing LVDS (Chris)
- Speed up GPU idle detection (Chris)
- Make intel_engine_dump irqsafe (Chris)
- Fix GVT crash (Zhenyu)
- Move GEM BO inside drm_framebuffer and use intel_fb_obj everywhere (Chris)
- Revert edp's alternate fixed mode (Jani)
- Protect tainted function pointer lookup (Chris)
  - And subsequent unsigned long size fix (Chris)
- Allow page directory allocation to fail (Chris)
- VBT's edp and lvds fix and clean-up (Ville)
- Many other reorganizations and cleanups on DDI and DP code, as well on scaler and planes (Ville)
- Selftest pin the mock kernel context (Chris)
- Many PSR Fixes, clean-up and improvements (Dhinakaran)
- PSR VBT fix (Vathsala)
- Fix i915_scheduler and intel_context declaration (Tvrtko)
- Improve PCH underruns detection on ILK-IVB (Ville)
- Few s/drm_priv/i915 (Chris, Michal)
- Notify opregion of the sanitized encoder state (Maarten)
- Guc's event handling improvements and fixes on initialization failures (Michal)
- Many gtt fixes and improvements (Chris)
- Fixes and improvements for Suspend and Freeze safely (Chris)
- i915_gem init and fini cleanup and fixes (Michal)
- Remove obsolete switch_mm for gen8+ (Chris)
- hw and context id fixes for GuC (Lionel)
- Add new vGPU cap info bit VGT_CAPS_HUGE_GTT (Changbin)
- Make context pin/unpin symmetric (Chris)
- vma: Move the bind_count vs pin_count assertion to a helper (Chris)
- Use available SZ_1M instead of 1 << 20 (Chris)
- Trace and PMU fixes and improvements (Tvrtko)

Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180611162737.GA2378@intel.com
84 files changed:
drivers/gpu/drm/i915/gvt/aperture_gm.c
drivers/gpu/drm/i915/gvt/display.c
drivers/gpu/drm/i915/gvt/fb_decoder.c
drivers/gpu/drm/i915/gvt/gvt.h
drivers/gpu/drm/i915/gvt/mmio_context.c
drivers/gpu/drm/i915/gvt/mmio_context.h
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/gvt/scheduler.h
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem.h
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_context.h
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_gtt.h
drivers/gpu/drm/i915/i915_gem_render_state.c
drivers/gpu/drm/i915/i915_gem_shrinker.c
drivers/gpu/drm/i915/i915_gem_stolen.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_gpu_error.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_params.c
drivers/gpu/drm/i915/i915_params.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_pmu.h
drivers/gpu/drm/i915/i915_pvinfo.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_request.c
drivers/gpu/drm/i915/i915_request.h
drivers/gpu/drm/i915/i915_trace.h
drivers/gpu/drm/i915/i915_vgpu.c
drivers/gpu/drm/i915/i915_vgpu.h
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_breadcrumbs.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_display.h
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dpll_mgr.c
drivers/gpu/drm/i915/intel_dpll_mgr.h
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_frontbuffer.c
drivers/gpu/drm/i915/intel_guc.c
drivers/gpu/drm/i915/intel_guc_submission.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_lrc.h
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_psr.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/i915/intel_uc.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/i915/intel_vbt_defs.h
drivers/gpu/drm/i915/intel_workarounds.c
drivers/gpu/drm/i915/selftests/huge_pages.c
drivers/gpu/drm/i915/selftests/i915_gem_context.c
drivers/gpu/drm/i915/selftests/i915_gem_evict.c
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
drivers/gpu/drm/i915/selftests/i915_gem_object.c
drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
drivers/gpu/drm/i915/selftests/i915_request.c
drivers/gpu/drm/i915/selftests/i915_vma.c
drivers/gpu/drm/i915/selftests/intel_hangcheck.c
drivers/gpu/drm/i915/selftests/intel_lrc.c
drivers/gpu/drm/i915/selftests/intel_workarounds.c
drivers/gpu/drm/i915/selftests/mock_context.c
drivers/gpu/drm/i915/selftests/mock_engine.c
drivers/gpu/drm/i915/selftests/mock_gem_device.c
drivers/gpu/drm/i915/selftests/mock_gtt.c

index 7c9ec4f4f36c747464342d14c8e3b5dd4c778335..380eeb2a0e83c60c1067a6d7150bd8608662d5b1 100644 (file)
@@ -61,7 +61,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
        }
 
        mutex_lock(&dev_priv->drm.struct_mutex);
-       ret = i915_gem_gtt_insert(&dev_priv->ggtt.base, node,
+       ret = i915_gem_gtt_insert(&dev_priv->ggtt.vm, node,
                                  size, I915_GTT_PAGE_SIZE,
                                  I915_COLOR_UNEVICTABLE,
                                  start, end, flags);
index 6d8180e8d1e21a71916e8b6cad404dab8d8c3257..120e24c3fc628415c73def88ae84d52efb766288 100644 (file)
@@ -273,8 +273,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
        for_each_pipe(dev_priv, pipe) {
                vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
                vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
-               vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
-               vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
        }
 
        vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
index 1c120683e9588c5a1d379c370e2760234f2d3ab1..00b788cf8b13eea6d71508ec9814310f8d5d4e4a 100644 (file)
@@ -300,16 +300,16 @@ static int cursor_mode_to_drm(int mode)
        int cursor_pixel_formats_index = 4;
 
        switch (mode) {
-       case CURSOR_MODE_128_ARGB_AX:
+       case MCURSOR_MODE_128_ARGB_AX:
                cursor_pixel_formats_index = 0;
                break;
-       case CURSOR_MODE_256_ARGB_AX:
+       case MCURSOR_MODE_256_ARGB_AX:
                cursor_pixel_formats_index = 1;
                break;
-       case CURSOR_MODE_64_ARGB_AX:
+       case MCURSOR_MODE_64_ARGB_AX:
                cursor_pixel_formats_index = 2;
                break;
-       case CURSOR_MODE_64_32B_AX:
+       case MCURSOR_MODE_64_32B_AX:
                cursor_pixel_formats_index = 3;
                break;
 
@@ -342,8 +342,8 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
                return -ENODEV;
 
        val = vgpu_vreg_t(vgpu, CURCNTR(pipe));
-       mode = val & CURSOR_MODE;
-       plane->enabled = (mode != CURSOR_MODE_DISABLE);
+       mode = val & MCURSOR_MODE;
+       plane->enabled = (mode != MCURSOR_MODE_DISABLE);
        if (!plane->enabled)
                return -ENODEV;
 
index 05d15a095310d41b75d6ab64aa04162799f393a1..2ff0d40281a9a8c28b8b5237da010fdfc0720ca0 100644 (file)
@@ -361,9 +361,9 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt);
 #define gvt_aperture_sz(gvt)     (gvt->dev_priv->ggtt.mappable_end)
 #define gvt_aperture_pa_base(gvt) (gvt->dev_priv->ggtt.gmadr.start)
 
-#define gvt_ggtt_gm_sz(gvt)      (gvt->dev_priv->ggtt.base.total)
+#define gvt_ggtt_gm_sz(gvt)      (gvt->dev_priv->ggtt.vm.total)
 #define gvt_ggtt_sz(gvt) \
-       ((gvt->dev_priv->ggtt.base.total >> PAGE_SHIFT) << 3)
+       ((gvt->dev_priv->ggtt.vm.total >> PAGE_SHIFT) << 3)
 #define gvt_hidden_sz(gvt)       (gvt_ggtt_gm_sz(gvt) - gvt_aperture_sz(gvt))
 
 #define gvt_aperture_gmadr_base(gvt) (0)
index 0f949554d118c22e1313cfecc2948d0fcc4672ef..708170e61625add3c2493cbecfd805d38b4cd941 100644 (file)
@@ -446,9 +446,9 @@ static void switch_mocs(struct intel_vgpu *pre, struct intel_vgpu *next,
 
 #define CTX_CONTEXT_CONTROL_VAL        0x03
 
-bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id)
+bool is_inhibit_context(struct intel_context *ce)
 {
-       u32 *reg_state = ctx->__engine[ring_id].lrc_reg_state;
+       const u32 *reg_state = ce->lrc_reg_state;
        u32 inhibit_mask =
                _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
 
@@ -501,7 +501,7 @@ static void switch_mmio(struct intel_vgpu *pre,
                         * itself.
                         */
                        if (mmio->in_context &&
-                           !is_inhibit_context(s->shadow_ctx, ring_id))
+                           !is_inhibit_context(&s->shadow_ctx->__engine[ring_id]))
                                continue;
 
                        if (mmio->mask)
index 0439eb8057a8a51068263a4272043d4463777c97..5c3b9ff9f96aa979edebd277a8b000715a3a7d72 100644 (file)
@@ -49,7 +49,7 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
 
 void intel_gvt_init_engine_mmio_context(struct intel_gvt *gvt);
 
-bool is_inhibit_context(struct i915_gem_context *ctx, int ring_id);
+bool is_inhibit_context(struct intel_context *ce);
 
 int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu,
                                       struct i915_request *req);
index c2d183b91500b72fccb8acd335e36f522b7403ee..7f5e01df95eee71786b8c1a65c894f27815de6a6 100644 (file)
@@ -54,11 +54,8 @@ static void set_context_pdp_root_pointer(
 
 static void update_shadow_pdps(struct intel_vgpu_workload *workload)
 {
-       struct intel_vgpu *vgpu = workload->vgpu;
-       int ring_id = workload->ring_id;
-       struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx;
        struct drm_i915_gem_object *ctx_obj =
-               shadow_ctx->__engine[ring_id].state->obj;
+               workload->req->hw_context->state->obj;
        struct execlist_ring_context *shadow_ring_context;
        struct page *page;
 
@@ -128,9 +125,8 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
        struct intel_vgpu *vgpu = workload->vgpu;
        struct intel_gvt *gvt = vgpu->gvt;
        int ring_id = workload->ring_id;
-       struct i915_gem_context *shadow_ctx = vgpu->submission.shadow_ctx;
        struct drm_i915_gem_object *ctx_obj =
-               shadow_ctx->__engine[ring_id].state->obj;
+               workload->req->hw_context->state->obj;
        struct execlist_ring_context *shadow_ring_context;
        struct page *page;
        void *dst;
@@ -205,7 +201,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
 
 static inline bool is_gvt_request(struct i915_request *req)
 {
-       return i915_gem_context_force_single_submission(req->ctx);
+       return i915_gem_context_force_single_submission(req->gem_context);
 }
 
 static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id)
@@ -280,10 +276,8 @@ static int shadow_context_status_change(struct notifier_block *nb,
        return NOTIFY_OK;
 }
 
-static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
-               struct intel_engine_cs *engine)
+static void shadow_context_descriptor_update(struct intel_context *ce)
 {
-       struct intel_context *ce = to_intel_context(ctx, engine);
        u64 desc = 0;
 
        desc = ce->lrc_desc;
@@ -292,7 +286,7 @@ static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
         * like GEN8_CTX_* cached in desc_template
         */
        desc &= U64_MAX << 12;
-       desc |= ctx->desc_template & ((1ULL << 12) - 1);
+       desc |= ce->gem_context->desc_template & ((1ULL << 12) - 1);
 
        ce->lrc_desc = desc;
 }
@@ -300,12 +294,11 @@ static void shadow_context_descriptor_update(struct i915_gem_context *ctx,
 static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload)
 {
        struct intel_vgpu *vgpu = workload->vgpu;
+       struct i915_request *req = workload->req;
        void *shadow_ring_buffer_va;
        u32 *cs;
-       struct i915_request *req = workload->req;
 
-       if (IS_KABYLAKE(req->i915) &&
-           is_inhibit_context(req->ctx, req->engine->id))
+       if (IS_KABYLAKE(req->i915) && is_inhibit_context(req->hw_context))
                intel_vgpu_restore_inhibit_context(vgpu, req);
 
        /* allocate shadow ring buffer */
@@ -353,92 +346,67 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
        struct intel_vgpu_submission *s = &vgpu->submission;
        struct i915_gem_context *shadow_ctx = s->shadow_ctx;
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
-       int ring_id = workload->ring_id;
-       struct intel_engine_cs *engine = dev_priv->engine[ring_id];
-       struct intel_ring *ring;
+       struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
+       struct intel_context *ce;
+       struct i915_request *rq;
        int ret;
 
        lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
-       if (workload->shadowed)
+       if (workload->req)
                return 0;
 
+       /* pin shadow context by gvt even the shadow context will be pinned
+        * when i915 alloc request. That is because gvt will update the guest
+        * context from shadow context when workload is completed, and at that
+        * moment, i915 may already unpined the shadow context to make the
+        * shadow_ctx pages invalid. So gvt need to pin itself. After update
+        * the guest context, gvt can unpin the shadow_ctx safely.
+        */
+       ce = intel_context_pin(shadow_ctx, engine);
+       if (IS_ERR(ce)) {
+               gvt_vgpu_err("fail to pin shadow context\n");
+               return PTR_ERR(ce);
+       }
+
        shadow_ctx->desc_template &= ~(0x3 << GEN8_CTX_ADDRESSING_MODE_SHIFT);
        shadow_ctx->desc_template |= workload->ctx_desc.addressing_mode <<
                                    GEN8_CTX_ADDRESSING_MODE_SHIFT;
 
-       if (!test_and_set_bit(ring_id, s->shadow_ctx_desc_updated))
-               shadow_context_descriptor_update(shadow_ctx,
-                                       dev_priv->engine[ring_id]);
+       if (!test_and_set_bit(workload->ring_id, s->shadow_ctx_desc_updated))
+               shadow_context_descriptor_update(ce);
 
        ret = intel_gvt_scan_and_shadow_ringbuffer(workload);
        if (ret)
-               goto err_scan;
+               goto err_unpin;
 
        if ((workload->ring_id == RCS) &&
            (workload->wa_ctx.indirect_ctx.size != 0)) {
                ret = intel_gvt_scan_and_shadow_wa_ctx(&workload->wa_ctx);
                if (ret)
-                       goto err_scan;
+                       goto err_shadow;
        }
 
-       /* pin shadow context by gvt even the shadow context will be pinned
-        * when i915 alloc request. That is because gvt will update the guest
-        * context from shadow context when workload is completed, and at that
-        * moment, i915 may already unpined the shadow context to make the
-        * shadow_ctx pages invalid. So gvt need to pin itself. After update
-        * the guest context, gvt can unpin the shadow_ctx safely.
-        */
-       ring = intel_context_pin(shadow_ctx, engine);
-       if (IS_ERR(ring)) {
-               ret = PTR_ERR(ring);
-               gvt_vgpu_err("fail to pin shadow context\n");
+       rq = i915_request_alloc(engine, shadow_ctx);
+       if (IS_ERR(rq)) {
+               gvt_vgpu_err("fail to allocate gem request\n");
+               ret = PTR_ERR(rq);
                goto err_shadow;
        }
+       workload->req = i915_request_get(rq);
 
        ret = populate_shadow_context(workload);
        if (ret)
-               goto err_unpin;
-       workload->shadowed = true;
-       return 0;
+               goto err_req;
 
-err_unpin:
-       intel_context_unpin(shadow_ctx, engine);
+       return 0;
+err_req:
+       rq = fetch_and_zero(&workload->req);
+       i915_request_put(rq);
 err_shadow:
        release_shadow_wa_ctx(&workload->wa_ctx);
-err_scan:
-       return ret;
-}
-
-static int intel_gvt_generate_request(struct intel_vgpu_workload *workload)
-{
-       int ring_id = workload->ring_id;
-       struct drm_i915_private *dev_priv = workload->vgpu->gvt->dev_priv;
-       struct intel_engine_cs *engine = dev_priv->engine[ring_id];
-       struct i915_request *rq;
-       struct intel_vgpu *vgpu = workload->vgpu;
-       struct intel_vgpu_submission *s = &vgpu->submission;
-       struct i915_gem_context *shadow_ctx = s->shadow_ctx;
-       int ret;
-
-       rq = i915_request_alloc(dev_priv->engine[ring_id], shadow_ctx);
-       if (IS_ERR(rq)) {
-               gvt_vgpu_err("fail to allocate gem request\n");
-               ret = PTR_ERR(rq);
-               goto err_unpin;
-       }
-
-       gvt_dbg_sched("ring id %d get i915 gem request %p\n", ring_id, rq);
-
-       workload->req = i915_request_get(rq);
-       ret = copy_workload_to_ring_buffer(workload);
-       if (ret)
-               goto err_unpin;
-       return 0;
-
 err_unpin:
-       intel_context_unpin(shadow_ctx, engine);
-       release_shadow_wa_ctx(&workload->wa_ctx);
+       intel_context_unpin(ce);
        return ret;
 }
 
@@ -517,21 +485,13 @@ err:
        return ret;
 }
 
-static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
+static void update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 {
-       struct intel_vgpu_workload *workload = container_of(wa_ctx,
-                                       struct intel_vgpu_workload,
-                                       wa_ctx);
-       int ring_id = workload->ring_id;
-       struct intel_vgpu_submission *s = &workload->vgpu->submission;
-       struct i915_gem_context *shadow_ctx = s->shadow_ctx;
-       struct drm_i915_gem_object *ctx_obj =
-               shadow_ctx->__engine[ring_id].state->obj;
-       struct execlist_ring_context *shadow_ring_context;
-       struct page *page;
-
-       page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
-       shadow_ring_context = kmap_atomic(page);
+       struct intel_vgpu_workload *workload =
+               container_of(wa_ctx, struct intel_vgpu_workload, wa_ctx);
+       struct i915_request *rq = workload->req;
+       struct execlist_ring_context *shadow_ring_context =
+               (struct execlist_ring_context *)rq->hw_context->lrc_reg_state;
 
        shadow_ring_context->bb_per_ctx_ptr.val =
                (shadow_ring_context->bb_per_ctx_ptr.val &
@@ -539,9 +499,6 @@ static int update_wa_ctx_2_shadow_ctx(struct intel_shadow_wa_ctx *wa_ctx)
        shadow_ring_context->rcs_indirect_ctx.val =
                (shadow_ring_context->rcs_indirect_ctx.val &
                (~INDIRECT_CTX_ADDR_MASK)) | wa_ctx->indirect_ctx.shadow_gma;
-
-       kunmap_atomic(shadow_ring_context);
-       return 0;
 }
 
 static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
@@ -633,7 +590,7 @@ static int prepare_workload(struct intel_vgpu_workload *workload)
                goto err_unpin_mm;
        }
 
-       ret = intel_gvt_generate_request(workload);
+       ret = copy_workload_to_ring_buffer(workload);
        if (ret) {
                gvt_vgpu_err("fail to generate request\n");
                goto err_unpin_mm;
@@ -670,12 +627,9 @@ err_unpin_mm:
 static int dispatch_workload(struct intel_vgpu_workload *workload)
 {
        struct intel_vgpu *vgpu = workload->vgpu;
-       struct intel_vgpu_submission *s = &vgpu->submission;
-       struct i915_gem_context *shadow_ctx = s->shadow_ctx;
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
        int ring_id = workload->ring_id;
-       struct intel_engine_cs *engine = dev_priv->engine[ring_id];
-       int ret = 0;
+       int ret;
 
        gvt_dbg_sched("ring id %d prepare to dispatch workload %p\n",
                ring_id, workload);
@@ -687,10 +641,6 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
                goto out;
 
        ret = prepare_workload(workload);
-       if (ret) {
-               intel_context_unpin(shadow_ctx, engine);
-               goto out;
-       }
 
 out:
        if (ret)
@@ -765,27 +715,23 @@ out:
 
 static void update_guest_context(struct intel_vgpu_workload *workload)
 {
+       struct i915_request *rq = workload->req;
        struct intel_vgpu *vgpu = workload->vgpu;
        struct intel_gvt *gvt = vgpu->gvt;
-       struct intel_vgpu_submission *s = &vgpu->submission;
-       struct i915_gem_context *shadow_ctx = s->shadow_ctx;
-       int ring_id = workload->ring_id;
-       struct drm_i915_gem_object *ctx_obj =
-               shadow_ctx->__engine[ring_id].state->obj;
+       struct drm_i915_gem_object *ctx_obj = rq->hw_context->state->obj;
        struct execlist_ring_context *shadow_ring_context;
        struct page *page;
        void *src;
        unsigned long context_gpa, context_page_num;
        int i;
 
-       gvt_dbg_sched("ring id %d workload lrca %x\n", ring_id,
-                       workload->ctx_desc.lrca);
-
-       context_page_num = gvt->dev_priv->engine[ring_id]->context_size;
+       gvt_dbg_sched("ring id %d workload lrca %x\n", rq->engine->id,
+                     workload->ctx_desc.lrca);
 
+       context_page_num = rq->engine->context_size;
        context_page_num = context_page_num >> PAGE_SHIFT;
 
-       if (IS_BROADWELL(gvt->dev_priv) && ring_id == RCS)
+       if (IS_BROADWELL(gvt->dev_priv) && rq->engine->id == RCS)
                context_page_num = 19;
 
        i = 2;
@@ -858,6 +804,7 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
                scheduler->current_workload[ring_id];
        struct intel_vgpu *vgpu = workload->vgpu;
        struct intel_vgpu_submission *s = &vgpu->submission;
+       struct i915_request *rq = workload->req;
        int event;
 
        mutex_lock(&gvt->lock);
@@ -866,11 +813,7 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
         * switch to make sure request is completed.
         * For the workload w/o request, directly complete the workload.
         */
-       if (workload->req) {
-               struct drm_i915_private *dev_priv =
-                       workload->vgpu->gvt->dev_priv;
-               struct intel_engine_cs *engine =
-                       dev_priv->engine[workload->ring_id];
+       if (rq) {
                wait_event(workload->shadow_ctx_status_wq,
                           !atomic_read(&workload->shadow_ctx_active));
 
@@ -886,8 +829,6 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
                                workload->status = 0;
                }
 
-               i915_request_put(fetch_and_zero(&workload->req));
-
                if (!workload->status && !(vgpu->resetting_eng &
                                           ENGINE_MASK(ring_id))) {
                        update_guest_context(workload);
@@ -896,10 +837,13 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
                                         INTEL_GVT_EVENT_MAX)
                                intel_vgpu_trigger_virtual_event(vgpu, event);
                }
-               mutex_lock(&dev_priv->drm.struct_mutex);
+
                /* unpin shadow ctx as the shadow_ctx update is done */
-               intel_context_unpin(s->shadow_ctx, engine);
-               mutex_unlock(&dev_priv->drm.struct_mutex);
+               mutex_lock(&rq->i915->drm.struct_mutex);
+               intel_context_unpin(rq->hw_context);
+               mutex_unlock(&rq->i915->drm.struct_mutex);
+
+               i915_request_put(fetch_and_zero(&workload->req));
        }
 
        gvt_dbg_sched("ring id %d complete workload %p status %d\n",
@@ -1270,7 +1214,6 @@ alloc_workload(struct intel_vgpu *vgpu)
        atomic_set(&workload->shadow_ctx_active, 0);
 
        workload->status = -EINPROGRESS;
-       workload->shadowed = false;
        workload->vgpu = vgpu;
 
        return workload;
index 6c644782193eaf28241174ea3e3f8d59776b2bf6..21eddab4a9cd465b1f835cb310ea091387d9bea2 100644 (file)
@@ -83,7 +83,6 @@ struct intel_vgpu_workload {
        struct i915_request *req;
        /* if this workload has been dispatched to i915? */
        bool dispatched;
-       bool shadowed;
        int status;
 
        struct intel_vgpu_mm *shadow_mm;
index 13e7b9e4a6e6ffa7f15aa4e9740df9ffd3b68737..698af45e229ce2e4517b3f062ff7803fb7c9f62e 100644 (file)
@@ -328,7 +328,7 @@ static int per_file_stats(int id, void *ptr, void *data)
                } else {
                        struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vma->vm);
 
-                       if (ppgtt->base.file != stats->file_priv)
+                       if (ppgtt->vm.file != stats->file_priv)
                                continue;
                }
 
@@ -508,7 +508,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
                   dpy_count, dpy_size);
 
        seq_printf(m, "%llu [%pa] gtt total\n",
-                  ggtt->base.total, &ggtt->mappable_end);
+                  ggtt->vm.total, &ggtt->mappable_end);
        seq_printf(m, "Supported page sizes: %s\n",
                   stringify_page_sizes(INTEL_INFO(dev_priv)->page_sizes,
                                        buf, sizeof(buf)));
@@ -542,8 +542,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
                                                   struct i915_request,
                                                   client_link);
                rcu_read_lock();
-               task = pid_task(request && request->ctx->pid ?
-                               request->ctx->pid : file->pid,
+               task = pid_task(request && request->gem_context->pid ?
+                               request->gem_context->pid : file->pid,
                                PIDTYPE_PID);
                print_file_stats(m, task ? task->comm : "<unknown>", stats);
                rcu_read_unlock();
@@ -1162,19 +1162,28 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 
                intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
-               if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv)) {
-                       pm_ier = I915_READ(GEN6_PMIER);
-                       pm_imr = I915_READ(GEN6_PMIMR);
-                       pm_isr = I915_READ(GEN6_PMISR);
-                       pm_iir = I915_READ(GEN6_PMIIR);
-                       pm_mask = I915_READ(GEN6_PMINTRMSK);
-               } else {
+               if (INTEL_GEN(dev_priv) >= 11) {
+                       pm_ier = I915_READ(GEN11_GPM_WGBOXPERF_INTR_ENABLE);
+                       pm_imr = I915_READ(GEN11_GPM_WGBOXPERF_INTR_MASK);
+                       /*
+                        * The equivalent to the PM ISR & IIR cannot be read
+                        * without affecting the current state of the system
+                        */
+                       pm_isr = 0;
+                       pm_iir = 0;
+               } else if (INTEL_GEN(dev_priv) >= 8) {
                        pm_ier = I915_READ(GEN8_GT_IER(2));
                        pm_imr = I915_READ(GEN8_GT_IMR(2));
                        pm_isr = I915_READ(GEN8_GT_ISR(2));
                        pm_iir = I915_READ(GEN8_GT_IIR(2));
-                       pm_mask = I915_READ(GEN6_PMINTRMSK);
+               } else {
+                       pm_ier = I915_READ(GEN6_PMIER);
+                       pm_imr = I915_READ(GEN6_PMIMR);
+                       pm_isr = I915_READ(GEN6_PMISR);
+                       pm_iir = I915_READ(GEN6_PMIIR);
                }
+               pm_mask = I915_READ(GEN6_PMINTRMSK);
+
                seq_printf(m, "Video Turbo Mode: %s\n",
                           yesno(rpmodectl & GEN6_RP_MEDIA_TURBO));
                seq_printf(m, "HW control enabled: %s\n",
@@ -1182,8 +1191,12 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
                seq_printf(m, "SW control enabled: %s\n",
                           yesno((rpmodectl & GEN6_RP_MEDIA_MODE_MASK) ==
                                  GEN6_RP_MEDIA_SW_MODE));
-               seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
-                          pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
+
+               seq_printf(m, "PM IER=0x%08x IMR=0x%08x, MASK=0x%08x\n",
+                          pm_ier, pm_imr, pm_mask);
+               if (INTEL_GEN(dev_priv) <= 10)
+                       seq_printf(m, "PM ISR=0x%08x IIR=0x%08x\n",
+                                  pm_isr, pm_iir);
                seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n",
                           rps->pm_intrmsk_mbz);
                seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
@@ -1895,7 +1908,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
                           fbdev_fb->base.format->cpp[0] * 8,
                           fbdev_fb->base.modifier,
                           drm_framebuffer_read_refcount(&fbdev_fb->base));
-               describe_obj(m, fbdev_fb->obj);
+               describe_obj(m, intel_fb_obj(&fbdev_fb->base));
                seq_putc(m, '\n');
        }
 #endif
@@ -1913,7 +1926,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
                           fb->base.format->cpp[0] * 8,
                           fb->base.modifier,
                           drm_framebuffer_read_refcount(&fb->base));
-               describe_obj(m, fb->obj);
+               describe_obj(m, intel_fb_obj(&fb->base));
                seq_putc(m, '\n');
        }
        mutex_unlock(&dev->mode_config.fb_lock);
@@ -2630,8 +2643,6 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        u32 psrperf = 0;
-       u32 stat[3];
-       enum pipe pipe;
        bool enabled = false;
        bool sink_support;
 
@@ -2652,47 +2663,17 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
        seq_printf(m, "Re-enable work scheduled: %s\n",
                   yesno(work_busy(&dev_priv->psr.work.work)));
 
-       if (HAS_DDI(dev_priv)) {
-               if (dev_priv->psr.psr2_enabled)
-                       enabled = I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE;
-               else
-                       enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
-       } else {
-               for_each_pipe(dev_priv, pipe) {
-                       enum transcoder cpu_transcoder =
-                               intel_pipe_to_cpu_transcoder(dev_priv, pipe);
-                       enum intel_display_power_domain power_domain;
-
-                       power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder);
-                       if (!intel_display_power_get_if_enabled(dev_priv,
-                                                               power_domain))
-                               continue;
-
-                       stat[pipe] = I915_READ(VLV_PSRSTAT(pipe)) &
-                               VLV_EDP_PSR_CURR_STATE_MASK;
-                       if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
-                           (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
-                               enabled = true;
-
-                       intel_display_power_put(dev_priv, power_domain);
-               }
-       }
+       if (dev_priv->psr.psr2_enabled)
+               enabled = I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE;
+       else
+               enabled = I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
 
        seq_printf(m, "Main link in standby mode: %s\n",
                   yesno(dev_priv->psr.link_standby));
 
-       seq_printf(m, "HW Enabled & Active bit: %s", yesno(enabled));
-
-       if (!HAS_DDI(dev_priv))
-               for_each_pipe(dev_priv, pipe) {
-                       if ((stat[pipe] == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
-                           (stat[pipe] == VLV_EDP_PSR_ACTIVE_SF_UPDATE))
-                               seq_printf(m, " pipe %c", pipe_name(pipe));
-               }
-       seq_puts(m, "\n");
+       seq_printf(m, "HW Enabled & Active bit: %s\n", yesno(enabled));
 
        /*
-        * VLV/CHV PSR has no kind of performance counter
         * SKL+ Perf counter is reset to 0 everytime DC state is entered
         */
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -4245,8 +4226,13 @@ i915_drop_caches_set(void *data, u64 val)
                i915_gem_shrink_all(dev_priv);
        fs_reclaim_release(GFP_KERNEL);
 
-       if (val & DROP_IDLE)
-               drain_delayed_work(&dev_priv->gt.idle_work);
+       if (val & DROP_IDLE) {
+               do {
+                       if (READ_ONCE(dev_priv->gt.active_requests))
+                               flush_delayed_work(&dev_priv->gt.retire_work);
+                       drain_delayed_work(&dev_priv->gt.idle_work);
+               } while (READ_ONCE(dev_priv->gt.awake));
+       }
 
        if (val & DROP_FREED)
                i915_gem_drain_freed_objects(dev_priv);
index 9c449b8d8eabb666fa6a420ec3301bc0ee84d845..be71fdf8d92e1659be47d1cad9410b652862cc84 100644 (file)
@@ -67,6 +67,7 @@ bool __i915_inject_load_failure(const char *func, int line)
        if (++i915_load_fail_count == i915_modparams.inject_load_failure) {
                DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
                         i915_modparams.inject_load_failure, func, line);
+               i915_modparams.inject_load_failure = 0;
                return true;
        }
 
@@ -117,16 +118,15 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
 static bool i915_error_injected(struct drm_i915_private *dev_priv)
 {
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
-       return i915_modparams.inject_load_failure &&
-              i915_load_fail_count == i915_modparams.inject_load_failure;
+       return i915_load_fail_count && !i915_modparams.inject_load_failure;
 #else
        return false;
 #endif
 }
 
-#define i915_load_error(dev_priv, fmt, ...)                                 \
-       __i915_printk(dev_priv,                                              \
-                     i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
+#define i915_load_error(i915, fmt, ...)                                         \
+       __i915_printk(i915,                                              \
+                     i915_error_injected(i915) ? KERN_DEBUG : KERN_ERR, \
                      fmt, ##__VA_ARGS__)
 
 /* Map PCH device id to PCH type, or PCH_NONE if unknown. */
@@ -233,6 +233,8 @@ intel_virt_detect_pch(const struct drm_i915_private *dev_priv)
                id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
        else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv))
                id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
+       else if (IS_ICELAKE(dev_priv))
+               id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
 
        if (id)
                DRM_DEBUG_KMS("Assuming PCH ID %04x\n", id);
@@ -634,26 +636,6 @@ static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
        .can_switch = i915_switcheroo_can_switch,
 };
 
-static void i915_gem_fini(struct drm_i915_private *dev_priv)
-{
-       /* Flush any outstanding unpin_work. */
-       i915_gem_drain_workqueue(dev_priv);
-
-       mutex_lock(&dev_priv->drm.struct_mutex);
-       intel_uc_fini_hw(dev_priv);
-       intel_uc_fini(dev_priv);
-       i915_gem_cleanup_engines(dev_priv);
-       i915_gem_contexts_fini(dev_priv);
-       mutex_unlock(&dev_priv->drm.struct_mutex);
-
-       intel_uc_fini_misc(dev_priv);
-       i915_gem_cleanup_userptr(dev_priv);
-
-       i915_gem_drain_freed_objects(dev_priv);
-
-       WARN_ON(!list_empty(&dev_priv->contexts.list));
-}
-
 static int i915_load_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -1553,12 +1535,30 @@ static bool suspend_to_idle(struct drm_i915_private *dev_priv)
        return false;
 }
 
+static int i915_drm_prepare(struct drm_device *dev)
+{
+       struct drm_i915_private *i915 = to_i915(dev);
+       int err;
+
+       /*
+        * NB intel_display_suspend() may issue new requests after we've
+        * ostensibly marked the GPU as ready-to-sleep here. We need to
+        * split out that work and pull it forward so that after point,
+        * the GPU is not woken again.
+        */
+       err = i915_gem_suspend(i915);
+       if (err)
+               dev_err(&i915->drm.pdev->dev,
+                       "GEM idle failed, suspend/resume might fail\n");
+
+       return err;
+}
+
 static int i915_drm_suspend(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct pci_dev *pdev = dev_priv->drm.pdev;
        pci_power_t opregion_target_state;
-       int error;
 
        /* ignore lid events during suspend */
        mutex_lock(&dev_priv->modeset_restore_lock);
@@ -1575,13 +1575,6 @@ static int i915_drm_suspend(struct drm_device *dev)
 
        pci_save_state(pdev);
 
-       error = i915_gem_suspend(dev_priv);
-       if (error) {
-               dev_err(&pdev->dev,
-                       "GEM idle failed, resume might fail\n");
-               goto out;
-       }
-
        intel_display_suspend(dev);
 
        intel_dp_mst_suspend(dev);
@@ -1600,7 +1593,6 @@ static int i915_drm_suspend(struct drm_device *dev)
        opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
        intel_opregion_notify_adapter(dev_priv, opregion_target_state);
 
-       intel_uncore_suspend(dev_priv);
        intel_opregion_unregister(dev_priv);
 
        intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
@@ -1609,10 +1601,9 @@ static int i915_drm_suspend(struct drm_device *dev)
 
        intel_csr_ucode_suspend(dev_priv);
 
-out:
        enable_rpm_wakeref_asserts(dev_priv);
 
-       return error;
+       return 0;
 }
 
 static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
@@ -1623,7 +1614,10 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)
 
        disable_rpm_wakeref_asserts(dev_priv);
 
+       i915_gem_suspend_late(dev_priv);
+
        intel_display_set_init_power(dev_priv, false);
+       intel_uncore_suspend(dev_priv);
 
        /*
         * In case of firmware assisted context save/restore don't manually
@@ -2081,6 +2075,22 @@ out:
        return ret;
 }
 
+static int i915_pm_prepare(struct device *kdev)
+{
+       struct pci_dev *pdev = to_pci_dev(kdev);
+       struct drm_device *dev = pci_get_drvdata(pdev);
+
+       if (!dev) {
+               dev_err(kdev, "DRM not initialized, aborting suspend.\n");
+               return -ENODEV;
+       }
+
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
+       return i915_drm_prepare(dev);
+}
+
 static int i915_pm_suspend(struct device *kdev)
 {
        struct pci_dev *pdev = to_pci_dev(kdev);
@@ -2731,6 +2741,7 @@ const struct dev_pm_ops i915_pm_ops = {
         * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND,
         * PMSG_RESUME]
         */
+       .prepare = i915_pm_prepare,
        .suspend = i915_pm_suspend,
        .suspend_late = i915_pm_suspend_late,
        .resume_early = i915_pm_resume_early,
index 34c125e2d90c094c98759e127d2f93780cd65788..79209ee25c2174257af7876511b869fecc5d50fa 100644 (file)
@@ -85,8 +85,8 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20180514"
-#define DRIVER_TIMESTAMP       1526300884
+#define DRIVER_DATE            "20180606"
+#define DRIVER_TIMESTAMP       1528323047
 
 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
  * WARN_ON()) for hw state sanity checks to check for unexpected conditions
@@ -607,7 +607,6 @@ struct i915_psr {
        bool link_standby;
        bool colorimetry_support;
        bool alpm;
-       bool has_hw_tracking;
        bool psr2_enabled;
        u8 sink_sync_latency;
        bool debug;
@@ -1049,9 +1048,9 @@ struct intel_vbt_data {
        /* Feature bits */
        unsigned int int_tv_support:1;
        unsigned int lvds_dither:1;
-       unsigned int lvds_vbt:1;
        unsigned int int_crt_support:1;
        unsigned int lvds_use_ssc:1;
+       unsigned int int_lvds_support:1;
        unsigned int display_clock_mode:1;
        unsigned int fdi_rx_polarity_inverted:1;
        unsigned int panel_type:4;
@@ -1067,7 +1066,6 @@ struct intel_vbt_data {
                int vswing;
                bool low_vswing;
                bool initialized;
-               bool support;
                int bpp;
                struct edp_power_seq pps;
        } edp;
@@ -1078,8 +1076,8 @@ struct intel_vbt_data {
                bool require_aux_wakeup;
                int idle_frames;
                enum psr_lines_to_wait lines_to_wait;
-               int tp1_wakeup_time;
-               int tp2_tp3_wakeup_time;
+               int tp1_wakeup_time_us;
+               int tp2_tp3_wakeup_time_us;
        } psr;
 
        struct {
@@ -1843,6 +1841,7 @@ struct drm_i915_private {
                 */
                struct ida hw_ida;
 #define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
+#define MAX_GUC_CONTEXT_HW_ID (1 << 20) /* exclusive */
 #define GEN11_MAX_CONTEXT_HW_ID (1<<11) /* exclusive */
        } contexts;
 
@@ -1950,7 +1949,9 @@ struct drm_i915_private {
                         */
                        struct i915_perf_stream *exclusive_stream;
 
+                       struct intel_context *pinned_ctx;
                        u32 specific_ctx_id;
+                       u32 specific_ctx_id_mask;
 
                        struct hrtimer poll_check_timer;
                        wait_queue_head_t poll_wq;
@@ -2743,6 +2744,8 @@ int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
 int intel_engines_init_mmio(struct drm_i915_private *dev_priv);
 int intel_engines_init(struct drm_i915_private *dev_priv);
 
+u32 intel_calculate_mcr_s_ss_select(struct drm_i915_private *dev_priv);
+
 /* intel_hotplug.c */
 void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
                           u32 pin_mask, u32 long_mask);
@@ -3164,10 +3167,12 @@ void i915_gem_init_mmio(struct drm_i915_private *i915);
 int __must_check i915_gem_init(struct drm_i915_private *dev_priv);
 int __must_check i915_gem_init_hw(struct drm_i915_private *dev_priv);
 void i915_gem_init_swizzling(struct drm_i915_private *dev_priv);
+void i915_gem_fini(struct drm_i915_private *dev_priv);
 void i915_gem_cleanup_engines(struct drm_i915_private *dev_priv);
 int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv,
                           unsigned int flags);
 int __must_check i915_gem_suspend(struct drm_i915_private *dev_priv);
+void i915_gem_suspend_late(struct drm_i915_private *dev_priv);
 void i915_gem_resume(struct drm_i915_private *dev_priv);
 int i915_gem_fault(struct vm_fault *vmf);
 int i915_gem_object_wait(struct drm_i915_gem_object *obj,
@@ -3208,7 +3213,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
 static inline struct i915_hw_ppgtt *
 i915_vm_to_ppgtt(struct i915_address_space *vm)
 {
-       return container_of(vm, struct i915_hw_ppgtt, base);
+       return container_of(vm, struct i915_hw_ppgtt, vm);
 }
 
 /* i915_gem_fence_reg.c */
index 3704f4c0c2c970c31b0c6031050b20126e7ae2a9..86f1f9aaa119886b8a0fcec72763f4cb8df11c56 100644 (file)
@@ -65,7 +65,7 @@ insert_mappable_node(struct i915_ggtt *ggtt,
                      struct drm_mm_node *node, u32 size)
 {
        memset(node, 0, sizeof(*node));
-       return drm_mm_insert_node_in_range(&ggtt->base.mm, node,
+       return drm_mm_insert_node_in_range(&ggtt->vm.mm, node,
                                           size, 0, I915_COLOR_UNEVICTABLE,
                                           0, ggtt->mappable_end,
                                           DRM_MM_INSERT_LOW);
@@ -139,6 +139,8 @@ int i915_mutex_lock_interruptible(struct drm_device *dev)
 
 static u32 __i915_gem_park(struct drm_i915_private *i915)
 {
+       GEM_TRACE("\n");
+
        lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(i915->gt.active_requests);
        GEM_BUG_ON(!list_empty(&i915->gt.active_rings));
@@ -181,6 +183,8 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 
 void i915_gem_park(struct drm_i915_private *i915)
 {
+       GEM_TRACE("\n");
+
        lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(i915->gt.active_requests);
 
@@ -193,6 +197,8 @@ void i915_gem_park(struct drm_i915_private *i915)
 
 void i915_gem_unpark(struct drm_i915_private *i915)
 {
+       GEM_TRACE("\n");
+
        lockdep_assert_held(&i915->drm.struct_mutex);
        GEM_BUG_ON(!i915->gt.active_requests);
 
@@ -243,17 +249,17 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
        struct i915_vma *vma;
        u64 pinned;
 
-       pinned = ggtt->base.reserved;
+       pinned = ggtt->vm.reserved;
        mutex_lock(&dev->struct_mutex);
-       list_for_each_entry(vma, &ggtt->base.active_list, vm_link)
+       list_for_each_entry(vma, &ggtt->vm.active_list, vm_link)
                if (i915_vma_is_pinned(vma))
                        pinned += vma->node.size;
-       list_for_each_entry(vma, &ggtt->base.inactive_list, vm_link)
+       list_for_each_entry(vma, &ggtt->vm.inactive_list, vm_link)
                if (i915_vma_is_pinned(vma))
                        pinned += vma->node.size;
        mutex_unlock(&dev->struct_mutex);
 
-       args->aper_size = ggtt->base.total;
+       args->aper_size = ggtt->vm.total;
        args->aper_available_size = args->aper_size - pinned;
 
        return 0;
@@ -1217,9 +1223,9 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
                page_length = remain < page_length ? remain : page_length;
                if (node.allocated) {
                        wmb();
-                       ggtt->base.insert_page(&ggtt->base,
-                                              i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
-                                              node.start, I915_CACHE_NONE, 0);
+                       ggtt->vm.insert_page(&ggtt->vm,
+                                            i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
+                                            node.start, I915_CACHE_NONE, 0);
                        wmb();
                } else {
                        page_base += offset & PAGE_MASK;
@@ -1240,8 +1246,7 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
 out_unpin:
        if (node.allocated) {
                wmb();
-               ggtt->base.clear_range(&ggtt->base,
-                                      node.start, node.size);
+               ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
                remove_mappable_node(&node);
        } else {
                i915_vma_unpin(vma);
@@ -1420,9 +1425,9 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj,
                page_length = remain < page_length ? remain : page_length;
                if (node.allocated) {
                        wmb(); /* flush the write before we modify the GGTT */
-                       ggtt->base.insert_page(&ggtt->base,
-                                              i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
-                                              node.start, I915_CACHE_NONE, 0);
+                       ggtt->vm.insert_page(&ggtt->vm,
+                                            i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
+                                            node.start, I915_CACHE_NONE, 0);
                        wmb(); /* flush modifications to the GGTT (insert_page) */
                } else {
                        page_base += offset & PAGE_MASK;
@@ -1449,8 +1454,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj,
 out_unpin:
        if (node.allocated) {
                wmb();
-               ggtt->base.clear_range(&ggtt->base,
-                                      node.start, node.size);
+               ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
                remove_mappable_node(&node);
        } else {
                i915_vma_unpin(vma);
@@ -1993,7 +1997,7 @@ compute_partial_view(struct drm_i915_gem_object *obj,
  */
 int i915_gem_fault(struct vm_fault *vmf)
 {
-#define MIN_CHUNK_PAGES ((1 << 20) >> PAGE_SHIFT) /* 1 MiB */
+#define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
        struct vm_area_struct *area = vmf->vma;
        struct drm_i915_gem_object *obj = to_intel_bo(area->vm_private_data);
        struct drm_device *dev = obj->base.dev;
@@ -3003,7 +3007,7 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 struct i915_request *
 i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
 {
-       struct i915_request *request = NULL;
+       struct i915_request *request;
 
        /*
         * During the reset sequence, we must prevent the engine from
@@ -3014,52 +3018,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
         */
        intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL);
 
-       /*
-        * Prevent the signaler thread from updating the request
-        * state (by calling dma_fence_signal) as we are processing
-        * the reset. The write from the GPU of the seqno is
-        * asynchronous and the signaler thread may see a different
-        * value to us and declare the request complete, even though
-        * the reset routine have picked that request as the active
-        * (incomplete) request. This conflict is not handled
-        * gracefully!
-        */
-       kthread_park(engine->breadcrumbs.signaler);
-
-       /*
-        * Prevent request submission to the hardware until we have
-        * completed the reset in i915_gem_reset_finish(). If a request
-        * is completed by one engine, it may then queue a request
-        * to a second via its execlists->tasklet *just* as we are
-        * calling engine->init_hw() and also writing the ELSP.
-        * Turning off the execlists->tasklet until the reset is over
-        * prevents the race.
-        *
-        * Note that this needs to be a single atomic operation on the
-        * tasklet (flush existing tasks, prevent new tasks) to prevent
-        * a race between reset and set-wedged. It is not, so we do the best
-        * we can atm and make sure we don't lock the machine up in the more
-        * common case of recursively being called from set-wedged from inside
-        * i915_reset.
-        */
-       if (!atomic_read(&engine->execlists.tasklet.count))
-               tasklet_kill(&engine->execlists.tasklet);
-       tasklet_disable(&engine->execlists.tasklet);
-
-       /*
-        * We're using worker to queue preemption requests from the tasklet in
-        * GuC submission mode.
-        * Even though tasklet was disabled, we may still have a worker queued.
-        * Let's make sure that all workers scheduled before disabling the
-        * tasklet are completed before continuing with the reset.
-        */
-       if (engine->i915->guc.preempt_wq)
-               flush_workqueue(engine->i915->guc.preempt_wq);
-
-       if (engine->irq_seqno_barrier)
-               engine->irq_seqno_barrier(engine);
-
-       request = i915_gem_find_active_request(engine);
+       request = engine->reset.prepare(engine);
        if (request && request->fence.error == -EIO)
                request = ERR_PTR(-EIO); /* Previous reset failed! */
 
@@ -3111,7 +3070,7 @@ static void skip_request(struct i915_request *request)
 static void engine_skip_context(struct i915_request *request)
 {
        struct intel_engine_cs *engine = request->engine;
-       struct i915_gem_context *hung_ctx = request->ctx;
+       struct i915_gem_context *hung_ctx = request->gem_context;
        struct i915_timeline *timeline = request->timeline;
        unsigned long flags;
 
@@ -3121,7 +3080,7 @@ static void engine_skip_context(struct i915_request *request)
        spin_lock_nested(&timeline->lock, SINGLE_DEPTH_NESTING);
 
        list_for_each_entry_continue(request, &engine->timeline.requests, link)
-               if (request->ctx == hung_ctx)
+               if (request->gem_context == hung_ctx)
                        skip_request(request);
 
        list_for_each_entry(request, &timeline->requests, link)
@@ -3167,11 +3126,11 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
        }
 
        if (stalled) {
-               i915_gem_context_mark_guilty(request->ctx);
+               i915_gem_context_mark_guilty(request->gem_context);
                skip_request(request);
 
                /* If this context is now banned, skip all pending requests. */
-               if (i915_gem_context_is_banned(request->ctx))
+               if (i915_gem_context_is_banned(request->gem_context))
                        engine_skip_context(request);
        } else {
                /*
@@ -3181,7 +3140,7 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
                 */
                request = i915_gem_find_active_request(engine);
                if (request) {
-                       i915_gem_context_mark_innocent(request->ctx);
+                       i915_gem_context_mark_innocent(request->gem_context);
                        dma_fence_set_error(&request->fence, -EAGAIN);
 
                        /* Rewind the engine to replay the incomplete rq */
@@ -3210,13 +3169,8 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine,
        if (request)
                request = i915_gem_reset_request(engine, request, stalled);
 
-       if (request) {
-               DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
-                                engine->name, request->global_seqno);
-       }
-
        /* Setup the CS to resume from the breadcrumb of the hung request */
-       engine->reset_hw(engine, request);
+       engine->reset.reset(engine, request);
 }
 
 void i915_gem_reset(struct drm_i915_private *dev_priv,
@@ -3230,14 +3184,14 @@ void i915_gem_reset(struct drm_i915_private *dev_priv,
        i915_retire_requests(dev_priv);
 
        for_each_engine(engine, dev_priv, id) {
-               struct i915_gem_context *ctx;
+               struct intel_context *ce;
 
                i915_gem_reset_engine(engine,
                                      engine->hangcheck.active_request,
                                      stalled_mask & ENGINE_MASK(id));
-               ctx = fetch_and_zero(&engine->last_retired_context);
-               if (ctx)
-                       intel_context_unpin(ctx, engine);
+               ce = fetch_and_zero(&engine->last_retired_context);
+               if (ce)
+                       intel_context_unpin(ce);
 
                /*
                 * Ostensibily, we always want a context loaded for powersaving,
@@ -3264,8 +3218,7 @@ void i915_gem_reset(struct drm_i915_private *dev_priv,
 
 void i915_gem_reset_finish_engine(struct intel_engine_cs *engine)
 {
-       tasklet_enable(&engine->execlists.tasklet);
-       kthread_unpark(engine->breadcrumbs.signaler);
+       engine->reset.finish(engine);
 
        intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL);
 }
@@ -3543,6 +3496,22 @@ new_requests_since_last_retire(const struct drm_i915_private *i915)
                work_pending(&i915->gt.idle_work.work));
 }
 
+static void assert_kernel_context_is_current(struct drm_i915_private *i915)
+{
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
+
+       if (i915_terminally_wedged(&i915->gpu_error))
+               return;
+
+       GEM_BUG_ON(i915->gt.active_requests);
+       for_each_engine(engine, i915, id) {
+               GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
+               GEM_BUG_ON(engine->last_retired_context !=
+                          to_intel_context(i915->kernel_context, engine));
+       }
+}
+
 static void
 i915_gem_idle_work_handler(struct work_struct *work)
 {
@@ -3554,6 +3523,24 @@ i915_gem_idle_work_handler(struct work_struct *work)
        if (!READ_ONCE(dev_priv->gt.awake))
                return;
 
+       if (READ_ONCE(dev_priv->gt.active_requests))
+               return;
+
+       /*
+        * Flush out the last user context, leaving only the pinned
+        * kernel context resident. When we are idling on the kernel_context,
+        * no more new requests (with a context switch) are emitted and we
+        * can finally rest. A consequence is that the idle work handler is
+        * always called at least twice before idling (and if the system is
+        * idle that implies a round trip through the retire worker).
+        */
+       mutex_lock(&dev_priv->drm.struct_mutex);
+       i915_gem_switch_to_kernel_context(dev_priv);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
+
+       GEM_TRACE("active_requests=%d (after switch-to-kernel-context)\n",
+                 READ_ONCE(dev_priv->gt.active_requests));
+
        /*
         * Wait for last execlists context complete, but bail out in case a
         * new request is submitted. As we don't trust the hardware, we
@@ -3587,6 +3574,8 @@ i915_gem_idle_work_handler(struct work_struct *work)
 
        epoch = __i915_gem_park(dev_priv);
 
+       assert_kernel_context_is_current(dev_priv);
+
        rearm_hangcheck = false;
 out_unlock:
        mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -3735,7 +3724,29 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 
 static int wait_for_timeline(struct i915_timeline *tl, unsigned int flags)
 {
-       return i915_gem_active_wait(&tl->last_request, flags);
+       struct i915_request *rq;
+       long ret;
+
+       rq = i915_gem_active_get_unlocked(&tl->last_request);
+       if (!rq)
+               return 0;
+
+       /*
+        * "Race-to-idle".
+        *
+        * Switching to the kernel context is often used a synchronous
+        * step prior to idling, e.g. in suspend for flushing all
+        * current operations to memory before sleeping. These we
+        * want to complete as quickly as possible to avoid prolonged
+        * stalls, so allow the gpu to boost to maximum clocks.
+        */
+       if (flags & I915_WAIT_FOR_IDLE_BOOST)
+               gen6_rps_boost(rq, NULL);
+
+       ret = i915_request_wait(rq, flags, MAX_SCHEDULE_TIMEOUT);
+       i915_request_put(rq);
+
+       return ret < 0 ? ret : 0;
 }
 
 static int wait_for_engines(struct drm_i915_private *i915)
@@ -3753,6 +3764,9 @@ static int wait_for_engines(struct drm_i915_private *i915)
 
 int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
 {
+       GEM_TRACE("flags=%x (%s)\n",
+                 flags, flags & I915_WAIT_LOCKED ? "locked" : "unlocked");
+
        /* If the device is asleep, we have no requests outstanding */
        if (!READ_ONCE(i915->gt.awake))
                return 0;
@@ -3769,6 +3783,7 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
                                return err;
                }
                i915_retire_requests(i915);
+               GEM_BUG_ON(i915->gt.active_requests);
 
                return wait_for_engines(i915);
        } else {
@@ -4357,7 +4372,7 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
                         u64 flags)
 {
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
-       struct i915_address_space *vm = &dev_priv->ggtt.base;
+       struct i915_address_space *vm = &dev_priv->ggtt.vm;
        struct i915_vma *vma;
        int ret;
 
@@ -4945,25 +4960,26 @@ void __i915_gem_object_release_unless_active(struct drm_i915_gem_object *obj)
                i915_gem_object_put(obj);
 }
 
-static void assert_kernel_context_is_current(struct drm_i915_private *i915)
+void i915_gem_sanitize(struct drm_i915_private *i915)
 {
-       struct i915_gem_context *kernel_context = i915->kernel_context;
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
 
-       for_each_engine(engine, i915, id) {
-               GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
-               GEM_BUG_ON(engine->last_retired_context != kernel_context);
-       }
-}
+       GEM_TRACE("\n");
 
-void i915_gem_sanitize(struct drm_i915_private *i915)
-{
-       if (i915_terminally_wedged(&i915->gpu_error)) {
-               mutex_lock(&i915->drm.struct_mutex);
+       mutex_lock(&i915->drm.struct_mutex);
+
+       intel_runtime_pm_get(i915);
+       intel_uncore_forcewake_get(i915, FORCEWAKE_ALL);
+
+       /*
+        * As we have just resumed the machine and woken the device up from
+        * deep PCI sleep (presumably D3_cold), assume the HW has been reset
+        * back to defaults, recovering from whatever wedged state we left it
+        * in and so worth trying to use the device once more.
+        */
+       if (i915_terminally_wedged(&i915->gpu_error))
                i915_gem_unset_wedged(i915);
-               mutex_unlock(&i915->drm.struct_mutex);
-       }
 
        /*
         * If we inherit context state from the BIOS or earlier occupants
@@ -4975,6 +4991,18 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
         */
        if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
                WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
+
+       /* Reset the submission backend after resume as well as the GPU reset */
+       for_each_engine(engine, i915, id) {
+               if (engine->reset.reset)
+                       engine->reset.reset(engine, NULL);
+       }
+
+       intel_uncore_forcewake_put(i915, FORCEWAKE_ALL);
+       intel_runtime_pm_put(i915);
+
+       i915_gem_contexts_lost(i915);
+       mutex_unlock(&i915->drm.struct_mutex);
 }
 
 int i915_gem_suspend(struct drm_i915_private *dev_priv)
@@ -4982,6 +5010,8 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
        struct drm_device *dev = &dev_priv->drm;
        int ret;
 
+       GEM_TRACE("\n");
+
        intel_runtime_pm_get(dev_priv);
        intel_suspend_gt_powersave(dev_priv);
 
@@ -5002,13 +5032,13 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
 
                ret = i915_gem_wait_for_idle(dev_priv,
                                             I915_WAIT_INTERRUPTIBLE |
-                                            I915_WAIT_LOCKED);
+                                            I915_WAIT_LOCKED |
+                                            I915_WAIT_FOR_IDLE_BOOST);
                if (ret && ret != -EIO)
                        goto err_unlock;
 
                assert_kernel_context_is_current(dev_priv);
        }
-       i915_gem_contexts_lost(dev_priv);
        mutex_unlock(&dev->struct_mutex);
 
        intel_uc_suspend(dev_priv);
@@ -5028,6 +5058,24 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
        if (WARN_ON(!intel_engines_are_idle(dev_priv)))
                i915_gem_set_wedged(dev_priv); /* no hope, discard everything */
 
+       intel_runtime_pm_put(dev_priv);
+       return 0;
+
+err_unlock:
+       mutex_unlock(&dev->struct_mutex);
+       intel_runtime_pm_put(dev_priv);
+       return ret;
+}
+
+void i915_gem_suspend_late(struct drm_i915_private *i915)
+{
+       struct drm_i915_gem_object *obj;
+       struct list_head *phases[] = {
+               &i915->mm.unbound_list,
+               &i915->mm.bound_list,
+               NULL
+       }, **phase;
+
        /*
         * Neither the BIOS, ourselves or any other kernel
         * expects the system to be in execlists mode on startup,
@@ -5047,20 +5095,22 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
         * machines is a good idea, we don't - just in case it leaves the
         * machine in an unusable condition.
         */
-       intel_uc_sanitize(dev_priv);
-       i915_gem_sanitize(dev_priv);
 
-       intel_runtime_pm_put(dev_priv);
-       return 0;
+       mutex_lock(&i915->drm.struct_mutex);
+       for (phase = phases; *phase; phase++) {
+               list_for_each_entry(obj, *phase, mm.link)
+                       WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
+       }
+       mutex_unlock(&i915->drm.struct_mutex);
 
-err_unlock:
-       mutex_unlock(&dev->struct_mutex);
-       intel_runtime_pm_put(dev_priv);
-       return ret;
+       intel_uc_sanitize(i915);
+       i915_gem_sanitize(i915);
 }
 
 void i915_gem_resume(struct drm_i915_private *i915)
 {
+       GEM_TRACE("\n");
+
        WARN_ON(i915->gt.awake);
 
        mutex_lock(&i915->drm.struct_mutex);
@@ -5234,9 +5284,15 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
 
        /* Only when the HW is re-initialised, can we replay the requests */
        ret = __i915_gem_restart_engines(dev_priv);
+       if (ret)
+               goto cleanup_uc;
 out:
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
        return ret;
+
+cleanup_uc:
+       intel_uc_fini_hw(dev_priv);
+       goto out;
 }
 
 static int __intel_engines_record_defaults(struct drm_i915_private *i915)
@@ -5357,12 +5413,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 {
        int ret;
 
-       /*
-        * We need to fallback to 4K pages since gvt gtt handling doesn't
-        * support huge page entries - we will need to check either hypervisor
-        * mm can support huge guest page or just do emulation in gvt.
-        */
-       if (intel_vgpu_active(dev_priv))
+       /* We need to fallback to 4K pages if host doesn't support huge gtt. */
+       if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))
                mkwrite_device_info(dev_priv)->page_sizes =
                        I915_GTT_PAGE_SIZE_4K;
 
@@ -5502,6 +5554,28 @@ err_unlock:
        return ret;
 }
 
+void i915_gem_fini(struct drm_i915_private *dev_priv)
+{
+       i915_gem_suspend_late(dev_priv);
+
+       /* Flush any outstanding unpin_work. */
+       i915_gem_drain_workqueue(dev_priv);
+
+       mutex_lock(&dev_priv->drm.struct_mutex);
+       intel_uc_fini_hw(dev_priv);
+       intel_uc_fini(dev_priv);
+       i915_gem_cleanup_engines(dev_priv);
+       i915_gem_contexts_fini(dev_priv);
+       mutex_unlock(&dev_priv->drm.struct_mutex);
+
+       intel_uc_fini_misc(dev_priv);
+       i915_gem_cleanup_userptr(dev_priv);
+
+       i915_gem_drain_freed_objects(dev_priv);
+
+       WARN_ON(!list_empty(&dev_priv->contexts.list));
+}
+
 void i915_gem_init_mmio(struct drm_i915_private *i915)
 {
        i915_gem_sanitize(i915);
@@ -5666,16 +5740,17 @@ int i915_gem_freeze(struct drm_i915_private *dev_priv)
        return 0;
 }
 
-int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
+int i915_gem_freeze_late(struct drm_i915_private *i915)
 {
        struct drm_i915_gem_object *obj;
        struct list_head *phases[] = {
-               &dev_priv->mm.unbound_list,
-               &dev_priv->mm.bound_list,
+               &i915->mm.unbound_list,
+               &i915->mm.bound_list,
                NULL
-       }, **p;
+       }, **phase;
 
-       /* Called just before we write the hibernation image.
+       /*
+        * Called just before we write the hibernation image.
         *
         * We need to update the domain tracking to reflect that the CPU
         * will be accessing all the pages to create and restore from the
@@ -5689,15 +5764,15 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
         * the objects as well, see i915_gem_freeze()
         */
 
-       i915_gem_shrink(dev_priv, -1UL, NULL, I915_SHRINK_UNBOUND);
-       i915_gem_drain_freed_objects(dev_priv);
+       i915_gem_shrink(i915, -1UL, NULL, I915_SHRINK_UNBOUND);
+       i915_gem_drain_freed_objects(i915);
 
-       spin_lock(&dev_priv->mm.obj_lock);
-       for (p = phases; *p; p++) {
-               list_for_each_entry(obj, *p, mm.link)
-                       __start_cpu_write(obj);
+       mutex_lock(&i915->drm.struct_mutex);
+       for (phase = phases; *phase; phase++) {
+               list_for_each_entry(obj, *phase, mm.link)
+                       WARN_ON(i915_gem_object_set_to_cpu_domain(obj, true));
        }
-       spin_unlock(&dev_priv->mm.obj_lock);
+       mutex_unlock(&i915->drm.struct_mutex);
 
        return 0;
 }
index 525920404ede44b18da84d7947ecee8345bf7f6b..261da577829a61b1c84ae8ab2d91bc6d307a6e0d 100644 (file)
@@ -26,6 +26,7 @@
 #define __I915_GEM_H__
 
 #include <linux/bug.h>
+#include <linux/interrupt.h>
 
 struct drm_i915_private;
 
@@ -62,9 +63,12 @@ struct drm_i915_private;
 #if IS_ENABLED(CONFIG_DRM_I915_TRACE_GEM)
 #define GEM_TRACE(...) trace_printk(__VA_ARGS__)
 #define GEM_TRACE_DUMP() ftrace_dump(DUMP_ALL)
+#define GEM_TRACE_DUMP_ON(expr) \
+       do { if (expr) ftrace_dump(DUMP_ALL); } while (0)
 #else
 #define GEM_TRACE(...) do { } while (0)
 #define GEM_TRACE_DUMP() do { } while (0)
+#define GEM_TRACE_DUMP_ON(expr) BUILD_BUG_ON_INVALID(expr)
 #endif
 
 #define I915_NUM_ENGINES 8
@@ -72,4 +76,16 @@ struct drm_i915_private;
 void i915_gem_park(struct drm_i915_private *i915);
 void i915_gem_unpark(struct drm_i915_private *i915);
 
+static inline void __tasklet_disable_sync_once(struct tasklet_struct *t)
+{
+       if (atomic_inc_return(&t->count) == 1)
+               tasklet_unlock_wait(t);
+}
+
+static inline void __tasklet_enable_sync_once(struct tasklet_struct *t)
+{
+       if (atomic_dec_return(&t->count) == 0)
+               tasklet_kill(t);
+}
+
 #endif /* __I915_GEM_H__ */
index 33f8a4b3c98170f2857e15255e4fc23ae8bbb49e..b2c7ac1b074d42f54fbfae9bc64c06787b5b0226 100644 (file)
@@ -127,14 +127,8 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
        for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) {
                struct intel_context *ce = &ctx->__engine[n];
 
-               if (!ce->state)
-                       continue;
-
-               WARN_ON(ce->pin_count);
-               if (ce->ring)
-                       intel_ring_free(ce->ring);
-
-               __i915_gem_object_release_unless_active(ce->state->obj);
+               if (ce->ops)
+                       ce->ops->destroy(ce);
        }
 
        kfree(ctx->name);
@@ -203,7 +197,7 @@ static void context_close(struct i915_gem_context *ctx)
         */
        lut_close(ctx);
        if (ctx->ppgtt)
-               i915_ppgtt_close(&ctx->ppgtt->base);
+               i915_ppgtt_close(&ctx->ppgtt->vm);
 
        ctx->file_priv = ERR_PTR(-EBADF);
        i915_gem_context_put(ctx);
@@ -214,10 +208,19 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
        int ret;
        unsigned int max;
 
-       if (INTEL_GEN(dev_priv) >= 11)
+       if (INTEL_GEN(dev_priv) >= 11) {
                max = GEN11_MAX_CONTEXT_HW_ID;
-       else
-               max = MAX_CONTEXT_HW_ID;
+       } else {
+               /*
+                * When using GuC in proxy submission, GuC consumes the
+                * highest bit in the context id to indicate proxy submission.
+                */
+               if (USES_GUC_SUBMISSION(dev_priv))
+                       max = MAX_GUC_CONTEXT_HW_ID;
+               else
+                       max = MAX_CONTEXT_HW_ID;
+       }
+
 
        ret = ida_simple_get(&dev_priv->contexts.hw_ida,
                             0, max, GFP_KERNEL);
@@ -246,7 +249,7 @@ static u32 default_desc_template(const struct drm_i915_private *i915,
        desc = GEN8_CTX_VALID | GEN8_CTX_PRIVILEGE;
 
        address_mode = INTEL_LEGACY_32B_CONTEXT;
-       if (ppgtt && i915_vm_is_48bit(&ppgtt->base))
+       if (ppgtt && i915_vm_is_48bit(&ppgtt->vm))
                address_mode = INTEL_LEGACY_64B_CONTEXT;
        desc |= address_mode << GEN8_CTX_ADDRESSING_MODE_SHIFT;
 
@@ -266,6 +269,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
                    struct drm_i915_file_private *file_priv)
 {
        struct i915_gem_context *ctx;
+       unsigned int n;
        int ret;
 
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -283,6 +287,12 @@ __create_hw_context(struct drm_i915_private *dev_priv,
        ctx->i915 = dev_priv;
        ctx->sched.priority = I915_PRIORITY_NORMAL;
 
+       for (n = 0; n < ARRAY_SIZE(ctx->__engine); n++) {
+               struct intel_context *ce = &ctx->__engine[n];
+
+               ce->gem_context = ctx;
+       }
+
        INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
        INIT_LIST_HEAD(&ctx->handles_list);
 
@@ -514,16 +524,8 @@ void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
 
        lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
-       for_each_engine(engine, dev_priv, id) {
-               engine->legacy_active_context = NULL;
-               engine->legacy_active_ppgtt = NULL;
-
-               if (!engine->last_retired_context)
-                       continue;
-
-               intel_context_unpin(engine->last_retired_context, engine);
-               engine->last_retired_context = NULL;
-       }
+       for_each_engine(engine, dev_priv, id)
+               intel_engine_lost_context(engine);
 }
 
 void i915_gem_contexts_fini(struct drm_i915_private *i915)
@@ -583,58 +585,119 @@ last_request_on_engine(struct i915_timeline *timeline,
 {
        struct i915_request *rq;
 
-       if (timeline == &engine->timeline)
-               return NULL;
+       GEM_BUG_ON(timeline == &engine->timeline);
 
        rq = i915_gem_active_raw(&timeline->last_request,
                                 &engine->i915->drm.struct_mutex);
-       if (rq && rq->engine == engine)
+       if (rq && rq->engine == engine) {
+               GEM_TRACE("last request for %s on engine %s: %llx:%d\n",
+                         timeline->name, engine->name,
+                         rq->fence.context, rq->fence.seqno);
+               GEM_BUG_ON(rq->timeline != timeline);
                return rq;
+       }
 
        return NULL;
 }
 
-static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
+static bool engine_has_kernel_context_barrier(struct intel_engine_cs *engine)
 {
-       struct i915_timeline *timeline;
+       struct drm_i915_private *i915 = engine->i915;
+       const struct intel_context * const ce =
+               to_intel_context(i915->kernel_context, engine);
+       struct i915_timeline *barrier = ce->ring->timeline;
+       struct intel_ring *ring;
+       bool any_active = false;
 
-       list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
-               if (last_request_on_engine(timeline, engine))
+       lockdep_assert_held(&i915->drm.struct_mutex);
+       list_for_each_entry(ring, &i915->gt.active_rings, active_link) {
+               struct i915_request *rq;
+
+               rq = last_request_on_engine(ring->timeline, engine);
+               if (!rq)
+                       continue;
+
+               any_active = true;
+
+               if (rq->hw_context == ce)
+                       continue;
+
+               /*
+                * Was this request submitted after the previous
+                * switch-to-kernel-context?
+                */
+               if (!i915_timeline_sync_is_later(barrier, &rq->fence)) {
+                       GEM_TRACE("%s needs barrier for %llx:%d\n",
+                                 ring->timeline->name,
+                                 rq->fence.context,
+                                 rq->fence.seqno);
                        return false;
+               }
+
+               GEM_TRACE("%s has barrier after %llx:%d\n",
+                         ring->timeline->name,
+                         rq->fence.context,
+                         rq->fence.seqno);
        }
 
-       return intel_engine_has_kernel_context(engine);
+       /*
+        * If any other timeline was still active and behind the last barrier,
+        * then our last switch-to-kernel-context must still be queued and
+        * will run last (leaving the engine in the kernel context when it
+        * eventually idles).
+        */
+       if (any_active)
+               return true;
+
+       /* The engine is idle; check that it is idling in the kernel context. */
+       return engine->last_retired_context == ce;
 }
 
-int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
+int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915)
 {
        struct intel_engine_cs *engine;
-       struct i915_timeline *timeline;
        enum intel_engine_id id;
 
-       lockdep_assert_held(&dev_priv->drm.struct_mutex);
+       GEM_TRACE("awake?=%s\n", yesno(i915->gt.awake));
+
+       lockdep_assert_held(&i915->drm.struct_mutex);
+       GEM_BUG_ON(!i915->kernel_context);
 
-       i915_retire_requests(dev_priv);
+       i915_retire_requests(i915);
 
-       for_each_engine(engine, dev_priv, id) {
+       for_each_engine(engine, i915, id) {
+               struct intel_ring *ring;
                struct i915_request *rq;
 
-               if (engine_has_idle_kernel_context(engine))
+               GEM_BUG_ON(!to_intel_context(i915->kernel_context, engine));
+               if (engine_has_kernel_context_barrier(engine))
                        continue;
 
-               rq = i915_request_alloc(engine, dev_priv->kernel_context);
+               GEM_TRACE("emit barrier on %s\n", engine->name);
+
+               rq = i915_request_alloc(engine, i915->kernel_context);
                if (IS_ERR(rq))
                        return PTR_ERR(rq);
 
                /* Queue this switch after all other activity */
-               list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
+               list_for_each_entry(ring, &i915->gt.active_rings, active_link) {
                        struct i915_request *prev;
 
-                       prev = last_request_on_engine(timeline, engine);
-                       if (prev)
-                               i915_sw_fence_await_sw_fence_gfp(&rq->submit,
-                                                                &prev->submit,
-                                                                I915_FENCE_GFP);
+                       prev = last_request_on_engine(ring->timeline, engine);
+                       if (!prev)
+                               continue;
+
+                       if (prev->gem_context == i915->kernel_context)
+                               continue;
+
+                       GEM_TRACE("add barrier on %s for %llx:%d\n",
+                                 engine->name,
+                                 prev->fence.context,
+                                 prev->fence.seqno);
+                       i915_sw_fence_await_sw_fence_gfp(&rq->submit,
+                                                        &prev->submit,
+                                                        I915_FENCE_GFP);
+                       i915_timeline_sync_set(rq->timeline, &prev->fence);
                }
 
                /*
@@ -747,11 +810,11 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
                break;
        case I915_CONTEXT_PARAM_GTT_SIZE:
                if (ctx->ppgtt)
-                       args->value = ctx->ppgtt->base.total;
+                       args->value = ctx->ppgtt->vm.total;
                else if (to_i915(dev)->mm.aliasing_ppgtt)
-                       args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total;
+                       args->value = to_i915(dev)->mm.aliasing_ppgtt->vm.total;
                else
-                       args->value = to_i915(dev)->ggtt.base.total;
+                       args->value = to_i915(dev)->ggtt.vm.total;
                break;
        case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
                args->value = i915_gem_context_no_error_capture(ctx);
index ace3b129c18966f9c76d88f11bc75b5b463e9f6c..b116e4942c10d13eb7e9771a4f50e737e47d185a 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/radix-tree.h>
 
 #include "i915_gem.h"
+#include "i915_scheduler.h"
 
 struct pid;
 
@@ -45,6 +46,13 @@ struct intel_ring;
 
 #define DEFAULT_CONTEXT_HANDLE 0
 
+struct intel_context;
+
+struct intel_context_ops {
+       void (*unpin)(struct intel_context *ce);
+       void (*destroy)(struct intel_context *ce);
+};
+
 /**
  * struct i915_gem_context - client state
  *
@@ -144,11 +152,14 @@ struct i915_gem_context {
 
        /** engine: per-engine logical HW state */
        struct intel_context {
+               struct i915_gem_context *gem_context;
                struct i915_vma *state;
                struct intel_ring *ring;
                u32 *lrc_reg_state;
                u64 lrc_desc;
                int pin_count;
+
+               const struct intel_context_ops *ops;
        } __engine[I915_NUM_ENGINES];
 
        /** ring_size: size for allocating the per-engine ring buffer */
@@ -263,25 +274,26 @@ to_intel_context(struct i915_gem_context *ctx,
        return &ctx->__engine[engine->id];
 }
 
-static inline struct intel_ring *
+static inline struct intel_context *
 intel_context_pin(struct i915_gem_context *ctx, struct intel_engine_cs *engine)
 {
        return engine->context_pin(engine, ctx);
 }
 
-static inline void __intel_context_pin(struct i915_gem_context *ctx,
-                                      const struct intel_engine_cs *engine)
+static inline void __intel_context_pin(struct intel_context *ce)
 {
-       struct intel_context *ce = to_intel_context(ctx, engine);
-
        GEM_BUG_ON(!ce->pin_count);
        ce->pin_count++;
 }
 
-static inline void intel_context_unpin(struct i915_gem_context *ctx,
-                                      struct intel_engine_cs *engine)
+static inline void intel_context_unpin(struct intel_context *ce)
 {
-       engine->context_unpin(engine, ctx);
+       GEM_BUG_ON(!ce->pin_count);
+       if (--ce->pin_count)
+               return;
+
+       GEM_BUG_ON(!ce->ops);
+       ce->ops->unpin(ce);
 }
 
 /* i915_gem_context.c */
index f627a8c47c58a36f6ff92f17a4d6d672b28bc00b..eefd449502e27399b83a088dd667b08fd9c38471 100644 (file)
@@ -703,7 +703,7 @@ static int eb_select_context(struct i915_execbuffer *eb)
                return -ENOENT;
 
        eb->ctx = ctx;
-       eb->vm = ctx->ppgtt ? &ctx->ppgtt->base : &eb->i915->ggtt.base;
+       eb->vm = ctx->ppgtt ? &ctx->ppgtt->vm : &eb->i915->ggtt.vm;
 
        eb->context_flags = 0;
        if (ctx->flags & CONTEXT_NO_ZEROMAP)
@@ -943,9 +943,9 @@ static void reloc_cache_reset(struct reloc_cache *cache)
                if (cache->node.allocated) {
                        struct i915_ggtt *ggtt = cache_to_ggtt(cache);
 
-                       ggtt->base.clear_range(&ggtt->base,
-                                              cache->node.start,
-                                              cache->node.size);
+                       ggtt->vm.clear_range(&ggtt->vm,
+                                            cache->node.start,
+                                            cache->node.size);
                        drm_mm_remove_node(&cache->node);
                } else {
                        i915_vma_unpin((struct i915_vma *)cache->node.mm);
@@ -1016,7 +1016,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
                if (IS_ERR(vma)) {
                        memset(&cache->node, 0, sizeof(cache->node));
                        err = drm_mm_insert_node_in_range
-                               (&ggtt->base.mm, &cache->node,
+                               (&ggtt->vm.mm, &cache->node,
                                 PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
                                 0, ggtt->mappable_end,
                                 DRM_MM_INSERT_LOW);
@@ -1037,9 +1037,9 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
        offset = cache->node.start;
        if (cache->node.allocated) {
                wmb();
-               ggtt->base.insert_page(&ggtt->base,
-                                      i915_gem_object_get_dma_address(obj, page),
-                                      offset, I915_CACHE_NONE, 0);
+               ggtt->vm.insert_page(&ggtt->vm,
+                                    i915_gem_object_get_dma_address(obj, page),
+                                    offset, I915_CACHE_NONE, 0);
        } else {
                offset += page << PAGE_SHIFT;
        }
index 996ab2ad6c45cade8d7e20a1d28e9bffddfac8ef..2b4a40a32b765ab9b44ec1e06c6a1bb272377bc1 100644 (file)
@@ -42,7 +42,7 @@
 #include "intel_drv.h"
 #include "intel_frontbuffer.h"
 
-#define I915_GFP_DMA (GFP_KERNEL | __GFP_HIGHMEM)
+#define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
 
 /**
  * DOC: Global GTT views
@@ -190,19 +190,11 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
        return 1;
 }
 
-static int ppgtt_bind_vma(struct i915_vma *vma,
-                         enum i915_cache_level cache_level,
-                         u32 unused)
+static int gen6_ppgtt_bind_vma(struct i915_vma *vma,
+                              enum i915_cache_level cache_level,
+                              u32 unused)
 {
        u32 pte_flags;
-       int ret;
-
-       if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
-               ret = vma->vm->allocate_va_range(vma->vm, vma->node.start,
-                                                vma->size);
-               if (ret)
-                       return ret;
-       }
 
        /* Currently applicable only to VLV */
        pte_flags = 0;
@@ -214,6 +206,22 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
        return 0;
 }
 
+static int gen8_ppgtt_bind_vma(struct i915_vma *vma,
+                              enum i915_cache_level cache_level,
+                              u32 unused)
+{
+       int ret;
+
+       if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
+               ret = vma->vm->allocate_va_range(vma->vm,
+                                                vma->node.start, vma->size);
+               if (ret)
+                       return ret;
+       }
+
+       return gen6_ppgtt_bind_vma(vma, cache_level, unused);
+}
+
 static void ppgtt_unbind_vma(struct i915_vma *vma)
 {
        vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
@@ -489,7 +497,7 @@ static int __setup_page_dma(struct i915_address_space *vm,
                            struct i915_page_dma *p,
                            gfp_t gfp)
 {
-       p->page = vm_alloc_page(vm, gfp | __GFP_NOWARN | __GFP_NORETRY);
+       p->page = vm_alloc_page(vm, gfp | I915_GFP_ALLOW_FAIL);
        if (unlikely(!p->page))
                return -ENOMEM;
 
@@ -506,7 +514,7 @@ static int __setup_page_dma(struct i915_address_space *vm,
 static int setup_page_dma(struct i915_address_space *vm,
                          struct i915_page_dma *p)
 {
-       return __setup_page_dma(vm, p, I915_GFP_DMA);
+       return __setup_page_dma(vm, p, __GFP_HIGHMEM);
 }
 
 static void cleanup_page_dma(struct i915_address_space *vm,
@@ -520,8 +528,8 @@ static void cleanup_page_dma(struct i915_address_space *vm,
 
 #define setup_px(vm, px) setup_page_dma((vm), px_base(px))
 #define cleanup_px(vm, px) cleanup_page_dma((vm), px_base(px))
-#define fill_px(ppgtt, px, v) fill_page_dma((vm), px_base(px), (v))
-#define fill32_px(ppgtt, px, v) fill_page_dma_32((vm), px_base(px), (v))
+#define fill_px(vm, px, v) fill_page_dma((vm), px_base(px), (v))
+#define fill32_px(vm, px, v) fill_page_dma_32((vm), px_base(px), (v))
 
 static void fill_page_dma(struct i915_address_space *vm,
                          struct i915_page_dma *p,
@@ -614,7 +622,7 @@ static struct i915_page_table *alloc_pt(struct i915_address_space *vm)
 {
        struct i915_page_table *pt;
 
-       pt = kmalloc(sizeof(*pt), GFP_KERNEL | __GFP_NOWARN);
+       pt = kmalloc(sizeof(*pt), I915_GFP_ALLOW_FAIL);
        if (unlikely(!pt))
                return ERR_PTR(-ENOMEM);
 
@@ -651,7 +659,7 @@ static struct i915_page_directory *alloc_pd(struct i915_address_space *vm)
 {
        struct i915_page_directory *pd;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL | __GFP_NOWARN);
+       pd = kzalloc(sizeof(*pd), I915_GFP_ALLOW_FAIL);
        if (unlikely(!pd))
                return ERR_PTR(-ENOMEM);
 
@@ -685,7 +693,7 @@ static int __pdp_init(struct i915_address_space *vm,
        const unsigned int pdpes = i915_pdpes_per_pdp(vm);
 
        pdp->page_directory = kmalloc_array(pdpes, sizeof(*pdp->page_directory),
-                                           GFP_KERNEL | __GFP_NOWARN);
+                                           I915_GFP_ALLOW_FAIL);
        if (unlikely(!pdp->page_directory))
                return -ENOMEM;
 
@@ -765,53 +773,6 @@ static void gen8_initialize_pml4(struct i915_address_space *vm,
        memset_p((void **)pml4->pdps, vm->scratch_pdp, GEN8_PML4ES_PER_PML4);
 }
 
-/* Broadwell Page Directory Pointer Descriptors */
-static int gen8_write_pdp(struct i915_request *rq,
-                         unsigned entry,
-                         dma_addr_t addr)
-{
-       struct intel_engine_cs *engine = rq->engine;
-       u32 *cs;
-
-       BUG_ON(entry >= 4);
-
-       cs = intel_ring_begin(rq, 6);
-       if (IS_ERR(cs))
-               return PTR_ERR(cs);
-
-       *cs++ = MI_LOAD_REGISTER_IMM(1);
-       *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(engine, entry));
-       *cs++ = upper_32_bits(addr);
-       *cs++ = MI_LOAD_REGISTER_IMM(1);
-       *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(engine, entry));
-       *cs++ = lower_32_bits(addr);
-       intel_ring_advance(rq, cs);
-
-       return 0;
-}
-
-static int gen8_mm_switch_3lvl(struct i915_hw_ppgtt *ppgtt,
-                              struct i915_request *rq)
-{
-       int i, ret;
-
-       for (i = GEN8_3LVL_PDPES - 1; i >= 0; i--) {
-               const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
-
-               ret = gen8_write_pdp(rq, i, pd_daddr);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int gen8_mm_switch_4lvl(struct i915_hw_ppgtt *ppgtt,
-                              struct i915_request *rq)
-{
-       return gen8_write_pdp(rq, 0, px_dma(&ppgtt->pml4));
-}
-
 /* PDE TLBs are a pain to invalidate on GEN8+. When we modify
  * the page table structures, we mark them dirty so that
  * context switching/execlist queuing code takes extra steps
@@ -819,7 +780,7 @@ static int gen8_mm_switch_4lvl(struct i915_hw_ppgtt *ppgtt,
  */
 static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
 {
-       ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.i915)->ring_mask;
+       ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->vm.i915)->ring_mask;
 }
 
 /* Removes entries from a single page table, releasing it if it's empty.
@@ -1012,7 +973,7 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt *ppgtt,
        gen8_pte_t *vaddr;
        bool ret;
 
-       GEM_BUG_ON(idx->pdpe >= i915_pdpes_per_pdp(&ppgtt->base));
+       GEM_BUG_ON(idx->pdpe >= i915_pdpes_per_pdp(&ppgtt->vm));
        pd = pdp->page_directory[idx->pdpe];
        vaddr = kmap_atomic_px(pd->page_table[idx->pde]);
        do {
@@ -1043,7 +1004,7 @@ gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt *ppgtt,
                                        break;
                                }
 
-                               GEM_BUG_ON(idx->pdpe >= i915_pdpes_per_pdp(&ppgtt->base));
+                               GEM_BUG_ON(idx->pdpe >= i915_pdpes_per_pdp(&ppgtt->vm));
                                pd = pdp->page_directory[idx->pdpe];
                        }
 
@@ -1229,7 +1190,7 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 {
        int ret;
 
-       ret = setup_scratch_page(vm, I915_GFP_DMA);
+       ret = setup_scratch_page(vm, __GFP_HIGHMEM);
        if (ret)
                return ret;
 
@@ -1272,7 +1233,7 @@ free_scratch_page:
 
 static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        struct drm_i915_private *dev_priv = vm->i915;
        enum vgt_g2v_type msg;
        int i;
@@ -1333,13 +1294,13 @@ static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
        int i;
 
        for (i = 0; i < GEN8_PML4ES_PER_PML4; i++) {
-               if (ppgtt->pml4.pdps[i] == ppgtt->base.scratch_pdp)
+               if (ppgtt->pml4.pdps[i] == ppgtt->vm.scratch_pdp)
                        continue;
 
-               gen8_ppgtt_cleanup_3lvl(&ppgtt->base, ppgtt->pml4.pdps[i]);
+               gen8_ppgtt_cleanup_3lvl(&ppgtt->vm, ppgtt->pml4.pdps[i]);
        }
 
-       cleanup_px(&ppgtt->base, &ppgtt->pml4);
+       cleanup_px(&ppgtt->vm, &ppgtt->pml4);
 }
 
 static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
@@ -1353,7 +1314,7 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
        if (use_4lvl(vm))
                gen8_ppgtt_cleanup_4lvl(ppgtt);
        else
-               gen8_ppgtt_cleanup_3lvl(&ppgtt->base, &ppgtt->pdp);
+               gen8_ppgtt_cleanup_3lvl(&ppgtt->vm, &ppgtt->pdp);
 
        gen8_free_scratch(vm);
 }
@@ -1489,7 +1450,7 @@ static void gen8_dump_pdp(struct i915_hw_ppgtt *ppgtt,
                          gen8_pte_t scratch_pte,
                          struct seq_file *m)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        struct i915_page_directory *pd;
        u32 pdpe;
 
@@ -1499,7 +1460,7 @@ static void gen8_dump_pdp(struct i915_hw_ppgtt *ppgtt,
                u64 pd_start = start;
                u32 pde;
 
-               if (pdp->page_directory[pdpe] == ppgtt->base.scratch_pd)
+               if (pdp->page_directory[pdpe] == ppgtt->vm.scratch_pd)
                        continue;
 
                seq_printf(m, "\tPDPE #%d\n", pdpe);
@@ -1507,7 +1468,7 @@ static void gen8_dump_pdp(struct i915_hw_ppgtt *ppgtt,
                        u32 pte;
                        gen8_pte_t *pt_vaddr;
 
-                       if (pd->page_table[pde] == ppgtt->base.scratch_pt)
+                       if (pd->page_table[pde] == ppgtt->vm.scratch_pt)
                                continue;
 
                        pt_vaddr = kmap_atomic_px(pt);
@@ -1540,10 +1501,10 @@ static void gen8_dump_pdp(struct i915_hw_ppgtt *ppgtt,
 
 static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        const gen8_pte_t scratch_pte =
                gen8_pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC);
-       u64 start = 0, length = ppgtt->base.total;
+       u64 start = 0, length = ppgtt->vm.total;
 
        if (use_4lvl(vm)) {
                u64 pml4e;
@@ -1551,7 +1512,7 @@ static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
                struct i915_page_directory_pointer *pdp;
 
                gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
-                       if (pml4->pdps[pml4e] == ppgtt->base.scratch_pdp)
+                       if (pml4->pdps[pml4e] == ppgtt->vm.scratch_pdp)
                                continue;
 
                        seq_printf(m, "    PML4E #%llu\n", pml4e);
@@ -1564,10 +1525,10 @@ static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 
 static int gen8_preallocate_top_level_pdp(struct i915_hw_ppgtt *ppgtt)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        struct i915_page_directory_pointer *pdp = &ppgtt->pdp;
        struct i915_page_directory *pd;
-       u64 start = 0, length = ppgtt->base.total;
+       u64 start = 0, length = ppgtt->vm.total;
        u64 from = start;
        unsigned int pdpe;
 
@@ -1603,11 +1564,11 @@ unwind:
  */
 static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        struct drm_i915_private *dev_priv = vm->i915;
        int ret;
 
-       ppgtt->base.total = USES_FULL_48BIT_PPGTT(dev_priv) ?
+       ppgtt->vm.total = USES_FULL_48BIT_PPGTT(dev_priv) ?
                1ULL << 48 :
                1ULL << 32;
 
@@ -1615,27 +1576,26 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
         * And we are not sure about the latter so play safe for now.
         */
        if (IS_CHERRYVIEW(dev_priv) || IS_BROXTON(dev_priv))
-               ppgtt->base.pt_kmap_wc = true;
+               ppgtt->vm.pt_kmap_wc = true;
 
-       ret = gen8_init_scratch(&ppgtt->base);
+       ret = gen8_init_scratch(&ppgtt->vm);
        if (ret) {
-               ppgtt->base.total = 0;
+               ppgtt->vm.total = 0;
                return ret;
        }
 
        if (use_4lvl(vm)) {
-               ret = setup_px(&ppgtt->base, &ppgtt->pml4);
+               ret = setup_px(&ppgtt->vm, &ppgtt->pml4);
                if (ret)
                        goto free_scratch;
 
-               gen8_initialize_pml4(&ppgtt->base, &ppgtt->pml4);
+               gen8_initialize_pml4(&ppgtt->vm, &ppgtt->pml4);
 
-               ppgtt->switch_mm = gen8_mm_switch_4lvl;
-               ppgtt->base.allocate_va_range = gen8_ppgtt_alloc_4lvl;
-               ppgtt->base.insert_entries = gen8_ppgtt_insert_4lvl;
-               ppgtt->base.clear_range = gen8_ppgtt_clear_4lvl;
+               ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc_4lvl;
+               ppgtt->vm.insert_entries = gen8_ppgtt_insert_4lvl;
+               ppgtt->vm.clear_range = gen8_ppgtt_clear_4lvl;
        } else {
-               ret = __pdp_init(&ppgtt->base, &ppgtt->pdp);
+               ret = __pdp_init(&ppgtt->vm, &ppgtt->pdp);
                if (ret)
                        goto free_scratch;
 
@@ -1647,36 +1607,35 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
                        }
                }
 
-               ppgtt->switch_mm = gen8_mm_switch_3lvl;
-               ppgtt->base.allocate_va_range = gen8_ppgtt_alloc_3lvl;
-               ppgtt->base.insert_entries = gen8_ppgtt_insert_3lvl;
-               ppgtt->base.clear_range = gen8_ppgtt_clear_3lvl;
+               ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc_3lvl;
+               ppgtt->vm.insert_entries = gen8_ppgtt_insert_3lvl;
+               ppgtt->vm.clear_range = gen8_ppgtt_clear_3lvl;
        }
 
        if (intel_vgpu_active(dev_priv))
                gen8_ppgtt_notify_vgt(ppgtt, true);
 
-       ppgtt->base.cleanup = gen8_ppgtt_cleanup;
-       ppgtt->base.unbind_vma = ppgtt_unbind_vma;
-       ppgtt->base.bind_vma = ppgtt_bind_vma;
-       ppgtt->base.set_pages = ppgtt_set_pages;
-       ppgtt->base.clear_pages = clear_pages;
+       ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
+       ppgtt->vm.bind_vma = gen8_ppgtt_bind_vma;
+       ppgtt->vm.unbind_vma = ppgtt_unbind_vma;
+       ppgtt->vm.set_pages = ppgtt_set_pages;
+       ppgtt->vm.clear_pages = clear_pages;
        ppgtt->debug_dump = gen8_dump_ppgtt;
 
        return 0;
 
 free_scratch:
-       gen8_free_scratch(&ppgtt->base);
+       gen8_free_scratch(&ppgtt->vm);
        return ret;
 }
 
 static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 {
-       struct i915_address_space *vm = &ppgtt->base;
+       struct i915_address_space *vm = &ppgtt->vm;
        struct i915_page_table *unused;
        gen6_pte_t scratch_pte;
        u32 pd_entry, pte, pde;
-       u32 start = 0, length = ppgtt->base.total;
+       u32 start = 0, length = ppgtt->vm.total;
 
        scratch_pte = vm->pte_encode(vm->scratch_page.daddr,
                                     I915_CACHE_LLC, 0);
@@ -1974,7 +1933,7 @@ static int gen6_init_scratch(struct i915_address_space *vm)
 {
        int ret;
 
-       ret = setup_scratch_page(vm, I915_GFP_DMA);
+       ret = setup_scratch_page(vm, __GFP_HIGHMEM);
        if (ret)
                return ret;
 
@@ -2013,8 +1972,8 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
 
 static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
 {
-       struct i915_address_space *vm = &ppgtt->base;
-       struct drm_i915_private *dev_priv = ppgtt->base.i915;
+       struct i915_address_space *vm = &ppgtt->vm;
+       struct drm_i915_private *dev_priv = ppgtt->vm.i915;
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
        int ret;
 
@@ -2022,16 +1981,16 @@ static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
         * allocator works in address space sizes, so it's multiplied by page
         * size. We allocate at the top of the GTT to avoid fragmentation.
         */
-       BUG_ON(!drm_mm_initialized(&ggtt->base.mm));
+       BUG_ON(!drm_mm_initialized(&ggtt->vm.mm));
 
        ret = gen6_init_scratch(vm);
        if (ret)
                return ret;
 
-       ret = i915_gem_gtt_insert(&ggtt->base, &ppgtt->node,
+       ret = i915_gem_gtt_insert(&ggtt->vm, &ppgtt->node,
                                  GEN6_PD_SIZE, GEN6_PD_ALIGN,
                                  I915_COLOR_UNEVICTABLE,
-                                 0, ggtt->base.total,
+                                 0, ggtt->vm.total,
                                  PIN_HIGH);
        if (ret)
                goto err_out;
@@ -2064,16 +2023,16 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt,
        u32 pde;
 
        gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde)
-               ppgtt->pd.page_table[pde] = ppgtt->base.scratch_pt;
+               ppgtt->pd.page_table[pde] = ppgtt->vm.scratch_pt;
 }
 
 static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 {
-       struct drm_i915_private *dev_priv = ppgtt->base.i915;
+       struct drm_i915_private *dev_priv = ppgtt->vm.i915;
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
        int ret;
 
-       ppgtt->base.pte_encode = ggtt->base.pte_encode;
+       ppgtt->vm.pte_encode = ggtt->vm.pte_encode;
        if (intel_vgpu_active(dev_priv) || IS_GEN6(dev_priv))
                ppgtt->switch_mm = gen6_mm_switch;
        else if (IS_HASWELL(dev_priv))
@@ -2087,24 +2046,24 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
        if (ret)
                return ret;
 
-       ppgtt->base.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
+       ppgtt->vm.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
 
-       gen6_scratch_va_range(ppgtt, 0, ppgtt->base.total);
-       gen6_write_page_range(ppgtt, 0, ppgtt->base.total);
+       gen6_scratch_va_range(ppgtt, 0, ppgtt->vm.total);
+       gen6_write_page_range(ppgtt, 0, ppgtt->vm.total);
 
-       ret = gen6_alloc_va_range(&ppgtt->base, 0, ppgtt->base.total);
+       ret = gen6_alloc_va_range(&ppgtt->vm, 0, ppgtt->vm.total);
        if (ret) {
-               gen6_ppgtt_cleanup(&ppgtt->base);
+               gen6_ppgtt_cleanup(&ppgtt->vm);
                return ret;
        }
 
-       ppgtt->base.clear_range = gen6_ppgtt_clear_range;
-       ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
-       ppgtt->base.unbind_vma = ppgtt_unbind_vma;
-       ppgtt->base.bind_vma = ppgtt_bind_vma;
-       ppgtt->base.set_pages = ppgtt_set_pages;
-       ppgtt->base.clear_pages = clear_pages;
-       ppgtt->base.cleanup = gen6_ppgtt_cleanup;
+       ppgtt->vm.clear_range = gen6_ppgtt_clear_range;
+       ppgtt->vm.insert_entries = gen6_ppgtt_insert_entries;
+       ppgtt->vm.bind_vma = gen6_ppgtt_bind_vma;
+       ppgtt->vm.unbind_vma = ppgtt_unbind_vma;
+       ppgtt->vm.set_pages = ppgtt_set_pages;
+       ppgtt->vm.clear_pages = clear_pages;
+       ppgtt->vm.cleanup = gen6_ppgtt_cleanup;
        ppgtt->debug_dump = gen6_dump_ppgtt;
 
        DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
@@ -2120,8 +2079,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
                           struct drm_i915_private *dev_priv)
 {
-       ppgtt->base.i915 = dev_priv;
-       ppgtt->base.dma = &dev_priv->drm.pdev->dev;
+       ppgtt->vm.i915 = dev_priv;
+       ppgtt->vm.dma = &dev_priv->drm.pdev->dev;
 
        if (INTEL_GEN(dev_priv) < 8)
                return gen6_ppgtt_init(ppgtt);
@@ -2231,10 +2190,10 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv,
        }
 
        kref_init(&ppgtt->ref);
-       i915_address_space_init(&ppgtt->base, dev_priv, name);
-       ppgtt->base.file = fpriv;
+       i915_address_space_init(&ppgtt->vm, dev_priv, name);
+       ppgtt->vm.file = fpriv;
 
-       trace_i915_ppgtt_create(&ppgtt->base);
+       trace_i915_ppgtt_create(&ppgtt->vm);
 
        return ppgtt;
 }
@@ -2268,16 +2227,16 @@ void i915_ppgtt_release(struct kref *kref)
        struct i915_hw_ppgtt *ppgtt =
                container_of(kref, struct i915_hw_ppgtt, ref);
 
-       trace_i915_ppgtt_release(&ppgtt->base);
+       trace_i915_ppgtt_release(&ppgtt->vm);
 
-       ppgtt_destroy_vma(&ppgtt->base);
+       ppgtt_destroy_vma(&ppgtt->vm);
 
-       GEM_BUG_ON(!list_empty(&ppgtt->base.active_list));
-       GEM_BUG_ON(!list_empty(&ppgtt->base.inactive_list));
-       GEM_BUG_ON(!list_empty(&ppgtt->base.unbound_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->vm.active_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->vm.inactive_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->vm.unbound_list));
 
-       ppgtt->base.cleanup(&ppgtt->base);
-       i915_address_space_fini(&ppgtt->base);
+       ppgtt->vm.cleanup(&ppgtt->vm);
+       i915_address_space_fini(&ppgtt->vm);
        kfree(ppgtt);
 }
 
@@ -2373,7 +2332,7 @@ void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
 
        i915_check_and_clear_faults(dev_priv);
 
-       ggtt->base.clear_range(&ggtt->base, 0, ggtt->base.total);
+       ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
 
        i915_ggtt_invalidate(dev_priv);
 }
@@ -2716,16 +2675,16 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
                struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt;
 
                if (!(vma->flags & I915_VMA_LOCAL_BIND) &&
-                   appgtt->base.allocate_va_range) {
-                       ret = appgtt->base.allocate_va_range(&appgtt->base,
-                                                            vma->node.start,
-                                                            vma->size);
+                   appgtt->vm.allocate_va_range) {
+                       ret = appgtt->vm.allocate_va_range(&appgtt->vm,
+                                                          vma->node.start,
+                                                          vma->size);
                        if (ret)
                                return ret;
                }
 
-               appgtt->base.insert_entries(&appgtt->base, vma, cache_level,
-                                           pte_flags);
+               appgtt->vm.insert_entries(&appgtt->vm, vma, cache_level,
+                                         pte_flags);
        }
 
        if (flags & I915_VMA_GLOBAL_BIND) {
@@ -2748,7 +2707,7 @@ static void aliasing_gtt_unbind_vma(struct i915_vma *vma)
        }
 
        if (vma->flags & I915_VMA_LOCAL_BIND) {
-               struct i915_address_space *vm = &i915->mm.aliasing_ppgtt->base;
+               struct i915_address_space *vm = &i915->mm.aliasing_ppgtt->vm;
 
                vm->clear_range(vm, vma->node.start, vma->size);
        }
@@ -2815,30 +2774,30 @@ int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915)
        if (IS_ERR(ppgtt))
                return PTR_ERR(ppgtt);
 
-       if (WARN_ON(ppgtt->base.total < ggtt->base.total)) {
+       if (WARN_ON(ppgtt->vm.total < ggtt->vm.total)) {
                err = -ENODEV;
                goto err_ppgtt;
        }
 
-       if (ppgtt->base.allocate_va_range) {
+       if (ppgtt->vm.allocate_va_range) {
                /* Note we only pre-allocate as far as the end of the global
                 * GTT. On 48b / 4-level page-tables, the difference is very,
                 * very significant! We have to preallocate as GVT/vgpu does
                 * not like the page directory disappearing.
                 */
-               err = ppgtt->base.allocate_va_range(&ppgtt->base,
-                                                   0, ggtt->base.total);
+               err = ppgtt->vm.allocate_va_range(&ppgtt->vm,
+                                                 0, ggtt->vm.total);
                if (err)
                        goto err_ppgtt;
        }
 
        i915->mm.aliasing_ppgtt = ppgtt;
 
-       GEM_BUG_ON(ggtt->base.bind_vma != ggtt_bind_vma);
-       ggtt->base.bind_vma = aliasing_gtt_bind_vma;
+       GEM_BUG_ON(ggtt->vm.bind_vma != ggtt_bind_vma);
+       ggtt->vm.bind_vma = aliasing_gtt_bind_vma;
 
-       GEM_BUG_ON(ggtt->base.unbind_vma != ggtt_unbind_vma);
-       ggtt->base.unbind_vma = aliasing_gtt_unbind_vma;
+       GEM_BUG_ON(ggtt->vm.unbind_vma != ggtt_unbind_vma);
+       ggtt->vm.unbind_vma = aliasing_gtt_unbind_vma;
 
        return 0;
 
@@ -2858,8 +2817,8 @@ void i915_gem_fini_aliasing_ppgtt(struct drm_i915_private *i915)
 
        i915_ppgtt_put(ppgtt);
 
-       ggtt->base.bind_vma = ggtt_bind_vma;
-       ggtt->base.unbind_vma = ggtt_unbind_vma;
+       ggtt->vm.bind_vma = ggtt_bind_vma;
+       ggtt->vm.unbind_vma = ggtt_unbind_vma;
 }
 
 int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
@@ -2883,7 +2842,7 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
                return ret;
 
        /* Reserve a mappable slot for our lockless error capture */
-       ret = drm_mm_insert_node_in_range(&ggtt->base.mm, &ggtt->error_capture,
+       ret = drm_mm_insert_node_in_range(&ggtt->vm.mm, &ggtt->error_capture,
                                          PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
                                          0, ggtt->mappable_end,
                                          DRM_MM_INSERT_LOW);
@@ -2891,16 +2850,15 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
                return ret;
 
        /* Clear any non-preallocated blocks */
-       drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) {
+       drm_mm_for_each_hole(entry, &ggtt->vm.mm, hole_start, hole_end) {
                DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
                              hole_start, hole_end);
-               ggtt->base.clear_range(&ggtt->base, hole_start,
-                                      hole_end - hole_start);
+               ggtt->vm.clear_range(&ggtt->vm, hole_start,
+                                    hole_end - hole_start);
        }
 
        /* And finally clear the reserved guard page */
-       ggtt->base.clear_range(&ggtt->base,
-                              ggtt->base.total - PAGE_SIZE, PAGE_SIZE);
+       ggtt->vm.clear_range(&ggtt->vm, ggtt->vm.total - PAGE_SIZE, PAGE_SIZE);
 
        if (USES_PPGTT(dev_priv) && !USES_FULL_PPGTT(dev_priv)) {
                ret = i915_gem_init_aliasing_ppgtt(dev_priv);
@@ -2925,11 +2883,11 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
        struct i915_vma *vma, *vn;
        struct pagevec *pvec;
 
-       ggtt->base.closed = true;
+       ggtt->vm.closed = true;
 
        mutex_lock(&dev_priv->drm.struct_mutex);
-       GEM_BUG_ON(!list_empty(&ggtt->base.active_list));
-       list_for_each_entry_safe(vma, vn, &ggtt->base.inactive_list, vm_link)
+       GEM_BUG_ON(!list_empty(&ggtt->vm.active_list));
+       list_for_each_entry_safe(vma, vn, &ggtt->vm.inactive_list, vm_link)
                WARN_ON(i915_vma_unbind(vma));
        mutex_unlock(&dev_priv->drm.struct_mutex);
 
@@ -2941,12 +2899,12 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
        if (drm_mm_node_allocated(&ggtt->error_capture))
                drm_mm_remove_node(&ggtt->error_capture);
 
-       if (drm_mm_initialized(&ggtt->base.mm)) {
+       if (drm_mm_initialized(&ggtt->vm.mm)) {
                intel_vgt_deballoon(dev_priv);
-               i915_address_space_fini(&ggtt->base);
+               i915_address_space_fini(&ggtt->vm);
        }
 
-       ggtt->base.cleanup(&ggtt->base);
+       ggtt->vm.cleanup(&ggtt->vm);
 
        pvec = &dev_priv->mm.wc_stash;
        if (pvec->nr) {
@@ -2996,7 +2954,7 @@ static unsigned int chv_get_total_gtt_size(u16 gmch_ctrl)
 
 static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 {
-       struct drm_i915_private *dev_priv = ggtt->base.i915;
+       struct drm_i915_private *dev_priv = ggtt->vm.i915;
        struct pci_dev *pdev = dev_priv->drm.pdev;
        phys_addr_t phys_addr;
        int ret;
@@ -3020,7 +2978,7 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
                return -ENOMEM;
        }
 
-       ret = setup_scratch_page(&ggtt->base, GFP_DMA32);
+       ret = setup_scratch_page(&ggtt->vm, GFP_DMA32);
        if (ret) {
                DRM_ERROR("Scratch setup failed\n");
                /* iounmap will also get called at remove, but meh */
@@ -3326,7 +3284,7 @@ static void setup_private_pat(struct drm_i915_private *dev_priv)
 
 static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 {
-       struct drm_i915_private *dev_priv = ggtt->base.i915;
+       struct drm_i915_private *dev_priv = ggtt->vm.i915;
        struct pci_dev *pdev = dev_priv->drm.pdev;
        unsigned int size;
        u16 snb_gmch_ctl;
@@ -3350,25 +3308,25 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
        else
                size = gen8_get_total_gtt_size(snb_gmch_ctl);
 
-       ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
-       ggtt->base.cleanup = gen6_gmch_remove;
-       ggtt->base.bind_vma = ggtt_bind_vma;
-       ggtt->base.unbind_vma = ggtt_unbind_vma;
-       ggtt->base.set_pages = ggtt_set_pages;
-       ggtt->base.clear_pages = clear_pages;
-       ggtt->base.insert_page = gen8_ggtt_insert_page;
-       ggtt->base.clear_range = nop_clear_range;
+       ggtt->vm.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
+       ggtt->vm.cleanup = gen6_gmch_remove;
+       ggtt->vm.bind_vma = ggtt_bind_vma;
+       ggtt->vm.unbind_vma = ggtt_unbind_vma;
+       ggtt->vm.set_pages = ggtt_set_pages;
+       ggtt->vm.clear_pages = clear_pages;
+       ggtt->vm.insert_page = gen8_ggtt_insert_page;
+       ggtt->vm.clear_range = nop_clear_range;
        if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv))
-               ggtt->base.clear_range = gen8_ggtt_clear_range;
+               ggtt->vm.clear_range = gen8_ggtt_clear_range;
 
-       ggtt->base.insert_entries = gen8_ggtt_insert_entries;
+       ggtt->vm.insert_entries = gen8_ggtt_insert_entries;
 
        /* Serialize GTT updates with aperture access on BXT if VT-d is on. */
        if (intel_ggtt_update_needs_vtd_wa(dev_priv)) {
-               ggtt->base.insert_entries = bxt_vtd_ggtt_insert_entries__BKL;
-               ggtt->base.insert_page    = bxt_vtd_ggtt_insert_page__BKL;
-               if (ggtt->base.clear_range != nop_clear_range)
-                       ggtt->base.clear_range = bxt_vtd_ggtt_clear_range__BKL;
+               ggtt->vm.insert_entries = bxt_vtd_ggtt_insert_entries__BKL;
+               ggtt->vm.insert_page    = bxt_vtd_ggtt_insert_page__BKL;
+               if (ggtt->vm.clear_range != nop_clear_range)
+                       ggtt->vm.clear_range = bxt_vtd_ggtt_clear_range__BKL;
        }
 
        ggtt->invalidate = gen6_ggtt_invalidate;
@@ -3380,7 +3338,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 
 static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 {
-       struct drm_i915_private *dev_priv = ggtt->base.i915;
+       struct drm_i915_private *dev_priv = ggtt->vm.i915;
        struct pci_dev *pdev = dev_priv->drm.pdev;
        unsigned int size;
        u16 snb_gmch_ctl;
@@ -3407,29 +3365,29 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
        pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
 
        size = gen6_get_total_gtt_size(snb_gmch_ctl);
-       ggtt->base.total = (size / sizeof(gen6_pte_t)) << PAGE_SHIFT;
+       ggtt->vm.total = (size / sizeof(gen6_pte_t)) << PAGE_SHIFT;
 
-       ggtt->base.clear_range = gen6_ggtt_clear_range;
-       ggtt->base.insert_page = gen6_ggtt_insert_page;
-       ggtt->base.insert_entries = gen6_ggtt_insert_entries;
-       ggtt->base.bind_vma = ggtt_bind_vma;
-       ggtt->base.unbind_vma = ggtt_unbind_vma;
-       ggtt->base.set_pages = ggtt_set_pages;
-       ggtt->base.clear_pages = clear_pages;
-       ggtt->base.cleanup = gen6_gmch_remove;
+       ggtt->vm.clear_range = gen6_ggtt_clear_range;
+       ggtt->vm.insert_page = gen6_ggtt_insert_page;
+       ggtt->vm.insert_entries = gen6_ggtt_insert_entries;
+       ggtt->vm.bind_vma = ggtt_bind_vma;
+       ggtt->vm.unbind_vma = ggtt_unbind_vma;
+       ggtt->vm.set_pages = ggtt_set_pages;
+       ggtt->vm.clear_pages = clear_pages;
+       ggtt->vm.cleanup = gen6_gmch_remove;
 
        ggtt->invalidate = gen6_ggtt_invalidate;
 
        if (HAS_EDRAM(dev_priv))
-               ggtt->base.pte_encode = iris_pte_encode;
+               ggtt->vm.pte_encode = iris_pte_encode;
        else if (IS_HASWELL(dev_priv))
-               ggtt->base.pte_encode = hsw_pte_encode;
+               ggtt->vm.pte_encode = hsw_pte_encode;
        else if (IS_VALLEYVIEW(dev_priv))
-               ggtt->base.pte_encode = byt_pte_encode;
+               ggtt->vm.pte_encode = byt_pte_encode;
        else if (INTEL_GEN(dev_priv) >= 7)
-               ggtt->base.pte_encode = ivb_pte_encode;
+               ggtt->vm.pte_encode = ivb_pte_encode;
        else
-               ggtt->base.pte_encode = snb_pte_encode;
+               ggtt->vm.pte_encode = snb_pte_encode;
 
        return ggtt_probe_common(ggtt, size);
 }
@@ -3441,7 +3399,7 @@ static void i915_gmch_remove(struct i915_address_space *vm)
 
 static int i915_gmch_probe(struct i915_ggtt *ggtt)
 {
-       struct drm_i915_private *dev_priv = ggtt->base.i915;
+       struct drm_i915_private *dev_priv = ggtt->vm.i915;
        phys_addr_t gmadr_base;
        int ret;
 
@@ -3451,23 +3409,21 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
                return -EIO;
        }
 
-       intel_gtt_get(&ggtt->base.total,
-                     &gmadr_base,
-                     &ggtt->mappable_end);
+       intel_gtt_get(&ggtt->vm.total, &gmadr_base, &ggtt->mappable_end);
 
        ggtt->gmadr =
                (struct resource) DEFINE_RES_MEM(gmadr_base,
                                                 ggtt->mappable_end);
 
        ggtt->do_idle_maps = needs_idle_maps(dev_priv);
-       ggtt->base.insert_page = i915_ggtt_insert_page;
-       ggtt->base.insert_entries = i915_ggtt_insert_entries;
-       ggtt->base.clear_range = i915_ggtt_clear_range;
-       ggtt->base.bind_vma = ggtt_bind_vma;
-       ggtt->base.unbind_vma = ggtt_unbind_vma;
-       ggtt->base.set_pages = ggtt_set_pages;
-       ggtt->base.clear_pages = clear_pages;
-       ggtt->base.cleanup = i915_gmch_remove;
+       ggtt->vm.insert_page = i915_ggtt_insert_page;
+       ggtt->vm.insert_entries = i915_ggtt_insert_entries;
+       ggtt->vm.clear_range = i915_ggtt_clear_range;
+       ggtt->vm.bind_vma = ggtt_bind_vma;
+       ggtt->vm.unbind_vma = ggtt_unbind_vma;
+       ggtt->vm.set_pages = ggtt_set_pages;
+       ggtt->vm.clear_pages = clear_pages;
+       ggtt->vm.cleanup = i915_gmch_remove;
 
        ggtt->invalidate = gmch_ggtt_invalidate;
 
@@ -3486,8 +3442,8 @@ int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv)
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
        int ret;
 
-       ggtt->base.i915 = dev_priv;
-       ggtt->base.dma = &dev_priv->drm.pdev->dev;
+       ggtt->vm.i915 = dev_priv;
+       ggtt->vm.dma = &dev_priv->drm.pdev->dev;
 
        if (INTEL_GEN(dev_priv) <= 5)
                ret = i915_gmch_probe(ggtt);
@@ -3504,27 +3460,29 @@ int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv)
         * restriction!
         */
        if (USES_GUC(dev_priv)) {
-               ggtt->base.total = min_t(u64, ggtt->base.total, GUC_GGTT_TOP);
-               ggtt->mappable_end = min_t(u64, ggtt->mappable_end, ggtt->base.total);
+               ggtt->vm.total = min_t(u64, ggtt->vm.total, GUC_GGTT_TOP);
+               ggtt->mappable_end =
+                       min_t(u64, ggtt->mappable_end, ggtt->vm.total);
        }
 
-       if ((ggtt->base.total - 1) >> 32) {
+       if ((ggtt->vm.total - 1) >> 32) {
                DRM_ERROR("We never expected a Global GTT with more than 32bits"
                          " of address space! Found %lldM!\n",
-                         ggtt->base.total >> 20);
-               ggtt->base.total = 1ULL << 32;
-               ggtt->mappable_end = min_t(u64, ggtt->mappable_end, ggtt->base.total);
+                         ggtt->vm.total >> 20);
+               ggtt->vm.total = 1ULL << 32;
+               ggtt->mappable_end =
+                       min_t(u64, ggtt->mappable_end, ggtt->vm.total);
        }
 
-       if (ggtt->mappable_end > ggtt->base.total) {
+       if (ggtt->mappable_end > ggtt->vm.total) {
                DRM_ERROR("mappable aperture extends past end of GGTT,"
                          " aperture=%pa, total=%llx\n",
-                         &ggtt->mappable_end, ggtt->base.total);
-               ggtt->mappable_end = ggtt->base.total;
+                         &ggtt->mappable_end, ggtt->vm.total);
+               ggtt->mappable_end = ggtt->vm.total;
        }
 
        /* GMADR is the PCI mmio aperture into the global GTT. */
-       DRM_DEBUG_DRIVER("GGTT size = %lluM\n", ggtt->base.total >> 20);
+       DRM_DEBUG_DRIVER("GGTT size = %lluM\n", ggtt->vm.total >> 20);
        DRM_DEBUG_DRIVER("GMADR size = %lluM\n", (u64)ggtt->mappable_end >> 20);
        DRM_DEBUG_DRIVER("DSM size = %lluM\n",
                         (u64)resource_size(&intel_graphics_stolen_res) >> 20);
@@ -3551,9 +3509,9 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
         * and beyond the end of the GTT if we do not provide a guard.
         */
        mutex_lock(&dev_priv->drm.struct_mutex);
-       i915_address_space_init(&ggtt->base, dev_priv, "[global]");
+       i915_address_space_init(&ggtt->vm, dev_priv, "[global]");
        if (!HAS_LLC(dev_priv) && !USES_PPGTT(dev_priv))
-               ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
+               ggtt->vm.mm.color_adjust = i915_gtt_color_adjust;
        mutex_unlock(&dev_priv->drm.struct_mutex);
 
        if (!io_mapping_init_wc(&dev_priv->ggtt.iomap,
@@ -3576,7 +3534,7 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
        return 0;
 
 out_gtt_cleanup:
-       ggtt->base.cleanup(&ggtt->base);
+       ggtt->vm.cleanup(&ggtt->vm);
        return ret;
 }
 
@@ -3610,34 +3568,31 @@ void i915_ggtt_disable_guc(struct drm_i915_private *i915)
 void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
 {
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
-       struct drm_i915_gem_object *obj, *on;
+       struct i915_vma *vma, *vn;
 
        i915_check_and_clear_faults(dev_priv);
 
        /* First fill our portion of the GTT with scratch pages */
-       ggtt->base.clear_range(&ggtt->base, 0, ggtt->base.total);
+       ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
 
-       ggtt->base.closed = true; /* skip rewriting PTE on VMA unbind */
+       ggtt->vm.closed = true; /* skip rewriting PTE on VMA unbind */
 
        /* clflush objects bound into the GGTT and rebind them. */
-       list_for_each_entry_safe(obj, on, &dev_priv->mm.bound_list, mm.link) {
-               bool ggtt_bound = false;
-               struct i915_vma *vma;
+       GEM_BUG_ON(!list_empty(&ggtt->vm.active_list));
+       list_for_each_entry_safe(vma, vn, &ggtt->vm.inactive_list, vm_link) {
+               struct drm_i915_gem_object *obj = vma->obj;
 
-               for_each_ggtt_vma(vma, obj) {
-                       if (!i915_vma_unbind(vma))
-                               continue;
+               if (!(vma->flags & I915_VMA_GLOBAL_BIND))
+                       continue;
 
-                       WARN_ON(i915_vma_bind(vma, obj->cache_level,
-                                             PIN_UPDATE));
-                       ggtt_bound = true;
-               }
+               if (!i915_vma_unbind(vma))
+                       continue;
 
-               if (ggtt_bound)
-                       WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
+               WARN_ON(i915_vma_bind(vma, obj->cache_level, PIN_UPDATE));
+               WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
        }
 
-       ggtt->base.closed = false;
+       ggtt->vm.closed = false;
 
        if (INTEL_GEN(dev_priv) >= 8) {
                struct intel_ppat *ppat = &dev_priv->ppat;
@@ -3657,8 +3612,10 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
                                ppgtt = dev_priv->mm.aliasing_ppgtt;
                        else
                                ppgtt = i915_vm_to_ppgtt(vm);
+                       if (!ppgtt)
+                               continue;
 
-                       gen6_write_page_range(ppgtt, 0, ppgtt->base.total);
+                       gen6_write_page_range(ppgtt, 0, ppgtt->vm.total);
                }
        }
 
@@ -3880,7 +3837,7 @@ int i915_gem_gtt_reserve(struct i915_address_space *vm,
        GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
        GEM_BUG_ON(!IS_ALIGNED(offset, I915_GTT_MIN_ALIGNMENT));
        GEM_BUG_ON(range_overflows(offset, size, vm->total));
-       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
+       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->vm);
        GEM_BUG_ON(drm_mm_node_allocated(node));
 
        node->size = size;
@@ -3977,7 +3934,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
        GEM_BUG_ON(start >= end);
        GEM_BUG_ON(start > 0  && !IS_ALIGNED(start, I915_GTT_PAGE_SIZE));
        GEM_BUG_ON(end < U64_MAX && !IS_ALIGNED(end, I915_GTT_PAGE_SIZE));
-       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
+       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->vm);
        GEM_BUG_ON(drm_mm_node_allocated(node));
 
        if (unlikely(range_overflows(start, size, end)))
index aec4f73574f4de684be02e0687b4da763344435e..197c2c06ecb73afb835c2fe2a0f10eee07a9895d 100644 (file)
@@ -65,7 +65,7 @@ typedef u64 gen8_pde_t;
 typedef u64 gen8_ppgtt_pdpe_t;
 typedef u64 gen8_ppgtt_pml4e_t;
 
-#define ggtt_total_entries(ggtt) ((ggtt)->base.total >> PAGE_SHIFT)
+#define ggtt_total_entries(ggtt) ((ggtt)->vm.total >> PAGE_SHIFT)
 
 /* gen6-hsw has bit 11-4 for physical addr bit 39-32 */
 #define GEN6_GTT_ADDR_ENCODE(addr)     ((addr) | (((addr) >> 28) & 0xff0))
@@ -367,7 +367,7 @@ i915_vm_has_scratch_64K(struct i915_address_space *vm)
  * the spec.
  */
 struct i915_ggtt {
-       struct i915_address_space base;
+       struct i915_address_space vm;
 
        struct io_mapping iomap;        /* Mapping to our CPU mappable region */
        struct resource gmadr;          /* GMADR resource */
@@ -385,7 +385,7 @@ struct i915_ggtt {
 };
 
 struct i915_hw_ppgtt {
-       struct i915_address_space base;
+       struct i915_address_space vm;
        struct kref ref;
        struct drm_mm_node node;
        unsigned long pd_dirty_rings;
@@ -543,7 +543,7 @@ static inline struct i915_ggtt *
 i915_vm_to_ggtt(struct i915_address_space *vm)
 {
        GEM_BUG_ON(!i915_is_ggtt(vm));
-       return container_of(vm, struct i915_ggtt, base);
+       return container_of(vm, struct i915_ggtt, vm);
 }
 
 #define INTEL_MAX_PPAT_ENTRIES 8
index 1036e8686916578accdb30f850401b4b384a6ba0..3210cedfa46c374829fa014932899a5637c610e7 100644 (file)
@@ -194,7 +194,7 @@ int i915_gem_render_state_emit(struct i915_request *rq)
        if (IS_ERR(so.obj))
                return PTR_ERR(so.obj);
 
-       so.vma = i915_vma_instance(so.obj, &engine->i915->ggtt.base, NULL);
+       so.vma = i915_vma_instance(so.obj, &engine->i915->ggtt.vm, NULL);
        if (IS_ERR(so.vma)) {
                err = PTR_ERR(so.vma);
                goto err_obj;
index 5757fb7c4b5af567d6841f128887875f03d96487..55e84e71f526d23bb34a71f1db60cd864e151e6c 100644 (file)
@@ -480,7 +480,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
 
        /* We also want to clear any cached iomaps as they wrap vmap */
        list_for_each_entry_safe(vma, next,
-                                &i915->ggtt.base.inactive_list, vm_link) {
+                                &i915->ggtt.vm.inactive_list, vm_link) {
                unsigned long count = vma->node.size >> PAGE_SHIFT;
                if (vma->iomap && i915_vma_unbind(vma) == 0)
                        freed_pages += count;
index ad949cc3092816cc123d8109d80151dfcc9e6ac9..79a347295e006e53de34acbdc8d5e86892ca21bd 100644 (file)
@@ -642,7 +642,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
        if (ret)
                goto err;
 
-       vma = i915_vma_instance(obj, &ggtt->base, NULL);
+       vma = i915_vma_instance(obj, &ggtt->vm, NULL);
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);
                goto err_pages;
@@ -653,7 +653,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
         * setting up the GTT space. The actual reservation will occur
         * later.
         */
-       ret = i915_gem_gtt_reserve(&ggtt->base, &vma->node,
+       ret = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
                                   size, gtt_offset, obj->cache_level,
                                   0);
        if (ret) {
@@ -666,7 +666,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
        vma->pages = obj->mm.pages;
        vma->flags |= I915_VMA_GLOBAL_BIND;
        __i915_vma_set_map_and_fenceable(vma);
-       list_move_tail(&vma->vm_link, &ggtt->base.inactive_list);
+       list_move_tail(&vma->vm_link, &ggtt->vm.inactive_list);
 
        spin_lock(&dev_priv->mm.obj_lock);
        list_move_tail(&obj->mm.link, &dev_priv->mm.bound_list);
index df234dc23274fe254c9210183ec8dd7f02de59c4..758234d20f4ea9b464bef01321a2d64a7253f538 100644 (file)
@@ -973,8 +973,7 @@ i915_error_object_create(struct drm_i915_private *i915,
                void __iomem *s;
                int ret;
 
-               ggtt->base.insert_page(&ggtt->base, dma, slot,
-                                      I915_CACHE_NONE, 0);
+               ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
 
                s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
                ret = compress_page(&compress, (void  __force *)s, dst);
@@ -993,7 +992,7 @@ unwind:
 
 out:
        compress_fini(&compress, dst);
-       ggtt->base.clear_range(&ggtt->base, slot, PAGE_SIZE);
+       ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
        return dst;
 }
 
@@ -1287,9 +1286,11 @@ static void error_record_engine_registers(struct i915_gpu_state *error,
 static void record_request(struct i915_request *request,
                           struct drm_i915_error_request *erq)
 {
-       erq->context = request->ctx->hw_id;
+       struct i915_gem_context *ctx = request->gem_context;
+
+       erq->context = ctx->hw_id;
        erq->sched_attr = request->sched.attr;
-       erq->ban_score = atomic_read(&request->ctx->ban_score);
+       erq->ban_score = atomic_read(&ctx->ban_score);
        erq->seqno = request->global_seqno;
        erq->jiffies = request->emitted_jiffies;
        erq->start = i915_ggtt_offset(request->ring->vma);
@@ -1297,7 +1298,7 @@ static void record_request(struct i915_request *request,
        erq->tail = request->tail;
 
        rcu_read_lock();
-       erq->pid = request->ctx->pid ? pid_nr(request->ctx->pid) : 0;
+       erq->pid = ctx->pid ? pid_nr(ctx->pid) : 0;
        rcu_read_unlock();
 }
 
@@ -1461,12 +1462,12 @@ static void gem_record_rings(struct i915_gpu_state *error)
 
                request = i915_gem_find_active_request(engine);
                if (request) {
+                       struct i915_gem_context *ctx = request->gem_context;
                        struct intel_ring *ring;
 
-                       ee->vm = request->ctx->ppgtt ?
-                               &request->ctx->ppgtt->base : &ggtt->base;
+                       ee->vm = ctx->ppgtt ? &ctx->ppgtt->vm : &ggtt->vm;
 
-                       record_context(&ee->context, request->ctx);
+                       record_context(&ee->context, ctx);
 
                        /* We need to copy these to an anonymous buffer
                         * as the simplest method to avoid being overwritten
@@ -1483,11 +1484,10 @@ static void gem_record_rings(struct i915_gpu_state *error)
 
                        ee->ctx =
                                i915_error_object_create(i915,
-                                                        to_intel_context(request->ctx,
-                                                                         engine)->state);
+                                                        request->hw_context->state);
 
                        error->simulated |=
-                               i915_gem_context_no_error_capture(request->ctx);
+                               i915_gem_context_no_error_capture(ctx);
 
                        ee->rq_head = request->head;
                        ee->rq_post = request->postfix;
@@ -1563,17 +1563,17 @@ static void capture_active_buffers(struct i915_gpu_state *error)
 
 static void capture_pinned_buffers(struct i915_gpu_state *error)
 {
-       struct i915_address_space *vm = &error->i915->ggtt.base;
+       struct i915_address_space *vm = &error->i915->ggtt.vm;
        struct drm_i915_error_buffer *bo;
        struct i915_vma *vma;
        int count_inactive, count_active;
 
        count_inactive = 0;
-       list_for_each_entry(vma, &vm->active_list, vm_link)
+       list_for_each_entry(vma, &vm->inactive_list, vm_link)
                count_inactive++;
 
        count_active = 0;
-       list_for_each_entry(vma, &vm->inactive_list, vm_link)
+       list_for_each_entry(vma, &vm->active_list, vm_link)
                count_active++;
 
        bo = NULL;
@@ -1667,7 +1667,16 @@ static void capture_reg_state(struct i915_gpu_state *error)
        }
 
        /* 4: Everything else */
-       if (INTEL_GEN(dev_priv) >= 8) {
+       if (INTEL_GEN(dev_priv) >= 11) {
+               error->ier = I915_READ(GEN8_DE_MISC_IER);
+               error->gtier[0] = I915_READ(GEN11_RENDER_COPY_INTR_ENABLE);
+               error->gtier[1] = I915_READ(GEN11_VCS_VECS_INTR_ENABLE);
+               error->gtier[2] = I915_READ(GEN11_GUC_SG_INTR_ENABLE);
+               error->gtier[3] = I915_READ(GEN11_GPM_WGBOXPERF_INTR_ENABLE);
+               error->gtier[4] = I915_READ(GEN11_CRYPTO_RSVD_INTR_ENABLE);
+               error->gtier[5] = I915_READ(GEN11_GUNIT_CSME_INTR_ENABLE);
+               error->ngtier = 6;
+       } else if (INTEL_GEN(dev_priv) >= 8) {
                error->ier = I915_READ(GEN8_DE_MISC_IER);
                for (i = 0; i < 4; i++)
                        error->gtier[i] = I915_READ(GEN8_GT_IER(i));
index dac0f8c4c1cfa776d3e79845a9e036361b511afd..58910f1dc67c226673f4c2f47f97d600f18e9401 100644 (file)
@@ -58,7 +58,7 @@ struct i915_gpu_state {
        u32 eir;
        u32 pgtbl_er;
        u32 ier;
-       u32 gtier[4], ngtier;
+       u32 gtier[6], ngtier;
        u32 ccid;
        u32 derrmr;
        u32 forcewake;
index f9bc3aaa90d0f5de110e893415be0a6ee1c40448..2fd92a886789494fc3276ab850ab545ecc3a5083 100644 (file)
@@ -2640,7 +2640,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
                                            GEN9_AUX_CHANNEL_C |
                                            GEN9_AUX_CHANNEL_D;
 
-                       if (IS_CNL_WITH_PORT_F(dev_priv))
+                       if (IS_CNL_WITH_PORT_F(dev_priv) ||
+                           INTEL_GEN(dev_priv) >= 11)
                                tmp_mask |= CNL_AUX_CHANNEL_F;
 
                        if (iir & tmp_mask) {
@@ -3920,7 +3921,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
                de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
        }
 
-       if (IS_CNL_WITH_PORT_F(dev_priv))
+       if (IS_CNL_WITH_PORT_F(dev_priv) || INTEL_GEN(dev_priv) >= 11)
                de_port_masked |= CNL_AUX_CHANNEL_F;
 
        de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
index 66ea3552c63ec7634d5b61b4023a1d8899bc291d..49fcc4679db67e47c2d49f77db9ae09417b64b1d 100644 (file)
@@ -130,9 +130,6 @@ i915_param_named_unsafe(invert_brightness, int, 0600,
 i915_param_named(disable_display, bool, 0400,
        "Disable display (default: false)");
 
-i915_param_named_unsafe(enable_cmd_parser, bool, 0400,
-       "Enable command parsing (true=enabled [default], false=disabled)");
-
 i915_param_named(mmio_debug, int, 0600,
        "Enable the MMIO debug code for the first N failures (default: off). "
        "This may negatively affect performance.");
index 6684025b7af8b899604ba67646f4a00191f685c6..aebe0469ddaa3e36af1568f42721d09aa9b40025 100644 (file)
@@ -58,7 +58,6 @@ struct drm_printer;
        param(unsigned int, inject_load_failure, 0) \
        /* leave bools at the end to not create holes */ \
        param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \
-       param(bool, enable_cmd_parser, true) \
        param(bool, enable_hangcheck, true) \
        param(bool, fastboot, false) \
        param(bool, prefault_disable, false) \
index 4364922e935d3380c07e7c998f3fba8c5368f645..97a91e6af7e3c5dcd6cce1d792d1fc23f9ee6cb9 100644 (file)
@@ -340,7 +340,6 @@ static const struct intel_device_info intel_valleyview_info = {
        GEN(7),
        .is_lp = 1,
        .num_pipes = 2,
-       .has_psr = 1,
        .has_runtime_pm = 1,
        .has_rc6 = 1,
        .has_gmch_display = 1,
@@ -433,7 +432,6 @@ static const struct intel_device_info intel_cherryview_info = {
        .is_lp = 1,
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
        .has_64bit_reloc = 1,
-       .has_psr = 1,
        .has_runtime_pm = 1,
        .has_resource_streamer = 1,
        .has_rc6 = 1,
index 019bd2d073ad4461b0660f60e0a696e6af203ed7..a6c8d61add0cd58f2e259422f185b4cf6497c2bc 100644 (file)
@@ -737,12 +737,7 @@ static int gen8_append_oa_reports(struct i915_perf_stream *stream,
                        continue;
                }
 
-               /*
-                * XXX: Just keep the lower 21 bits for now since I'm not
-                * entirely sure if the HW touches any of the higher bits in
-                * this field
-                */
-               ctx_id = report32[2] & 0x1fffff;
+               ctx_id = report32[2] & dev_priv->perf.oa.specific_ctx_id_mask;
 
                /*
                 * Squash whatever is in the CTX_ID field if it's marked as
@@ -1203,6 +1198,33 @@ static int i915_oa_read(struct i915_perf_stream *stream,
        return dev_priv->perf.oa.ops.read(stream, buf, count, offset);
 }
 
+static struct intel_context *oa_pin_context(struct drm_i915_private *i915,
+                                           struct i915_gem_context *ctx)
+{
+       struct intel_engine_cs *engine = i915->engine[RCS];
+       struct intel_context *ce;
+       int ret;
+
+       ret = i915_mutex_lock_interruptible(&i915->drm);
+       if (ret)
+               return ERR_PTR(ret);
+
+       /*
+        * As the ID is the gtt offset of the context's vma we
+        * pin the vma to ensure the ID remains fixed.
+        *
+        * NB: implied RCS engine...
+        */
+       ce = intel_context_pin(ctx, engine);
+       mutex_unlock(&i915->drm.struct_mutex);
+       if (IS_ERR(ce))
+               return ce;
+
+       i915->perf.oa.pinned_ctx = ce;
+
+       return ce;
+}
+
 /**
  * oa_get_render_ctx_id - determine and hold ctx hw id
  * @stream: An i915-perf stream opened for OA metrics
@@ -1215,40 +1237,76 @@ static int i915_oa_read(struct i915_perf_stream *stream,
  */
 static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 {
-       struct drm_i915_private *dev_priv = stream->dev_priv;
+       struct drm_i915_private *i915 = stream->dev_priv;
+       struct intel_context *ce;
 
-       if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
-               dev_priv->perf.oa.specific_ctx_id = stream->ctx->hw_id;
-       } else {
-               struct intel_engine_cs *engine = dev_priv->engine[RCS];
-               struct intel_ring *ring;
-               int ret;
-
-               ret = i915_mutex_lock_interruptible(&dev_priv->drm);
-               if (ret)
-                       return ret;
+       ce = oa_pin_context(i915, stream->ctx);
+       if (IS_ERR(ce))
+               return PTR_ERR(ce);
 
+       switch (INTEL_GEN(i915)) {
+       case 7: {
                /*
-                * As the ID is the gtt offset of the context's vma we
-                * pin the vma to ensure the ID remains fixed.
-                *
-                * NB: implied RCS engine...
+                * On Haswell we don't do any post processing of the reports
+                * and don't need to use the mask.
                 */
-               ring = intel_context_pin(stream->ctx, engine);
-               mutex_unlock(&dev_priv->drm.struct_mutex);
-               if (IS_ERR(ring))
-                       return PTR_ERR(ring);
+               i915->perf.oa.specific_ctx_id = i915_ggtt_offset(ce->state);
+               i915->perf.oa.specific_ctx_id_mask = 0;
+               break;
+       }
 
+       case 8:
+       case 9:
+       case 10:
+               if (USES_GUC_SUBMISSION(i915)) {
+                       /*
+                        * When using GuC, the context descriptor we write in
+                        * i915 is read by GuC and rewritten before it's
+                        * actually written into the hardware. The LRCA is
+                        * what is put into the context id field of the
+                        * context descriptor by GuC. Because it's aligned to
+                        * a page, the lower 12bits are always at 0 and
+                        * dropped by GuC. They won't be part of the context
+                        * ID in the OA reports, so squash those lower bits.
+                        */
+                       i915->perf.oa.specific_ctx_id =
+                               lower_32_bits(ce->lrc_desc) >> 12;
 
-               /*
-                * Explicitly track the ID (instead of calling
-                * i915_ggtt_offset() on the fly) considering the difference
-                * with gen8+ and execlists
-                */
-               dev_priv->perf.oa.specific_ctx_id =
-                       i915_ggtt_offset(to_intel_context(stream->ctx, engine)->state);
+                       /*
+                        * GuC uses the top bit to signal proxy submission, so
+                        * ignore that bit.
+                        */
+                       i915->perf.oa.specific_ctx_id_mask =
+                               (1U << (GEN8_CTX_ID_WIDTH - 1)) - 1;
+               } else {
+                       i915->perf.oa.specific_ctx_id = stream->ctx->hw_id;
+                       i915->perf.oa.specific_ctx_id_mask =
+                               (1U << GEN8_CTX_ID_WIDTH) - 1;
+               }
+               break;
+
+       case 11: {
+               struct intel_engine_cs *engine = i915->engine[RCS];
+
+               i915->perf.oa.specific_ctx_id =
+                       stream->ctx->hw_id << (GEN11_SW_CTX_ID_SHIFT - 32) |
+                       engine->instance << (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
+                       engine->class << (GEN11_ENGINE_INSTANCE_SHIFT - 32);
+               i915->perf.oa.specific_ctx_id_mask =
+                       ((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32) |
+                       ((1U << GEN11_ENGINE_INSTANCE_WIDTH) - 1) << (GEN11_ENGINE_INSTANCE_SHIFT - 32) |
+                       ((1 << GEN11_ENGINE_CLASS_WIDTH) - 1) << (GEN11_ENGINE_CLASS_SHIFT - 32);
+               break;
+       }
+
+       default:
+               MISSING_CASE(INTEL_GEN(i915));
        }
 
+       DRM_DEBUG_DRIVER("filtering on ctx_id=0x%x ctx_id_mask=0x%x\n",
+                        i915->perf.oa.specific_ctx_id,
+                        i915->perf.oa.specific_ctx_id_mask);
+
        return 0;
 }
 
@@ -1262,17 +1320,15 @@ static int oa_get_render_ctx_id(struct i915_perf_stream *stream)
 static void oa_put_render_ctx_id(struct i915_perf_stream *stream)
 {
        struct drm_i915_private *dev_priv = stream->dev_priv;
+       struct intel_context *ce;
 
-       if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) {
-               dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
-       } else {
-               struct intel_engine_cs *engine = dev_priv->engine[RCS];
+       dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
+       dev_priv->perf.oa.specific_ctx_id_mask = 0;
 
+       ce = fetch_and_zero(&dev_priv->perf.oa.pinned_ctx);
+       if (ce) {
                mutex_lock(&dev_priv->drm.struct_mutex);
-
-               dev_priv->perf.oa.specific_ctx_id = INVALID_CTX_ID;
-               intel_context_unpin(stream->ctx, engine);
-
+               intel_context_unpin(ce);
                mutex_unlock(&dev_priv->drm.struct_mutex);
        }
 }
index dc87797db500517b8ada97d92acf5d6f399b3bd5..c39541ed2219482c17814b9f3190b75f6be3c75d 100644 (file)
@@ -127,6 +127,7 @@ static void __i915_pmu_maybe_start_timer(struct drm_i915_private *i915)
 {
        if (!i915->pmu.timer_enabled && pmu_needs_timer(i915, true)) {
                i915->pmu.timer_enabled = true;
+               i915->pmu.timer_last = ktime_get();
                hrtimer_start_range_ns(&i915->pmu.timer,
                                       ns_to_ktime(PERIOD), 0,
                                       HRTIMER_MODE_REL_PINNED);
@@ -155,12 +156,13 @@ static bool grab_forcewake(struct drm_i915_private *i915, bool fw)
 }
 
 static void
-update_sample(struct i915_pmu_sample *sample, u32 unit, u32 val)
+add_sample(struct i915_pmu_sample *sample, u32 val)
 {
-       sample->cur += mul_u32_u32(val, unit);
+       sample->cur += val;
 }
 
-static void engines_sample(struct drm_i915_private *dev_priv)
+static void
+engines_sample(struct drm_i915_private *dev_priv, unsigned int period_ns)
 {
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
@@ -182,8 +184,9 @@ static void engines_sample(struct drm_i915_private *dev_priv)
 
                val = !i915_seqno_passed(current_seqno, last_seqno);
 
-               update_sample(&engine->pmu.sample[I915_SAMPLE_BUSY],
-                             PERIOD, val);
+               if (val)
+                       add_sample(&engine->pmu.sample[I915_SAMPLE_BUSY],
+                                  period_ns);
 
                if (val && (engine->pmu.enable &
                    (BIT(I915_SAMPLE_WAIT) | BIT(I915_SAMPLE_SEMA)))) {
@@ -194,11 +197,13 @@ static void engines_sample(struct drm_i915_private *dev_priv)
                        val = 0;
                }
 
-               update_sample(&engine->pmu.sample[I915_SAMPLE_WAIT],
-                             PERIOD, !!(val & RING_WAIT));
+               if (val & RING_WAIT)
+                       add_sample(&engine->pmu.sample[I915_SAMPLE_WAIT],
+                                  period_ns);
 
-               update_sample(&engine->pmu.sample[I915_SAMPLE_SEMA],
-                             PERIOD, !!(val & RING_WAIT_SEMAPHORE));
+               if (val & RING_WAIT_SEMAPHORE)
+                       add_sample(&engine->pmu.sample[I915_SAMPLE_SEMA],
+                                  period_ns);
        }
 
        if (fw)
@@ -207,7 +212,14 @@ static void engines_sample(struct drm_i915_private *dev_priv)
        intel_runtime_pm_put(dev_priv);
 }
 
-static void frequency_sample(struct drm_i915_private *dev_priv)
+static void
+add_sample_mult(struct i915_pmu_sample *sample, u32 val, u32 mul)
+{
+       sample->cur += mul_u32_u32(val, mul);
+}
+
+static void
+frequency_sample(struct drm_i915_private *dev_priv, unsigned int period_ns)
 {
        if (dev_priv->pmu.enable &
            config_enabled_mask(I915_PMU_ACTUAL_FREQUENCY)) {
@@ -221,15 +233,17 @@ static void frequency_sample(struct drm_i915_private *dev_priv)
                        intel_runtime_pm_put(dev_priv);
                }
 
-               update_sample(&dev_priv->pmu.sample[__I915_SAMPLE_FREQ_ACT],
-                             1, intel_gpu_freq(dev_priv, val));
+               add_sample_mult(&dev_priv->pmu.sample[__I915_SAMPLE_FREQ_ACT],
+                               intel_gpu_freq(dev_priv, val),
+                               period_ns / 1000);
        }
 
        if (dev_priv->pmu.enable &
            config_enabled_mask(I915_PMU_REQUESTED_FREQUENCY)) {
-               update_sample(&dev_priv->pmu.sample[__I915_SAMPLE_FREQ_REQ], 1,
-                             intel_gpu_freq(dev_priv,
-                                            dev_priv->gt_pm.rps.cur_freq));
+               add_sample_mult(&dev_priv->pmu.sample[__I915_SAMPLE_FREQ_REQ],
+                               intel_gpu_freq(dev_priv,
+                                              dev_priv->gt_pm.rps.cur_freq),
+                               period_ns / 1000);
        }
 }
 
@@ -237,14 +251,27 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
 {
        struct drm_i915_private *i915 =
                container_of(hrtimer, struct drm_i915_private, pmu.timer);
+       unsigned int period_ns;
+       ktime_t now;
 
        if (!READ_ONCE(i915->pmu.timer_enabled))
                return HRTIMER_NORESTART;
 
-       engines_sample(i915);
-       frequency_sample(i915);
+       now = ktime_get();
+       period_ns = ktime_to_ns(ktime_sub(now, i915->pmu.timer_last));
+       i915->pmu.timer_last = now;
+
+       /*
+        * Strictly speaking the passed in period may not be 100% accurate for
+        * all internal calculation, since some amount of time can be spent on
+        * grabbing the forcewake. However the potential error from timer call-
+        * back delay greatly dominates this so we keep it simple.
+        */
+       engines_sample(i915, period_ns);
+       frequency_sample(i915, period_ns);
+
+       hrtimer_forward(hrtimer, now, ns_to_ktime(PERIOD));
 
-       hrtimer_forward_now(hrtimer, ns_to_ktime(PERIOD));
        return HRTIMER_RESTART;
 }
 
@@ -519,12 +546,12 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
                case I915_PMU_ACTUAL_FREQUENCY:
                        val =
                           div_u64(i915->pmu.sample[__I915_SAMPLE_FREQ_ACT].cur,
-                                  FREQUENCY);
+                                  USEC_PER_SEC /* to MHz */);
                        break;
                case I915_PMU_REQUESTED_FREQUENCY:
                        val =
                           div_u64(i915->pmu.sample[__I915_SAMPLE_FREQ_REQ].cur,
-                                  FREQUENCY);
+                                  USEC_PER_SEC /* to MHz */);
                        break;
                case I915_PMU_INTERRUPTS:
                        val = count_interrupts(i915);
index 2ba735299f7c5815ac3803ec62525802ab0950b2..7f164ca3db129472d3262439f5290d505ea6e14a 100644 (file)
@@ -65,6 +65,14 @@ struct i915_pmu {
         * event types.
         */
        u64 enable;
+
+       /**
+        * @timer_last:
+        *
+        * Timestmap of the previous timer invocation.
+        */
+       ktime_t timer_last;
+
        /**
         * @enable_count: Reference counts for the enabled events.
         *
index 195203f298dfcfdc03f91b529af65f8e6337aad9..55bde4a0228969c3bbb9d153b01101edbdc919d8 100644 (file)
@@ -54,6 +54,7 @@ enum vgt_g2v_type {
  */
 #define VGT_CAPS_FULL_48BIT_PPGTT      BIT(2)
 #define VGT_CAPS_HWSP_EMULATION                BIT(3)
+#define VGT_CAPS_HUGE_GTT              BIT(4)
 
 struct vgt_if {
        u64 magic;              /* VGT_MAGIC */
index f11bb213ec0784e4c50db5bd0ea0647a5419e0e1..f0317bde3aabc130287b3e19e5a901ed330bbebf 100644 (file)
@@ -1990,6 +1990,11 @@ enum i915_power_well_id {
                                                   _ICL_PORT_COMP_DW10_A, \
                                                   _ICL_PORT_COMP_DW10_B)
 
+/* ICL PHY DFLEX registers */
+#define PORT_TX_DFLEXDPMLE1            _MMIO(0x1638C0)
+#define   DFLEXDPMLE1_DPMLETC_MASK(n)  (0xf << (4 * (n)))
+#define   DFLEXDPMLE1_DPMLETC(n, x)    ((x) << (4 * (n)))
+
 /* BXT PHY Ref registers */
 #define _PORT_REF_DW3_A                        0x16218C
 #define _PORT_REF_DW3_BC               0x6C18C
@@ -2306,8 +2311,9 @@ enum i915_power_well_id {
 #define   GAMW_ECO_ENABLE_64K_IPS_FIELD 0xF
 
 #define GAMT_CHKN_BIT_REG      _MMIO(0x4ab8)
-#define   GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING     (1<<28)
-#define   GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT       (1<<24)
+#define   GAMT_CHKN_DISABLE_L3_COH_PIPE                        (1 << 31)
+#define   GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING     (1 << 28)
+#define   GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT       (1 << 24)
 
 #if 0
 #define PRB0_TAIL      _MMIO(0x2030)
@@ -2663,6 +2669,9 @@ enum i915_power_well_id {
 #define   GEN8_4x4_STC_OPTIMIZATION_DISABLE    (1<<6)
 #define   GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE   (1<<1)
 
+#define GEN10_CACHE_MODE_SS                    _MMIO(0xe420)
+#define   FLOAT_BLEND_OPTIMIZATION_ENABLE      (1 << 4)
+
 #define GEN6_BLITTER_ECOSKPD   _MMIO(0x221d0)
 #define   GEN6_BLITTER_LOCK_SHIFT                      16
 #define   GEN6_BLITTER_FBC_NOTIFY                      (1<<3)
@@ -2709,6 +2718,10 @@ enum i915_power_well_id {
 #define   GEN10_F2_SS_DIS_SHIFT                18
 #define   GEN10_F2_SS_DIS_MASK         (0xf << GEN10_F2_SS_DIS_SHIFT)
 
+#define        GEN10_MIRROR_FUSE3              _MMIO(0x9118)
+#define GEN10_L3BANK_PAIR_COUNT     4
+#define GEN10_L3BANK_MASK   0x0F
+
 #define GEN8_EU_DISABLE0               _MMIO(0x9134)
 #define   GEN8_EU_DIS0_S0_MASK         0xffffff
 #define   GEN8_EU_DIS0_S1_SHIFT                24
@@ -4088,10 +4101,10 @@ enum {
 #define   EDP_Y_COORDINATE_ENABLE      (1<<25) /* GLK and CNL+ */
 #define   EDP_MAX_SU_DISABLE_TIME(t)   ((t)<<20)
 #define   EDP_MAX_SU_DISABLE_TIME_MASK (0x1f<<20)
-#define   EDP_PSR2_TP2_TIME_500                (0<<8)
-#define   EDP_PSR2_TP2_TIME_100                (1<<8)
-#define   EDP_PSR2_TP2_TIME_2500       (2<<8)
-#define   EDP_PSR2_TP2_TIME_50         (3<<8)
+#define   EDP_PSR2_TP2_TIME_500us      (0<<8)
+#define   EDP_PSR2_TP2_TIME_100us      (1<<8)
+#define   EDP_PSR2_TP2_TIME_2500us     (2<<8)
+#define   EDP_PSR2_TP2_TIME_50us       (3<<8)
 #define   EDP_PSR2_TP2_TIME_MASK       (3<<8)
 #define   EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4
 #define   EDP_PSR2_FRAME_BEFORE_SU_MASK        (0xf<<4)
@@ -4133,11 +4146,12 @@ enum {
 
 #define   ADPA_DAC_ENABLE      (1<<31)
 #define   ADPA_DAC_DISABLE     0
-#define   ADPA_PIPE_SELECT_MASK        (1<<30)
-#define   ADPA_PIPE_A_SELECT   0
-#define   ADPA_PIPE_B_SELECT   (1<<30)
-#define   ADPA_PIPE_SELECT(pipe) ((pipe) << 30)
-/* CPT uses bits 29:30 for pch transcoder select */
+#define   ADPA_PIPE_SEL_SHIFT          30
+#define   ADPA_PIPE_SEL_MASK           (1<<30)
+#define   ADPA_PIPE_SEL(pipe)          ((pipe) << 30)
+#define   ADPA_PIPE_SEL_SHIFT_CPT      29
+#define   ADPA_PIPE_SEL_MASK_CPT       (3<<29)
+#define   ADPA_PIPE_SEL_CPT(pipe)      ((pipe) << 29)
 #define   ADPA_CRT_HOTPLUG_MASK  0x03ff0000 /* bit 25-16 */
 #define   ADPA_CRT_HOTPLUG_MONITOR_NONE  (0<<24)
 #define   ADPA_CRT_HOTPLUG_MONITOR_MASK  (3<<24)
@@ -4296,9 +4310,9 @@ enum {
 
 /* Gen 3 SDVO bits: */
 #define   SDVO_ENABLE                          (1 << 31)
-#define   SDVO_PIPE_SEL(pipe)                  ((pipe) << 30)
+#define   SDVO_PIPE_SEL_SHIFT                  30
 #define   SDVO_PIPE_SEL_MASK                   (1 << 30)
-#define   SDVO_PIPE_B_SELECT                   (1 << 30)
+#define   SDVO_PIPE_SEL(pipe)                  ((pipe) << 30)
 #define   SDVO_STALL_SELECT                    (1 << 29)
 #define   SDVO_INTERRUPT_ENABLE                        (1 << 26)
 /*
@@ -4338,12 +4352,14 @@ enum {
 #define   SDVOB_HOTPLUG_ENABLE                 (1 << 23) /* SDVO only */
 
 /* Gen 6 (CPT) SDVO/HDMI bits: */
-#define   SDVO_PIPE_SEL_CPT(pipe)              ((pipe) << 29)
+#define   SDVO_PIPE_SEL_SHIFT_CPT              29
 #define   SDVO_PIPE_SEL_MASK_CPT               (3 << 29)
+#define   SDVO_PIPE_SEL_CPT(pipe)              ((pipe) << 29)
 
 /* CHV SDVO/HDMI bits: */
-#define   SDVO_PIPE_SEL_CHV(pipe)              ((pipe) << 24)
+#define   SDVO_PIPE_SEL_SHIFT_CHV              24
 #define   SDVO_PIPE_SEL_MASK_CHV               (3 << 24)
+#define   SDVO_PIPE_SEL_CHV(pipe)              ((pipe) << 24)
 
 
 /* DVO port control */
@@ -4354,7 +4370,9 @@ enum {
 #define _DVOC                  0x61160
 #define DVOC                   _MMIO(_DVOC)
 #define   DVO_ENABLE                   (1 << 31)
-#define   DVO_PIPE_B_SELECT            (1 << 30)
+#define   DVO_PIPE_SEL_SHIFT           30
+#define   DVO_PIPE_SEL_MASK            (1 << 30)
+#define   DVO_PIPE_SEL(pipe)           ((pipe) << 30)
 #define   DVO_PIPE_STALL_UNUSED                (0 << 28)
 #define   DVO_PIPE_STALL               (1 << 28)
 #define   DVO_PIPE_STALL_TV            (2 << 28)
@@ -4391,9 +4409,12 @@ enum {
  */
 #define   LVDS_PORT_EN                 (1 << 31)
 /* Selects pipe B for LVDS data.  Must be set on pre-965. */
-#define   LVDS_PIPEB_SELECT            (1 << 30)
-#define   LVDS_PIPE_MASK               (1 << 30)
-#define   LVDS_PIPE(pipe)              ((pipe) << 30)
+#define   LVDS_PIPE_SEL_SHIFT          30
+#define   LVDS_PIPE_SEL_MASK           (1 << 30)
+#define   LVDS_PIPE_SEL(pipe)          ((pipe) << 30)
+#define   LVDS_PIPE_SEL_SHIFT_CPT      29
+#define   LVDS_PIPE_SEL_MASK_CPT       (3 << 29)
+#define   LVDS_PIPE_SEL_CPT(pipe)      ((pipe) << 29)
 /* LVDS dithering flag on 965/g4x platform */
 #define   LVDS_ENABLE_DITHER           (1 << 25)
 /* LVDS sync polarity flags. Set to invert (i.e. negative) */
@@ -4690,7 +4711,9 @@ enum {
 /* Enables the TV encoder */
 # define TV_ENC_ENABLE                 (1 << 31)
 /* Sources the TV encoder input from pipe B instead of A. */
-# define TV_ENC_PIPEB_SELECT           (1 << 30)
+# define TV_ENC_PIPE_SEL_SHIFT         30
+# define TV_ENC_PIPE_SEL_MASK          (1 << 30)
+# define TV_ENC_PIPE_SEL(pipe)         ((pipe) << 30)
 /* Outputs composite video (DAC A only) */
 # define TV_ENC_OUTPUT_COMPOSITE       (0 << 28)
 /* Outputs SVideo video (DAC B/C) */
@@ -5172,10 +5195,15 @@ enum {
 #define CHV_DP_D               _MMIO(VLV_DISPLAY_BASE + 0x64300)
 
 #define   DP_PORT_EN                   (1 << 31)
-#define   DP_PIPEB_SELECT              (1 << 30)
-#define   DP_PIPE_MASK                 (1 << 30)
-#define   DP_PIPE_SELECT_CHV(pipe)     ((pipe) << 16)
-#define   DP_PIPE_MASK_CHV             (3 << 16)
+#define   DP_PIPE_SEL_SHIFT            30
+#define   DP_PIPE_SEL_MASK             (1 << 30)
+#define   DP_PIPE_SEL(pipe)            ((pipe) << 30)
+#define   DP_PIPE_SEL_SHIFT_IVB                29
+#define   DP_PIPE_SEL_MASK_IVB         (3 << 29)
+#define   DP_PIPE_SEL_IVB(pipe)                ((pipe) << 29)
+#define   DP_PIPE_SEL_SHIFT_CHV                16
+#define   DP_PIPE_SEL_MASK_CHV         (3 << 16)
+#define   DP_PIPE_SEL_CHV(pipe)                ((pipe) << 16)
 
 /* Link training mode - select a suitable mode for each stage */
 #define   DP_LINK_TRAIN_PAT_1          (0 << 28)
@@ -5896,7 +5924,6 @@ enum {
 #define   CURSOR_GAMMA_ENABLE  0x40000000
 #define   CURSOR_STRIDE_SHIFT  28
 #define   CURSOR_STRIDE(x)     ((ffs(x)-9) << CURSOR_STRIDE_SHIFT) /* 256,512,1k,2k */
-#define   CURSOR_PIPE_CSC_ENABLE (1<<24)
 #define   CURSOR_FORMAT_SHIFT  24
 #define   CURSOR_FORMAT_MASK   (0x07 << CURSOR_FORMAT_SHIFT)
 #define   CURSOR_FORMAT_2C     (0x00 << CURSOR_FORMAT_SHIFT)
@@ -5905,18 +5932,21 @@ enum {
 #define   CURSOR_FORMAT_ARGB   (0x04 << CURSOR_FORMAT_SHIFT)
 #define   CURSOR_FORMAT_XRGB   (0x05 << CURSOR_FORMAT_SHIFT)
 /* New style CUR*CNTR flags */
-#define   CURSOR_MODE          0x27
-#define   CURSOR_MODE_DISABLE   0x00
-#define   CURSOR_MODE_128_32B_AX 0x02
-#define   CURSOR_MODE_256_32B_AX 0x03
-#define   CURSOR_MODE_64_32B_AX 0x07
-#define   CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX)
-#define   CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX)
-#define   CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define   MCURSOR_MODE         0x27
+#define   MCURSOR_MODE_DISABLE   0x00
+#define   MCURSOR_MODE_128_32B_AX 0x02
+#define   MCURSOR_MODE_256_32B_AX 0x03
+#define   MCURSOR_MODE_64_32B_AX 0x07
+#define   MCURSOR_MODE_128_ARGB_AX ((1 << 5) | MCURSOR_MODE_128_32B_AX)
+#define   MCURSOR_MODE_256_ARGB_AX ((1 << 5) | MCURSOR_MODE_256_32B_AX)
+#define   MCURSOR_MODE_64_ARGB_AX ((1 << 5) | MCURSOR_MODE_64_32B_AX)
+#define   MCURSOR_PIPE_SELECT_MASK     (0x3 << 28)
+#define   MCURSOR_PIPE_SELECT_SHIFT    28
 #define   MCURSOR_PIPE_SELECT(pipe)    ((pipe) << 28)
 #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
-#define   CURSOR_ROTATE_180    (1<<15)
-#define   CURSOR_TRICKLE_FEED_DISABLE  (1 << 14)
+#define   MCURSOR_PIPE_CSC_ENABLE (1<<24)
+#define   MCURSOR_ROTATE_180   (1<<15)
+#define   MCURSOR_TRICKLE_FEED_DISABLE (1 << 14)
 #define _CURABASE              0x70084
 #define _CURAPOS               0x70088
 #define   CURSOR_POS_MASK       0x007FF
@@ -6764,6 +6794,10 @@ enum {
 #define _PS_VPHASE_1B       0x68988
 #define _PS_VPHASE_2B       0x68A88
 #define _PS_VPHASE_1C       0x69188
+#define  PS_Y_PHASE(x)         ((x) << 16)
+#define  PS_UV_RGB_PHASE(x)    ((x) << 0)
+#define   PS_PHASE_MASK        (0x7fff << 1) /* u2.13 */
+#define   PS_PHASE_TRIP        (1 << 0)
 
 #define _PS_HPHASE_1A       0x68194
 #define _PS_HPHASE_2A       0x68294
@@ -7192,13 +7226,17 @@ enum {
 
 /* GEN7 chicken */
 #define GEN7_COMMON_SLICE_CHICKEN1             _MMIO(0x7010)
-# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC     ((1<<10) | (1<<26))
-# define GEN9_RHWO_OPTIMIZATION_DISABLE                (1<<14)
-#define COMMON_SLICE_CHICKEN2                  _MMIO(0x7014)
-# define GEN9_PBE_COMPRESSED_HASH_SELECTION    (1<<13)
-# define GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE (1<<12)
-# define GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION (1<<8)
-# define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE  (1<<0)
+  #define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC    ((1 << 10) | (1 << 26))
+  #define GEN9_RHWO_OPTIMIZATION_DISABLE       (1 << 14)
+
+#define COMMON_SLICE_CHICKEN2                                  _MMIO(0x7014)
+  #define GEN9_PBE_COMPRESSED_HASH_SELECTION                   (1 << 13)
+  #define GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE       (1 << 12)
+  #define GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION             (1 << 8)
+  #define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE                 (1 << 0)
+
+#define GEN11_COMMON_SLICE_CHICKEN3            _MMIO(0x7304)
+  #define GEN11_BLEND_EMB_FIX_DISABLE_IN_RCC   (1 << 11)
 
 #define HIZ_CHICKEN                                    _MMIO(0x7018)
 # define CHV_HZ_8X8_MODE_IN_1X                         (1<<15)
@@ -7208,6 +7246,7 @@ enum {
 #define  DISABLE_PIXEL_MASK_CAMMING            (1<<14)
 
 #define GEN9_SLICE_COMMON_ECO_CHICKEN1         _MMIO(0x731c)
+#define   GEN11_STATE_CACHE_REDIRECT_TO_CS     (1 << 11)
 
 #define GEN7_L3SQCREG1                         _MMIO(0xB010)
 #define  VLV_B0_WA_L3SQCREG1_VALUE             0x00D30000
@@ -7862,27 +7901,14 @@ enum {
 #define PCH_DP_AUX_CH_DATA(aux_ch, i)  _MMIO(_PORT((aux_ch) - AUX_CH_B, _PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
 
 /* CPT */
-#define  PORT_TRANS_A_SEL_CPT  0
-#define  PORT_TRANS_B_SEL_CPT  (1<<29)
-#define  PORT_TRANS_C_SEL_CPT  (2<<29)
-#define  PORT_TRANS_SEL_MASK   (3<<29)
-#define  PORT_TRANS_SEL_CPT(pipe)      ((pipe) << 29)
-#define  PORT_TO_PIPE(val)     (((val) & (1<<30)) >> 30)
-#define  PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29)
-#define  SDVO_PORT_TO_PIPE_CHV(val)    (((val) & (3<<24)) >> 24)
-#define  DP_PORT_TO_PIPE_CHV(val)      (((val) & (3<<16)) >> 16)
-
 #define _TRANS_DP_CTL_A                0xe0300
 #define _TRANS_DP_CTL_B                0xe1300
 #define _TRANS_DP_CTL_C                0xe2300
 #define TRANS_DP_CTL(pipe)     _MMIO_PIPE(pipe, _TRANS_DP_CTL_A, _TRANS_DP_CTL_B)
 #define  TRANS_DP_OUTPUT_ENABLE        (1<<31)
-#define  TRANS_DP_PORT_SEL_B   (0<<29)
-#define  TRANS_DP_PORT_SEL_C   (1<<29)
-#define  TRANS_DP_PORT_SEL_D   (2<<29)
-#define  TRANS_DP_PORT_SEL_NONE        (3<<29)
-#define  TRANS_DP_PORT_SEL_MASK        (3<<29)
-#define  TRANS_DP_PIPE_TO_PORT(val)    ((((val) & TRANS_DP_PORT_SEL_MASK) >> 29) + PORT_B)
+#define  TRANS_DP_PORT_SEL_MASK                (3 << 29)
+#define  TRANS_DP_PORT_SEL_NONE                (3 << 29)
+#define  TRANS_DP_PORT_SEL(port)       (((port) - PORT_B) << 29)
 #define  TRANS_DP_AUDIO_ONLY   (1<<26)
 #define  TRANS_DP_ENH_FRAMING  (1<<18)
 #define  TRANS_DP_8BPC         (0<<9)
@@ -8322,8 +8348,9 @@ enum {
 
 #define GEN7_ROW_CHICKEN2              _MMIO(0xe4f4)
 #define GEN7_ROW_CHICKEN2_GT2          _MMIO(0xf4f4)
-#define   DOP_CLOCK_GATING_DISABLE     (1<<0)
-#define   PUSH_CONSTANT_DEREF_DISABLE  (1<<8)
+#define   DOP_CLOCK_GATING_DISABLE     (1 << 0)
+#define   PUSH_CONSTANT_DEREF_DISABLE  (1 << 8)
+#define   GEN11_TDL_CLOCK_GATING_FIX_DISABLE   (1 << 1)
 
 #define HSW_ROW_CHICKEN3               _MMIO(0xe49c)
 #define  HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE    (1 << 6)
@@ -9100,13 +9127,16 @@ enum skl_power_gate {
 #define  DPLL_CFGCR1_QDIV_RATIO_MASK   (0xff << 10)
 #define  DPLL_CFGCR1_QDIV_RATIO_SHIFT  (10)
 #define  DPLL_CFGCR1_QDIV_RATIO(x)     ((x) << 10)
+#define  DPLL_CFGCR1_QDIV_MODE_SHIFT   (9)
 #define  DPLL_CFGCR1_QDIV_MODE(x)      ((x) << 9)
 #define  DPLL_CFGCR1_KDIV_MASK         (7 << 6)
+#define  DPLL_CFGCR1_KDIV_SHIFT                (6)
 #define  DPLL_CFGCR1_KDIV(x)           ((x) << 6)
 #define  DPLL_CFGCR1_KDIV_1            (1 << 6)
 #define  DPLL_CFGCR1_KDIV_2            (2 << 6)
 #define  DPLL_CFGCR1_KDIV_4            (4 << 6)
 #define  DPLL_CFGCR1_PDIV_MASK         (0xf << 2)
+#define  DPLL_CFGCR1_PDIV_SHIFT                (2)
 #define  DPLL_CFGCR1_PDIV(x)           ((x) << 2)
 #define  DPLL_CFGCR1_PDIV_2            (1 << 2)
 #define  DPLL_CFGCR1_PDIV_3            (2 << 2)
index 8928894dd9c77d1b1aa4d28c5a0ab06ec4b83a25..f187250e60c6f56bd1f349284f00be9478fe8073 100644 (file)
@@ -320,6 +320,7 @@ static void advance_ring(struct i915_request *request)
                 * is just about to be. Either works, if we miss the last two
                 * noops - they are safe to be replayed on a reset.
                 */
+               GEM_TRACE("marking %s as inactive\n", ring->timeline->name);
                tail = READ_ONCE(request->tail);
                list_del(&ring->active_link);
        } else {
@@ -383,8 +384,8 @@ static void __retire_engine_request(struct intel_engine_cs *engine,
         * the subsequent request.
         */
        if (engine->last_retired_context)
-               intel_context_unpin(engine->last_retired_context, engine);
-       engine->last_retired_context = rq->ctx;
+               intel_context_unpin(engine->last_retired_context);
+       engine->last_retired_context = rq->hw_context;
 }
 
 static void __retire_engine_upto(struct intel_engine_cs *engine,
@@ -455,8 +456,8 @@ static void i915_request_retire(struct i915_request *request)
        i915_request_remove_from_client(request);
 
        /* Retirement decays the ban score as it is a sign of ctx progress */
-       atomic_dec_if_positive(&request->ctx->ban_score);
-       intel_context_unpin(request->ctx, request->engine);
+       atomic_dec_if_positive(&request->gem_context->ban_score);
+       intel_context_unpin(request->hw_context);
 
        __retire_engine_upto(request->engine, request);
 
@@ -657,7 +658,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 {
        struct drm_i915_private *i915 = engine->i915;
        struct i915_request *rq;
-       struct intel_ring *ring;
+       struct intel_context *ce;
        int ret;
 
        lockdep_assert_held(&i915->drm.struct_mutex);
@@ -681,22 +682,21 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
         * GGTT space, so do this first before we reserve a seqno for
         * ourselves.
         */
-       ring = intel_context_pin(ctx, engine);
-       if (IS_ERR(ring))
-               return ERR_CAST(ring);
-       GEM_BUG_ON(!ring);
+       ce = intel_context_pin(ctx, engine);
+       if (IS_ERR(ce))
+               return ERR_CAST(ce);
 
        ret = reserve_gt(i915);
        if (ret)
                goto err_unpin;
 
-       ret = intel_ring_wait_for_space(ring, MIN_SPACE_FOR_ADD_REQUEST);
+       ret = intel_ring_wait_for_space(ce->ring, MIN_SPACE_FOR_ADD_REQUEST);
        if (ret)
                goto err_unreserve;
 
        /* Move our oldest request to the slab-cache (if not in use!) */
-       rq = list_first_entry(&ring->request_list, typeof(*rq), ring_link);
-       if (!list_is_last(&rq->ring_link, &ring->request_list) &&
+       rq = list_first_entry(&ce->ring->request_list, typeof(*rq), ring_link);
+       if (!list_is_last(&rq->ring_link, &ce->ring->request_list) &&
            i915_request_completed(rq))
                i915_request_retire(rq);
 
@@ -760,9 +760,10 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
        INIT_LIST_HEAD(&rq->active_list);
        rq->i915 = i915;
        rq->engine = engine;
-       rq->ctx = ctx;
-       rq->ring = ring;
-       rq->timeline = ring->timeline;
+       rq->gem_context = ctx;
+       rq->hw_context = ce;
+       rq->ring = ce->ring;
+       rq->timeline = ce->ring->timeline;
        GEM_BUG_ON(rq->timeline == &engine->timeline);
 
        spin_lock_init(&rq->lock);
@@ -814,14 +815,14 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
                goto err_unwind;
 
        /* Keep a second pin for the dual retirement along engine and ring */
-       __intel_context_pin(rq->ctx, engine);
+       __intel_context_pin(ce);
 
        /* Check that we didn't interrupt ourselves with a new request */
        GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno);
        return rq;
 
 err_unwind:
-       rq->ring->emit = rq->head;
+       ce->ring->emit = rq->head;
 
        /* Make sure we didn't add ourselves to external state before freeing */
        GEM_BUG_ON(!list_empty(&rq->active_list));
@@ -832,7 +833,7 @@ err_unwind:
 err_unreserve:
        unreserve_gt(i915);
 err_unpin:
-       intel_context_unpin(ctx, engine);
+       intel_context_unpin(ce);
        return ERR_PTR(ret);
 }
 
@@ -1018,8 +1019,8 @@ i915_request_await_object(struct i915_request *to,
 void __i915_request_add(struct i915_request *request, bool flush_caches)
 {
        struct intel_engine_cs *engine = request->engine;
-       struct intel_ring *ring = request->ring;
        struct i915_timeline *timeline = request->timeline;
+       struct intel_ring *ring = request->ring;
        struct i915_request *prev;
        u32 *cs;
        int err;
@@ -1095,8 +1096,10 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
        i915_gem_active_set(&timeline->last_request, request);
 
        list_add_tail(&request->ring_link, &ring->request_list);
-       if (list_is_first(&request->ring_link, &ring->request_list))
+       if (list_is_first(&request->ring_link, &ring->request_list)) {
+               GEM_TRACE("marking %s as active\n", ring->timeline->name);
                list_add(&ring->active_link, &request->i915->gt.active_rings);
+       }
        request->emitted_jiffies = jiffies;
 
        /*
@@ -1113,7 +1116,7 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
        local_bh_disable();
        rcu_read_lock(); /* RCU serialisation for set-wedged protection */
        if (engine->schedule)
-               engine->schedule(request, &request->ctx->sched);
+               engine->schedule(request, &request->gem_context->sched);
        rcu_read_unlock();
        i915_sw_fence_commit(&request->submit);
        local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
index eddbd4245cb3afa92253d2c023f9ffb29b73f6d9..491ff81d0fea78c136224ed221ef2be3a8b31b42 100644 (file)
@@ -93,8 +93,9 @@ struct i915_request {
         * i915_request_free() will then decrement the refcount on the
         * context.
         */
-       struct i915_gem_context *ctx;
+       struct i915_gem_context *gem_context;
        struct intel_engine_cs *engine;
+       struct intel_context *hw_context;
        struct intel_ring *ring;
        struct i915_timeline *timeline;
        struct intel_signal_node signaling;
@@ -266,6 +267,7 @@ long i915_request_wait(struct i915_request *rq,
 #define I915_WAIT_INTERRUPTIBLE        BIT(0)
 #define I915_WAIT_LOCKED       BIT(1) /* struct_mutex held, handle GPU reset */
 #define I915_WAIT_ALL          BIT(2) /* used by i915_gem_object_wait() */
+#define I915_WAIT_FOR_IDLE_BOOST BIT(3)
 
 static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine);
 
index 8cc3a256f29d3e0ae4cb2afebd04cac76fbd5784..1472f48ab2e804ca9404155b8004d18237b657ec 100644 (file)
@@ -591,21 +591,26 @@ TRACE_EVENT(i915_gem_ring_sync_to,
 
            TP_STRUCT__entry(
                             __field(u32, dev)
-                            __field(u32, sync_from)
-                            __field(u32, sync_to)
+                            __field(u32, from_class)
+                            __field(u32, from_instance)
+                            __field(u32, to_class)
+                            __field(u32, to_instance)
                             __field(u32, seqno)
                             ),
 
            TP_fast_assign(
                           __entry->dev = from->i915->drm.primary->index;
-                          __entry->sync_from = from->engine->id;
-                          __entry->sync_to = to->engine->id;
+                          __entry->from_class = from->engine->uabi_class;
+                          __entry->from_instance = from->engine->instance;
+                          __entry->to_class = to->engine->uabi_class;
+                          __entry->to_instance = to->engine->instance;
                           __entry->seqno = from->global_seqno;
                           ),
 
-           TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u",
+           TP_printk("dev=%u, sync-from=%u:%u, sync-to=%u:%u, seqno=%u",
                      __entry->dev,
-                     __entry->sync_from, __entry->sync_to,
+                     __entry->from_class, __entry->from_instance,
+                     __entry->to_class, __entry->to_instance,
                      __entry->seqno)
 );
 
@@ -616,24 +621,27 @@ TRACE_EVENT(i915_request_queue,
            TP_STRUCT__entry(
                             __field(u32, dev)
                             __field(u32, hw_id)
-                            __field(u32, ring)
-                            __field(u32, ctx)
+                            __field(u64, ctx)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(u32, flags)
                             ),
 
            TP_fast_assign(
                           __entry->dev = rq->i915->drm.primary->index;
-                          __entry->hw_id = rq->ctx->hw_id;
-                          __entry->ring = rq->engine->id;
+                          __entry->hw_id = rq->gem_context->hw_id;
+                          __entry->class = rq->engine->uabi_class;
+                          __entry->instance = rq->engine->instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->flags = flags;
                           ),
 
-           TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, flags=0x%x",
-                     __entry->dev, __entry->hw_id, __entry->ring, __entry->ctx,
-                     __entry->seqno, __entry->flags)
+           TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, flags=0x%x",
+                     __entry->dev, __entry->class, __entry->instance,
+                     __entry->hw_id, __entry->ctx, __entry->seqno,
+                     __entry->flags)
 );
 
 DECLARE_EVENT_CLASS(i915_request,
@@ -643,24 +651,27 @@ DECLARE_EVENT_CLASS(i915_request,
            TP_STRUCT__entry(
                             __field(u32, dev)
                             __field(u32, hw_id)
-                            __field(u32, ring)
-                            __field(u32, ctx)
+                            __field(u64, ctx)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(u32, global)
                             ),
 
            TP_fast_assign(
                           __entry->dev = rq->i915->drm.primary->index;
-                          __entry->hw_id = rq->ctx->hw_id;
-                          __entry->ring = rq->engine->id;
+                          __entry->hw_id = rq->gem_context->hw_id;
+                          __entry->class = rq->engine->uabi_class;
+                          __entry->instance = rq->engine->instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->global = rq->global_seqno;
                           ),
 
-           TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, global=%u",
-                     __entry->dev, __entry->hw_id, __entry->ring, __entry->ctx,
-                     __entry->seqno, __entry->global)
+           TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, global=%u",
+                     __entry->dev, __entry->class, __entry->instance,
+                     __entry->hw_id, __entry->ctx, __entry->seqno,
+                     __entry->global)
 );
 
 DEFINE_EVENT(i915_request, i915_request_add,
@@ -686,8 +697,9 @@ TRACE_EVENT(i915_request_in,
            TP_STRUCT__entry(
                             __field(u32, dev)
                             __field(u32, hw_id)
-                            __field(u32, ring)
-                            __field(u32, ctx)
+                            __field(u64, ctx)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(u32, global_seqno)
                             __field(u32, port)
@@ -696,8 +708,9 @@ TRACE_EVENT(i915_request_in,
 
            TP_fast_assign(
                           __entry->dev = rq->i915->drm.primary->index;
-                          __entry->hw_id = rq->ctx->hw_id;
-                          __entry->ring = rq->engine->id;
+                          __entry->hw_id = rq->gem_context->hw_id;
+                          __entry->class = rq->engine->uabi_class;
+                          __entry->instance = rq->engine->instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->global_seqno = rq->global_seqno;
@@ -705,10 +718,10 @@ TRACE_EVENT(i915_request_in,
                           __entry->port = port;
                           ),
 
-           TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, prio=%u, global=%u, port=%u",
-                     __entry->dev, __entry->hw_id, __entry->ring, __entry->ctx,
-                     __entry->seqno, __entry->prio, __entry->global_seqno,
-                     __entry->port)
+           TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, prio=%u, global=%u, port=%u",
+                     __entry->dev, __entry->class, __entry->instance,
+                     __entry->hw_id, __entry->ctx, __entry->seqno,
+                     __entry->prio, __entry->global_seqno, __entry->port)
 );
 
 TRACE_EVENT(i915_request_out,
@@ -718,8 +731,9 @@ TRACE_EVENT(i915_request_out,
            TP_STRUCT__entry(
                             __field(u32, dev)
                             __field(u32, hw_id)
-                            __field(u32, ring)
-                            __field(u32, ctx)
+                            __field(u64, ctx)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(u32, global_seqno)
                             __field(u32, completed)
@@ -727,17 +741,18 @@ TRACE_EVENT(i915_request_out,
 
            TP_fast_assign(
                           __entry->dev = rq->i915->drm.primary->index;
-                          __entry->hw_id = rq->ctx->hw_id;
-                          __entry->ring = rq->engine->id;
+                          __entry->hw_id = rq->gem_context->hw_id;
+                          __entry->class = rq->engine->uabi_class;
+                          __entry->instance = rq->engine->instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->global_seqno = rq->global_seqno;
                           __entry->completed = i915_request_completed(rq);
                           ),
 
-                   TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, global=%u, completed?=%u",
-                             __entry->dev, __entry->hw_id, __entry->ring,
-                             __entry->ctx, __entry->seqno,
+                   TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, global=%u, completed?=%u",
+                             __entry->dev, __entry->class, __entry->instance,
+                             __entry->hw_id, __entry->ctx, __entry->seqno,
                              __entry->global_seqno, __entry->completed)
 );
 
@@ -771,21 +786,23 @@ TRACE_EVENT(intel_engine_notify,
 
            TP_STRUCT__entry(
                             __field(u32, dev)
-                            __field(u32, ring)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(bool, waiters)
                             ),
 
            TP_fast_assign(
                           __entry->dev = engine->i915->drm.primary->index;
-                          __entry->ring = engine->id;
+                          __entry->class = engine->uabi_class;
+                          __entry->instance = engine->instance;
                           __entry->seqno = intel_engine_get_seqno(engine);
                           __entry->waiters = waiters;
                           ),
 
-           TP_printk("dev=%u, ring=%u, seqno=%u, waiters=%u",
-                     __entry->dev, __entry->ring, __entry->seqno,
-                     __entry->waiters)
+           TP_printk("dev=%u, engine=%u:%u, seqno=%u, waiters=%u",
+                     __entry->dev, __entry->class, __entry->instance,
+                     __entry->seqno, __entry->waiters)
 );
 
 DEFINE_EVENT(i915_request, i915_request_retire,
@@ -800,8 +817,9 @@ TRACE_EVENT(i915_request_wait_begin,
            TP_STRUCT__entry(
                             __field(u32, dev)
                             __field(u32, hw_id)
-                            __field(u32, ring)
-                            __field(u32, ctx)
+                            __field(u64, ctx)
+                            __field(u16, class)
+                            __field(u16, instance)
                             __field(u32, seqno)
                             __field(u32, global)
                             __field(unsigned int, flags)
@@ -815,18 +833,20 @@ TRACE_EVENT(i915_request_wait_begin,
             */
            TP_fast_assign(
                           __entry->dev = rq->i915->drm.primary->index;
-                          __entry->hw_id = rq->ctx->hw_id;
-                          __entry->ring = rq->engine->id;
+                          __entry->hw_id = rq->gem_context->hw_id;
+                          __entry->class = rq->engine->uabi_class;
+                          __entry->instance = rq->engine->instance;
                           __entry->ctx = rq->fence.context;
                           __entry->seqno = rq->fence.seqno;
                           __entry->global = rq->global_seqno;
                           __entry->flags = flags;
                           ),
 
-           TP_printk("dev=%u, hw_id=%u, ring=%u, ctx=%u, seqno=%u, global=%u, blocking=%u, flags=0x%x",
-                     __entry->dev, __entry->hw_id, __entry->ring, __entry->ctx,
-                     __entry->seqno, __entry->global,
-                     !!(__entry->flags & I915_WAIT_LOCKED), __entry->flags)
+           TP_printk("dev=%u, engine=%u:%u, hw_id=%u, ctx=%llu, seqno=%u, global=%u, blocking=%u, flags=0x%x",
+                     __entry->dev, __entry->class, __entry->instance,
+                     __entry->hw_id, __entry->ctx, __entry->seqno,
+                     __entry->global, !!(__entry->flags & I915_WAIT_LOCKED),
+                     __entry->flags)
 );
 
 DEFINE_EVENT(i915_request, i915_request_wait_end,
@@ -936,7 +956,7 @@ DECLARE_EVENT_CLASS(i915_context,
                        __entry->dev = ctx->i915->drm.primary->index;
                        __entry->ctx = ctx;
                        __entry->hw_id = ctx->hw_id;
-                       __entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL;
+                       __entry->vm = ctx->ppgtt ? &ctx->ppgtt->vm : NULL;
        ),
 
        TP_printk("dev=%u, ctx=%p, ctx_vm=%p, hw_id=%u",
@@ -966,21 +986,24 @@ TRACE_EVENT(switch_mm,
        TP_ARGS(engine, to),
 
        TP_STRUCT__entry(
-                       __field(u32, ring)
+                       __field(u16, class)
+                       __field(u16, instance)
                        __field(struct i915_gem_context *, to)
                        __field(struct i915_address_space *, vm)
                        __field(u32, dev)
        ),
 
        TP_fast_assign(
-                       __entry->ring = engine->id;
+                       __entry->class = engine->uabi_class;
+                       __entry->instance = engine->instance;
                        __entry->to = to;
-                       __entry->vm = to->ppgtt? &to->ppgtt->base : NULL;
+                       __entry->vm = to->ppgtt ? &to->ppgtt->vm : NULL;
                        __entry->dev = engine->i915->drm.primary->index;
        ),
 
-       TP_printk("dev=%u, ring=%u, ctx=%p, ctx_vm=%p",
-                 __entry->dev, __entry->ring, __entry->to, __entry->vm)
+       TP_printk("dev=%u, engine=%u:%u, ctx=%p, ctx_vm=%p",
+                 __entry->dev, __entry->class, __entry->instance, __entry->to,
+                 __entry->vm)
 );
 
 #endif /* _I915_TRACE_H_ */
index 5fe9f3f3946728aa7985ab6f251f685bc97cfe6b..869cf4a3b6de75fee593c0f66c953cc1035434a6 100644 (file)
@@ -105,7 +105,7 @@ static void vgt_deballoon_space(struct i915_ggtt *ggtt,
                         node->start + node->size,
                         node->size / 1024);
 
-       ggtt->base.reserved -= node->size;
+       ggtt->vm.reserved -= node->size;
        drm_mm_remove_node(node);
 }
 
@@ -141,11 +141,11 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt,
 
        DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n",
                 start, end, size / 1024);
-       ret = i915_gem_gtt_reserve(&ggtt->base, node,
+       ret = i915_gem_gtt_reserve(&ggtt->vm, node,
                                   size, start, I915_COLOR_UNEVICTABLE,
                                   0);
        if (!ret)
-               ggtt->base.reserved += size;
+               ggtt->vm.reserved += size;
 
        return ret;
 }
@@ -197,7 +197,7 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt,
 int intel_vgt_balloon(struct drm_i915_private *dev_priv)
 {
        struct i915_ggtt *ggtt = &dev_priv->ggtt;
-       unsigned long ggtt_end = ggtt->base.total;
+       unsigned long ggtt_end = ggtt->vm.total;
 
        unsigned long mappable_base, mappable_size, mappable_end;
        unsigned long unmappable_base, unmappable_size, unmappable_end;
index bb8338450dc11021b003155d59b3a4bbbe24b4f9..551acc3900464bb7d4aee586ba7792155631bef5 100644 (file)
@@ -36,6 +36,12 @@ intel_vgpu_has_hwsp_emulation(struct drm_i915_private *dev_priv)
        return dev_priv->vgpu.caps & VGT_CAPS_HWSP_EMULATION;
 }
 
+static inline bool
+intel_vgpu_has_huge_gtt(struct drm_i915_private *dev_priv)
+{
+       return dev_priv->vgpu.caps & VGT_CAPS_HUGE_GTT;
+}
+
 int intel_vgt_balloon(struct drm_i915_private *dev_priv);
 void intel_vgt_deballoon(struct drm_i915_private *dev_priv);
 
index 9324d476e0a7c356b39cb02374e904a2b0a95262..912f16ffe7eea4b62f1f562fd16938d1c69fb14f 100644 (file)
@@ -85,7 +85,7 @@ vma_create(struct drm_i915_gem_object *obj,
        int i;
 
        /* The aliasing_ppgtt should never be used directly! */
-       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
+       GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->vm);
 
        vma = kmem_cache_zalloc(vm->i915->vmas, GFP_KERNEL);
        if (vma == NULL)
@@ -459,6 +459,18 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long cache_level)
        return true;
 }
 
+static void assert_bind_count(const struct drm_i915_gem_object *obj)
+{
+       /*
+        * Combine the assertion that the object is bound and that we have
+        * pinned its pages. But we should never have bound the object
+        * more than we have pinned its pages. (For complete accuracy, we
+        * assume that no else is pinning the pages, but as a rough assertion
+        * that we will not run into problems later, this will do!)
+        */
+       GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count);
+}
+
 /**
  * i915_vma_insert - finds a slot for the vma in its address space
  * @vma: the vma
@@ -595,7 +607,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
        obj->bind_count++;
        spin_unlock(&dev_priv->mm.obj_lock);
 
-       GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count);
+       assert_bind_count(obj);
 
        return 0;
 
@@ -633,7 +645,7 @@ i915_vma_remove(struct i915_vma *vma)
         * reaped by the shrinker.
         */
        i915_gem_object_unpin_pages(obj);
-       GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count);
+       assert_bind_count(obj);
 }
 
 int __i915_vma_do_pin(struct i915_vma *vma,
index 54270bdde1005615d67b37a29bf34b87a89b3382..465dff4780fea9317813bb7f1f936de375bcd97b 100644 (file)
@@ -267,8 +267,6 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
        if (!lvds_lfp_data_ptrs)
                return;
 
-       dev_priv->vbt.lvds_vbt = 1;
-
        panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
                                               lvds_lfp_data_ptrs,
                                               panel_type);
@@ -518,8 +516,31 @@ parse_driver_features(struct drm_i915_private *dev_priv,
        if (!driver)
                return;
 
-       if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
-               dev_priv->vbt.edp.support = 1;
+       if (INTEL_GEN(dev_priv) >= 5) {
+               /*
+                * Note that we consider BDB_DRIVER_FEATURE_INT_SDVO_LVDS
+                * to mean "eDP". The VBT spec doesn't agree with that
+                * interpretation, but real world VBTs seem to.
+                */
+               if (driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS)
+                       dev_priv->vbt.int_lvds_support = 0;
+       } else {
+               /*
+                * FIXME it's not clear which BDB version has the LVDS config
+                * bits defined. Revision history in the VBT spec says:
+                * "0.92 | Add two definitions for VBT value of LVDS Active
+                *  Config (00b and 11b values defined) | 06/13/2005"
+                * but does not the specify the BDB version.
+                *
+                * So far version 134 (on i945gm) is the oldest VBT observed
+                * in the wild with the bits correctly populated. Version
+                * 108 (on i85x) does not have the bits correctly populated.
+                */
+               if (bdb->version >= 134 &&
+                   driver->lvds_config != BDB_DRIVER_FEATURE_INT_LVDS &&
+                   driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS)
+                       dev_priv->vbt.int_lvds_support = 0;
+       }
 
        DRM_DEBUG_KMS("DRRS State Enabled:%d\n", driver->drrs_enabled);
        /*
@@ -542,11 +563,8 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
        int panel_type = dev_priv->vbt.panel_type;
 
        edp = find_section(bdb, BDB_EDP);
-       if (!edp) {
-               if (dev_priv->vbt.edp.support)
-                       DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
+       if (!edp)
                return;
-       }
 
        switch ((edp->color_depth >> (panel_type * 2)) & 3) {
        case EDP_18BPP:
@@ -688,8 +706,52 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
                break;
        }
 
-       dev_priv->vbt.psr.tp1_wakeup_time = psr_table->tp1_wakeup_time;
-       dev_priv->vbt.psr.tp2_tp3_wakeup_time = psr_table->tp2_tp3_wakeup_time;
+       /*
+        * New psr options 0=500us, 1=100us, 2=2500us, 3=0us
+        * Old decimal value is wake up time in multiples of 100 us.
+        */
+       if (bdb->version >= 209 && IS_GEN9_BC(dev_priv)) {
+               switch (psr_table->tp1_wakeup_time) {
+               case 0:
+                       dev_priv->vbt.psr.tp1_wakeup_time_us = 500;
+                       break;
+               case 1:
+                       dev_priv->vbt.psr.tp1_wakeup_time_us = 100;
+                       break;
+               case 3:
+                       dev_priv->vbt.psr.tp1_wakeup_time_us = 0;
+                       break;
+               default:
+                       DRM_DEBUG_KMS("VBT tp1 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",
+                                       psr_table->tp1_wakeup_time);
+                       /* fallthrough */
+               case 2:
+                       dev_priv->vbt.psr.tp1_wakeup_time_us = 2500;
+                       break;
+               }
+
+               switch (psr_table->tp2_tp3_wakeup_time) {
+               case 0:
+                       dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = 500;
+                       break;
+               case 1:
+                       dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = 100;
+                       break;
+               case 3:
+                       dev_priv->vbt.psr.tp1_wakeup_time_us = 0;
+                       break;
+               default:
+                       DRM_DEBUG_KMS("VBT tp2_tp3 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",
+                                       psr_table->tp2_tp3_wakeup_time);
+                       /* fallthrough */
+               case 2:
+                       dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = 2500;
+               break;
+               }
+       } else {
+               dev_priv->vbt.psr.tp1_wakeup_time_us = psr_table->tp1_wakeup_time * 100;
+               dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100;
+       }
 }
 
 static void parse_dsi_backlight_ports(struct drm_i915_private *dev_priv,
@@ -1197,18 +1259,37 @@ static const u8 cnp_ddc_pin_map[] = {
        [DDC_BUS_DDI_F] = GMBUS_PIN_3_BXT, /* sic */
 };
 
+static const u8 icp_ddc_pin_map[] = {
+       [ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT,
+       [ICL_DDC_BUS_DDI_B] = GMBUS_PIN_2_BXT,
+       [ICL_DDC_BUS_PORT_1] = GMBUS_PIN_9_TC1_ICP,
+       [ICL_DDC_BUS_PORT_2] = GMBUS_PIN_10_TC2_ICP,
+       [ICL_DDC_BUS_PORT_3] = GMBUS_PIN_11_TC3_ICP,
+       [ICL_DDC_BUS_PORT_4] = GMBUS_PIN_12_TC4_ICP,
+};
+
 static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
 {
-       if (HAS_PCH_CNP(dev_priv)) {
-               if (vbt_pin < ARRAY_SIZE(cnp_ddc_pin_map)) {
-                       return cnp_ddc_pin_map[vbt_pin];
-               } else {
-                       DRM_DEBUG_KMS("Ignoring alternate pin: VBT claims DDC pin %d, which is not valid for this platform\n", vbt_pin);
-                       return 0;
-               }
+       const u8 *ddc_pin_map;
+       int n_entries;
+
+       if (HAS_PCH_ICP(dev_priv)) {
+               ddc_pin_map = icp_ddc_pin_map;
+               n_entries = ARRAY_SIZE(icp_ddc_pin_map);
+       } else if (HAS_PCH_CNP(dev_priv)) {
+               ddc_pin_map = cnp_ddc_pin_map;
+               n_entries = ARRAY_SIZE(cnp_ddc_pin_map);
+       } else {
+               /* Assuming direct map */
+               return vbt_pin;
        }
 
-       return vbt_pin;
+       if (vbt_pin < n_entries && ddc_pin_map[vbt_pin] != 0)
+               return ddc_pin_map[vbt_pin];
+
+       DRM_DEBUG_KMS("Ignoring alternate pin: VBT claims DDC pin %d, which is not valid for this platform\n",
+                     vbt_pin);
+       return 0;
 }
 
 static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
@@ -1504,7 +1585,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
 
        /* LFP panel data */
        dev_priv->vbt.lvds_dither = 1;
-       dev_priv->vbt.lvds_vbt = 0;
 
        /* SDVO panel data */
        dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
@@ -1513,6 +1593,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
        dev_priv->vbt.int_tv_support = 1;
        dev_priv->vbt.int_crt_support = 1;
 
+       /* driver features */
+       dev_priv->vbt.int_lvds_support = 1;
+
        /* Default to using SSC */
        dev_priv->vbt.lvds_use_ssc = 1;
        /*
index 18e643df523e5ff074d4629da20670e77fea660b..86a987b8ac667b6988a64d446b76ee594046005d 100644 (file)
@@ -846,8 +846,9 @@ static void cancel_fake_irq(struct intel_engine_cs *engine)
 void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
 {
        struct intel_breadcrumbs *b = &engine->breadcrumbs;
+       unsigned long flags;
 
-       spin_lock_irq(&b->irq_lock);
+       spin_lock_irqsave(&b->irq_lock, flags);
 
        /*
         * Leave the fake_irq timer enabled (if it is running), but clear the
@@ -871,7 +872,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
         */
        clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
 
-       spin_unlock_irq(&b->irq_lock);
+       spin_unlock_irqrestore(&b->irq_lock, flags);
 }
 
 void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
index de0e22322c76ed649c2f36266e65247ed9d02c28..211d601cd1b1628c61f0519423663fdf2efab165 100644 (file)
@@ -63,33 +63,35 @@ static struct intel_crt *intel_attached_crt(struct drm_connector *connector)
        return intel_encoder_to_crt(intel_attached_encoder(connector));
 }
 
+bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
+                           i915_reg_t adpa_reg, enum pipe *pipe)
+{
+       u32 val;
+
+       val = I915_READ(adpa_reg);
+
+       /* asserts want to know the pipe even if the port is disabled */
+       if (HAS_PCH_CPT(dev_priv))
+               *pipe = (val & ADPA_PIPE_SEL_MASK_CPT) >> ADPA_PIPE_SEL_SHIFT_CPT;
+       else
+               *pipe = (val & ADPA_PIPE_SEL_MASK) >> ADPA_PIPE_SEL_SHIFT;
+
+       return val & ADPA_DAC_ENABLE;
+}
+
 static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
                                   enum pipe *pipe)
 {
-       struct drm_device *dev = encoder->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crt *crt = intel_encoder_to_crt(encoder);
-       u32 tmp;
        bool ret;
 
        if (!intel_display_power_get_if_enabled(dev_priv,
                                                encoder->power_domain))
                return false;
 
-       ret = false;
-
-       tmp = I915_READ(crt->adpa_reg);
-
-       if (!(tmp & ADPA_DAC_ENABLE))
-               goto out;
+       ret = intel_crt_port_enabled(dev_priv, crt->adpa_reg, pipe);
 
-       if (HAS_PCH_CPT(dev_priv))
-               *pipe = PORT_TO_PIPE_CPT(tmp);
-       else
-               *pipe = PORT_TO_PIPE(tmp);
-
-       ret = true;
-out:
        intel_display_power_put(dev_priv, encoder->power_domain);
 
        return ret;
@@ -168,11 +170,9 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
        if (HAS_PCH_LPT(dev_priv))
                ; /* Those bits don't exist here */
        else if (HAS_PCH_CPT(dev_priv))
-               adpa |= PORT_TRANS_SEL_CPT(crtc->pipe);
-       else if (crtc->pipe == 0)
-               adpa |= ADPA_PIPE_A_SELECT;
+               adpa |= ADPA_PIPE_SEL_CPT(crtc->pipe);
        else
-               adpa |= ADPA_PIPE_B_SELECT;
+               adpa |= ADPA_PIPE_SEL(crtc->pipe);
 
        if (!HAS_PCH_SPLIT(dev_priv))
                I915_WRITE(BCLRPAT(crtc->pipe), 0);
index f4a8598a2d392d607e8d17338f1ff251bc7c627b..b344e0fe08fd5c949bf945e951cf2eb9254307cd 100644 (file)
@@ -1243,35 +1243,6 @@ intel_ddi_get_crtc_encoder(struct intel_crtc *crtc)
        return ret;
 }
 
-/* Finds the only possible encoder associated with the given CRTC. */
-struct intel_encoder *
-intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
-{
-       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-       struct intel_encoder *ret = NULL;
-       struct drm_atomic_state *state;
-       struct drm_connector *connector;
-       struct drm_connector_state *connector_state;
-       int num_encoders = 0;
-       int i;
-
-       state = crtc_state->base.state;
-
-       for_each_new_connector_in_state(state, connector, connector_state, i) {
-               if (connector_state->crtc != crtc_state->base.crtc)
-                       continue;
-
-               ret = to_intel_encoder(connector_state->best_encoder);
-               num_encoders++;
-       }
-
-       WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
-            pipe_name(crtc->pipe));
-
-       BUG_ON(ret == NULL);
-       return ret;
-}
-
 #define LC_FREQ 2700
 
 static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
@@ -1374,8 +1345,13 @@ static int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv,
        uint32_t cfgcr0, cfgcr1;
        uint32_t p0, p1, p2, dco_freq, ref_clock;
 
-       cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
-       cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+       if (INTEL_GEN(dev_priv) >= 11) {
+               cfgcr0 = I915_READ(ICL_DPLL_CFGCR0(pll_id));
+               cfgcr1 = I915_READ(ICL_DPLL_CFGCR1(pll_id));
+       } else {
+               cfgcr0 = I915_READ(CNL_DPLL_CFGCR0(pll_id));
+               cfgcr1 = I915_READ(CNL_DPLL_CFGCR1(pll_id));
+       }
 
        p0 = cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
        p2 = cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
@@ -1451,6 +1427,30 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
        pipe_config->base.adjusted_mode.crtc_clock = dotclock;
 }
 
+static void icl_ddi_clock_get(struct intel_encoder *encoder,
+                             struct intel_crtc_state *pipe_config)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       enum port port = encoder->port;
+       int link_clock = 0;
+       uint32_t pll_id;
+
+       pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
+       if (port == PORT_A || port == PORT_B) {
+               if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
+                       link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
+               else
+                       link_clock = icl_calc_dp_combo_pll_link(dev_priv,
+                                                               pll_id);
+       } else {
+               /* FIXME - Add for MG PLL */
+               WARN(1, "MG PLL clock_get code not implemented yet\n");
+       }
+
+       pipe_config->port_clock = link_clock;
+       ddi_dotclock_get(pipe_config);
+}
+
 static void cnl_ddi_clock_get(struct intel_encoder *encoder,
                              struct intel_crtc_state *pipe_config)
 {
@@ -1644,6 +1644,8 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
                bxt_ddi_clock_get(encoder, pipe_config);
        else if (IS_CANNONLAKE(dev_priv))
                cnl_ddi_clock_get(encoder, pipe_config);
+       else if (IS_ICELAKE(dev_priv))
+               icl_ddi_clock_get(encoder, pipe_config);
 }
 
 void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
@@ -2115,6 +2117,26 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
                DP_TRAIN_VOLTAGE_SWING_MASK;
 }
 
+/*
+ * We assume that the full set of pre-emphasis values can be
+ * used on all DDI platforms. Should that change we need to
+ * rethink this code.
+ */
+u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, u8 voltage_swing)
+{
+       switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
+       case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
+               return DP_TRAIN_PRE_EMPH_LEVEL_3;
+       case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
+               return DP_TRAIN_PRE_EMPH_LEVEL_2;
+       case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
+               return DP_TRAIN_PRE_EMPH_LEVEL_1;
+       case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
+       default:
+               return DP_TRAIN_PRE_EMPH_LEVEL_0;
+       }
+}
+
 static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
                                   int level, enum intel_output_type type)
 {
index dee3a8e659f1d6c9dbe2040abd6e2ba42020070a..17c590b42fd76e58208d6aa77ee2ee78e39643b9 100644 (file)
@@ -1202,7 +1202,7 @@ void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
        i915_reg_t pp_reg;
        u32 val;
-       enum pipe panel_pipe = PIPE_A;
+       enum pipe panel_pipe = INVALID_PIPE;
        bool locked = true;
 
        if (WARN_ON(HAS_DDI(dev_priv)))
@@ -1214,18 +1214,35 @@ void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe)
                pp_reg = PP_CONTROL(0);
                port_sel = I915_READ(PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
 
-               if (port_sel == PANEL_PORT_SELECT_LVDS &&
-                   I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT)
-                       panel_pipe = PIPE_B;
-               /* XXX: else fix for eDP */
+               switch (port_sel) {
+               case PANEL_PORT_SELECT_LVDS:
+                       intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe);
+                       break;
+               case PANEL_PORT_SELECT_DPA:
+                       intel_dp_port_enabled(dev_priv, DP_A, PORT_A, &panel_pipe);
+                       break;
+               case PANEL_PORT_SELECT_DPC:
+                       intel_dp_port_enabled(dev_priv, PCH_DP_C, PORT_C, &panel_pipe);
+                       break;
+               case PANEL_PORT_SELECT_DPD:
+                       intel_dp_port_enabled(dev_priv, PCH_DP_D, PORT_D, &panel_pipe);
+                       break;
+               default:
+                       MISSING_CASE(port_sel);
+                       break;
+               }
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                /* presumably write lock depends on pipe, not port select */
                pp_reg = PP_CONTROL(pipe);
                panel_pipe = pipe;
        } else {
+               u32 port_sel;
+
                pp_reg = PP_CONTROL(0);
-               if (I915_READ(LVDS) & LVDS_PIPEB_SELECT)
-                       panel_pipe = PIPE_B;
+               port_sel = I915_READ(PP_ON_DELAYS(0)) & PANEL_PORT_SELECT_MASK;
+
+               WARN_ON(port_sel != PANEL_PORT_SELECT_LVDS);
+               intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe);
        }
 
        val = I915_READ(pp_reg);
@@ -1267,7 +1284,10 @@ void assert_pipe(struct drm_i915_private *dev_priv,
 
 static void assert_plane(struct intel_plane *plane, bool state)
 {
-       bool cur_state = plane->get_hw_state(plane);
+       enum pipe pipe;
+       bool cur_state;
+
+       cur_state = plane->get_hw_state(plane, &pipe);
 
        I915_STATE_WARN(cur_state != state,
                        "%s assertion failure (expected %s, current %s)\n",
@@ -1305,125 +1325,64 @@ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
             pipe_name(pipe));
 }
 
-static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
-                           enum pipe pipe, u32 port_sel, u32 val)
+static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
+                                  enum pipe pipe, enum port port,
+                                  i915_reg_t dp_reg)
 {
-       if ((val & DP_PORT_EN) == 0)
-               return false;
+       enum pipe port_pipe;
+       bool state;
 
-       if (HAS_PCH_CPT(dev_priv)) {
-               u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
-               if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
-                       return false;
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               if ((val & DP_PIPE_MASK_CHV) != DP_PIPE_SELECT_CHV(pipe))
-                       return false;
-       } else {
-               if ((val & DP_PIPE_MASK) != (pipe << 30))
-                       return false;
-       }
-       return true;
-}
+       state = intel_dp_port_enabled(dev_priv, dp_reg, port, &port_pipe);
 
-static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
-                             enum pipe pipe, u32 val)
-{
-       if ((val & SDVO_ENABLE) == 0)
-               return false;
+       I915_STATE_WARN(state && port_pipe == pipe,
+                       "PCH DP %c enabled on transcoder %c, should be disabled\n",
+                       port_name(port), pipe_name(pipe));
 
-       if (HAS_PCH_CPT(dev_priv)) {
-               if ((val & SDVO_PIPE_SEL_MASK_CPT) != SDVO_PIPE_SEL_CPT(pipe))
-                       return false;
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               if ((val & SDVO_PIPE_SEL_MASK_CHV) != SDVO_PIPE_SEL_CHV(pipe))
-                       return false;
-       } else {
-               if ((val & SDVO_PIPE_SEL_MASK) != SDVO_PIPE_SEL(pipe))
-                       return false;
-       }
-       return true;
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
+                       "IBX PCH DP %c still using transcoder B\n",
+                       port_name(port));
 }
 
-static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv,
-                             enum pipe pipe, u32 val)
-{
-       if ((val & LVDS_PORT_EN) == 0)
-               return false;
-
-       if (HAS_PCH_CPT(dev_priv)) {
-               if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
-                       return false;
-       } else {
-               if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe))
-                       return false;
-       }
-       return true;
-}
-
-static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv,
-                             enum pipe pipe, u32 val)
-{
-       if ((val & ADPA_DAC_ENABLE) == 0)
-               return false;
-       if (HAS_PCH_CPT(dev_priv)) {
-               if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
-                       return false;
-       } else {
-               if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe))
-                       return false;
-       }
-       return true;
-}
-
-static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
-                                  enum pipe pipe, i915_reg_t reg,
-                                  u32 port_sel)
+static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
+                                    enum pipe pipe, enum port port,
+                                    i915_reg_t hdmi_reg)
 {
-       u32 val = I915_READ(reg);
-       I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
-            "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
-            i915_mmio_reg_offset(reg), pipe_name(pipe));
+       enum pipe port_pipe;
+       bool state;
 
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & DP_PORT_EN) == 0
-            && (val & DP_PIPEB_SELECT),
-            "IBX PCH dp port still using transcoder B\n");
-}
+       state = intel_sdvo_port_enabled(dev_priv, hdmi_reg, &port_pipe);
 
-static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
-                                    enum pipe pipe, i915_reg_t reg)
-{
-       u32 val = I915_READ(reg);
-       I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
-            "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
-            i915_mmio_reg_offset(reg), pipe_name(pipe));
+       I915_STATE_WARN(state && port_pipe == pipe,
+                       "PCH HDMI %c enabled on transcoder %c, should be disabled\n",
+                       port_name(port), pipe_name(pipe));
 
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & SDVO_ENABLE) == 0
-            && (val & SDVO_PIPE_B_SELECT),
-            "IBX PCH hdmi port still using transcoder B\n");
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
+                       "IBX PCH HDMI %c still using transcoder B\n",
+                       port_name(port));
 }
 
 static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
                                      enum pipe pipe)
 {
-       u32 val;
+       enum pipe port_pipe;
 
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_B, PCH_DP_B);
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_C, PCH_DP_C);
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_D, PCH_DP_D);
 
-       val = I915_READ(PCH_ADPA);
-       I915_STATE_WARN(adpa_pipe_enabled(dev_priv, pipe, val),
-            "PCH VGA enabled on transcoder %c, should be disabled\n",
-            pipe_name(pipe));
+       I915_STATE_WARN(intel_crt_port_enabled(dev_priv, PCH_ADPA, &port_pipe) &&
+                       port_pipe == pipe,
+                       "PCH VGA enabled on transcoder %c, should be disabled\n",
+                       pipe_name(pipe));
 
-       val = I915_READ(PCH_LVDS);
-       I915_STATE_WARN(lvds_pipe_enabled(dev_priv, pipe, val),
-            "PCH LVDS enabled on transcoder %c, should be disabled\n",
-            pipe_name(pipe));
+       I915_STATE_WARN(intel_lvds_port_enabled(dev_priv, PCH_LVDS, &port_pipe) &&
+                       port_pipe == pipe,
+                       "PCH LVDS enabled on transcoder %c, should be disabled\n",
+                       pipe_name(pipe));
 
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIB);
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIC);
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_B, PCH_HDMIB);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_C, PCH_HDMIC);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID);
 }
 
 static void _vlv_enable_pll(struct intel_crtc *crtc,
@@ -2521,6 +2480,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 {
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
        struct intel_rotation_info *rot_info = &intel_fb->rot_info;
+       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        u32 gtt_offset_rotated = 0;
        unsigned int max_size = 0;
        int i, num_planes = fb->format->num_planes;
@@ -2585,7 +2545,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
                 * fb layout agrees with the fence layout. We already check that the
                 * fb stride matches the fence stride elsewhere.
                 */
-               if (i == 0 && i915_gem_object_is_tiled(intel_fb->obj) &&
+               if (i == 0 && i915_gem_object_is_tiled(obj) &&
                    (x + width) * cpp > fb->pitches[i]) {
                        DRM_DEBUG_KMS("bad fb plane %d offset: 0x%x\n",
                                      i, fb->offsets[i]);
@@ -2670,9 +2630,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
                max_size = max(max_size, offset + size);
        }
 
-       if (max_size * tile_size > intel_fb->obj->base.size) {
+       if (max_size * tile_size > obj->base.size) {
                DRM_DEBUG_KMS("fb too big for bo (need %u bytes, have %zu bytes)\n",
-                             max_size * tile_size, intel_fb->obj->base.size);
+                             max_size * tile_size, obj->base.size);
                return -EINVAL;
        }
 
@@ -3430,24 +3390,33 @@ static void i9xx_disable_plane(struct intel_plane *plane,
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
-static bool i9xx_plane_get_hw_state(struct intel_plane *plane)
+static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
+                                   enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       enum pipe pipe = plane->pipe;
        bool ret;
+       u32 val;
 
        /*
         * Not 100% correct for planes that can move between pipes,
         * but that's only the case for gen2-4 which don't have any
         * display power wells.
         */
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(DSPCNTR(i9xx_plane)) & DISPLAY_PLANE_ENABLE;
+       val = I915_READ(DSPCNTR(i9xx_plane));
+
+       ret = val & DISPLAY_PLANE_ENABLE;
+
+       if (INTEL_GEN(dev_priv) >= 5)
+               *pipe = plane->pipe;
+       else
+               *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
+                       DISPPLANE_SEL_PIPE_SHIFT;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -4631,20 +4600,33 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
        }
 }
 
-/* Return which DP Port should be selected for Transcoder DP control */
-static enum port
-intel_trans_dp_port_sel(struct intel_crtc *crtc)
+/*
+ * Finds the encoder associated with the given CRTC. This can only be
+ * used when we know that the CRTC isn't feeding multiple encoders!
+ */
+static struct intel_encoder *
+intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
+                          const struct intel_crtc_state *crtc_state)
 {
-       struct drm_device *dev = crtc->base.dev;
-       struct intel_encoder *encoder;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       const struct drm_connector_state *connector_state;
+       const struct drm_connector *connector;
+       struct intel_encoder *encoder = NULL;
+       int num_encoders = 0;
+       int i;
+
+       for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
+               if (connector_state->crtc != &crtc->base)
+                       continue;
 
-       for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
-               if (encoder->type == INTEL_OUTPUT_DP ||
-                   encoder->type == INTEL_OUTPUT_EDP)
-                       return encoder->port;
+               encoder = to_intel_encoder(connector_state->best_encoder);
+               num_encoders++;
        }
 
-       return -1;
+       WARN(num_encoders != 1, "%d encoders for pipe %c\n",
+            num_encoders, pipe_name(crtc->pipe));
+
+       return encoder;
 }
 
 /*
@@ -4655,7 +4637,8 @@ intel_trans_dp_port_sel(struct intel_crtc *crtc)
  *   - DP transcoding bits
  *   - transcoder
  */
-static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
+static void ironlake_pch_enable(const struct intel_atomic_state *state,
+                               const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_device *dev = crtc->base.dev;
@@ -4714,6 +4697,8 @@ static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
                        &crtc_state->base.adjusted_mode;
                u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
                i915_reg_t reg = TRANS_DP_CTL(pipe);
+               enum port port;
+
                temp = I915_READ(reg);
                temp &= ~(TRANS_DP_PORT_SEL_MASK |
                          TRANS_DP_SYNC_MASK |
@@ -4726,19 +4711,9 @@ static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
                if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
                        temp |= TRANS_DP_VSYNC_ACTIVE_HIGH;
 
-               switch (intel_trans_dp_port_sel(crtc)) {
-               case PORT_B:
-                       temp |= TRANS_DP_PORT_SEL_B;
-                       break;
-               case PORT_C:
-                       temp |= TRANS_DP_PORT_SEL_C;
-                       break;
-               case PORT_D:
-                       temp |= TRANS_DP_PORT_SEL_D;
-                       break;
-               default:
-                       BUG();
-               }
+               port = intel_get_crtc_new_encoder(state, crtc_state)->port;
+               WARN_ON(port < PORT_B || port > PORT_D);
+               temp |= TRANS_DP_PORT_SEL(port);
 
                I915_WRITE(reg, temp);
        }
@@ -4746,7 +4721,8 @@ static void ironlake_pch_enable(const struct intel_crtc_state *crtc_state)
        ironlake_enable_pch_transcoder(dev_priv, pipe);
 }
 
-static void lpt_pch_enable(const struct intel_crtc_state *crtc_state)
+static void lpt_pch_enable(const struct intel_atomic_state *state,
+                          const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -4776,6 +4752,39 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe)
        }
 }
 
+/*
+ * The hardware phase 0.0 refers to the center of the pixel.
+ * We want to start from the top/left edge which is phase
+ * -0.5. That matches how the hardware calculates the scaling
+ * factors (from top-left of the first pixel to bottom-right
+ * of the last pixel, as opposed to the pixel centers).
+ *
+ * For 4:2:0 subsampled chroma planes we obviously have to
+ * adjust that so that the chroma sample position lands in
+ * the right spot.
+ *
+ * Note that for packed YCbCr 4:2:2 formats there is no way to
+ * control chroma siting. The hardware simply replicates the
+ * chroma samples for both of the luma samples, and thus we don't
+ * actually get the expected MPEG2 chroma siting convention :(
+ * The same behaviour is observed on pre-SKL platforms as well.
+ */
+u16 skl_scaler_calc_phase(int sub, bool chroma_cosited)
+{
+       int phase = -0x8000;
+       u16 trip = 0;
+
+       if (chroma_cosited)
+               phase += (sub - 1) * 0x8000 / sub;
+
+       if (phase < 0)
+               phase = 0x10000 + phase;
+       else
+               trip = PS_PHASE_TRIP;
+
+       return ((phase >> 2) & PS_PHASE_MASK) | trip;
+}
+
 static int
 skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
                  unsigned int scaler_user, int *scaler_id,
@@ -4975,14 +4984,22 @@ static void skylake_pfit_enable(struct intel_crtc *crtc)
                &crtc->config->scaler_state;
 
        if (crtc->config->pch_pfit.enabled) {
+               u16 uv_rgb_hphase, uv_rgb_vphase;
                int id;
 
                if (WARN_ON(crtc->config->scaler_state.scaler_id < 0))
                        return;
 
+               uv_rgb_hphase = skl_scaler_calc_phase(1, false);
+               uv_rgb_vphase = skl_scaler_calc_phase(1, false);
+
                id = scaler_state->scaler_id;
                I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
                        PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
+               I915_WRITE_FW(SKL_PS_VPHASE(pipe, id),
+                             PS_Y_PHASE(0) | PS_UV_RGB_PHASE(uv_rgb_vphase));
+               I915_WRITE_FW(SKL_PS_HPHASE(pipe, id),
+                             PS_Y_PHASE(0) | PS_UV_RGB_PHASE(uv_rgb_hphase));
                I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
                I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
        }
@@ -5501,10 +5518,8 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
         *
         * Spurious PCH underruns also occur during PCH enabling.
         */
-       if (intel_crtc->config->has_pch_encoder || IS_GEN5(dev_priv))
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-       if (intel_crtc->config->has_pch_encoder)
-               intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+       intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
 
        if (intel_crtc->config->has_pch_encoder)
                intel_prepare_shared_dpll(intel_crtc);
@@ -5549,7 +5564,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
        intel_enable_pipe(pipe_config);
 
        if (intel_crtc->config->has_pch_encoder)
-               ironlake_pch_enable(pipe_config);
+               ironlake_pch_enable(old_intel_state, pipe_config);
 
        assert_vblank_disabled(crtc);
        drm_crtc_vblank_on(crtc);
@@ -5559,9 +5574,16 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
        if (HAS_PCH_CPT(dev_priv))
                cpt_verify_modeset(dev, intel_crtc->pipe);
 
-       /* Must wait for vblank to avoid spurious PCH FIFO underruns */
-       if (intel_crtc->config->has_pch_encoder)
+       /*
+        * Must wait for vblank to avoid spurious PCH FIFO underruns.
+        * And a second vblank wait is needed at least on ILK with
+        * some interlaced HDMI modes. Let's do the double wait always
+        * in case there are more corner cases we don't know about.
+        */
+       if (intel_crtc->config->has_pch_encoder) {
+               intel_wait_for_vblank(dev_priv, pipe);
                intel_wait_for_vblank(dev_priv, pipe);
+       }
        intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
        intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
 }
@@ -5623,6 +5645,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
        if (INTEL_GEN(dev_priv) >= 11)
                icl_map_plls_to_ports(crtc, pipe_config, old_state);
 
+       intel_encoders_pre_enable(crtc, pipe_config, old_state);
+
+       if (!transcoder_is_dsi(cpu_transcoder))
+               intel_ddi_enable_pipe_clock(pipe_config);
+
        if (intel_crtc_has_dp_encoder(intel_crtc->config))
                intel_dp_set_m_n(intel_crtc, M1_N1);
 
@@ -5651,11 +5678,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 
        intel_crtc->active = true;
 
-       intel_encoders_pre_enable(crtc, pipe_config, old_state);
-
-       if (!transcoder_is_dsi(cpu_transcoder))
-               intel_ddi_enable_pipe_clock(pipe_config);
-
        /* Display WA #1180: WaDisableScalarClockGating: glk, cnl */
        psl_clkgate_wa = (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
                         intel_crtc->config->pch_pfit.enabled;
@@ -5688,7 +5710,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                intel_enable_pipe(pipe_config);
 
        if (intel_crtc->config->has_pch_encoder)
-               lpt_pch_enable(pipe_config);
+               lpt_pch_enable(old_intel_state, pipe_config);
 
        if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DP_MST))
                intel_ddi_set_vc_payload_alloc(pipe_config, true);
@@ -5741,10 +5763,8 @@ static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
         * pipe is already disabled, but FDI RX/TX is still enabled.
         * Happens at least with VGA+HDMI cloning. Suppress them.
         */
-       if (intel_crtc->config->has_pch_encoder) {
-               intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-               intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
-       }
+       intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+       intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
 
        intel_encoders_disable(crtc, old_crtc_state, old_state);
 
@@ -5849,6 +5869,22 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
+bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port)
+{
+       if (IS_ICELAKE(dev_priv))
+               return port >= PORT_C && port <= PORT_F;
+
+       return false;
+}
+
+enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port)
+{
+       if (!intel_port_is_tc(dev_priv, port))
+               return PORT_TC_NONE;
+
+       return port - PORT_C;
+}
+
 enum intel_display_power_domain intel_port_to_power_domain(enum port port)
 {
        switch (port) {
@@ -7675,16 +7711,18 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *plane = to_intel_plane(crtc->base.primary);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       enum pipe pipe = crtc->pipe;
+       enum pipe pipe;
        u32 val, base, offset;
        int fourcc, pixel_format;
        unsigned int aligned_height;
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
-       if (!plane->get_hw_state(plane))
+       if (!plane->get_hw_state(plane, &pipe))
                return;
 
+       WARN_ON(pipe != crtc->pipe);
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -8705,16 +8743,18 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct intel_plane *plane = to_intel_plane(crtc->base.primary);
        enum plane_id plane_id = plane->id;
-       enum pipe pipe = crtc->pipe;
+       enum pipe pipe;
        u32 val, base, offset, stride_mult, tiling, alpha;
        int fourcc, pixel_format;
        unsigned int aligned_height;
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
 
-       if (!plane->get_hw_state(plane))
+       if (!plane->get_hw_state(plane, &pipe))
                return;
 
+       WARN_ON(pipe != crtc->pipe);
+
        intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
        if (!intel_fb) {
                DRM_DEBUG_KMS("failed to alloc fb\n");
@@ -9142,9 +9182,12 @@ void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
                                      struct intel_crtc_state *crtc_state)
 {
+       struct intel_atomic_state *state =
+               to_intel_atomic_state(crtc_state->base.state);
+
        if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) {
                struct intel_encoder *encoder =
-                       intel_ddi_get_crtc_new_encoder(crtc_state);
+                       intel_get_crtc_new_encoder(state, crtc_state);
 
                if (!intel_get_shared_dpll(crtc, crtc_state, encoder)) {
                        DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
@@ -9692,7 +9735,8 @@ static void i845_disable_cursor(struct intel_plane *plane,
        i845_update_cursor(plane, NULL, NULL);
 }
 
-static bool i845_cursor_get_hw_state(struct intel_plane *plane)
+static bool i845_cursor_get_hw_state(struct intel_plane *plane,
+                                    enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
@@ -9704,6 +9748,8 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane)
 
        ret = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE;
 
+       *pipe = PIPE_A;
+
        intel_display_power_put(dev_priv, power_domain);
 
        return ret;
@@ -9715,25 +9761,30 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
        struct drm_i915_private *dev_priv =
                to_i915(plane_state->base.plane->dev);
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-       u32 cntl;
+       u32 cntl = 0;
 
-       cntl = MCURSOR_GAMMA_ENABLE;
+       if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
+               cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
 
-       if (HAS_DDI(dev_priv))
-               cntl |= CURSOR_PIPE_CSC_ENABLE;
+       if (INTEL_GEN(dev_priv) <= 10) {
+               cntl |= MCURSOR_GAMMA_ENABLE;
+
+               if (HAS_DDI(dev_priv))
+                       cntl |= MCURSOR_PIPE_CSC_ENABLE;
+       }
 
        if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
                cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
 
        switch (plane_state->base.crtc_w) {
        case 64:
-               cntl |= CURSOR_MODE_64_ARGB_AX;
+               cntl |= MCURSOR_MODE_64_ARGB_AX;
                break;
        case 128:
-               cntl |= CURSOR_MODE_128_ARGB_AX;
+               cntl |= MCURSOR_MODE_128_ARGB_AX;
                break;
        case 256:
-               cntl |= CURSOR_MODE_256_ARGB_AX;
+               cntl |= MCURSOR_MODE_256_ARGB_AX;
                break;
        default:
                MISSING_CASE(plane_state->base.crtc_w);
@@ -9741,7 +9792,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
        }
 
        if (plane_state->base.rotation & DRM_MODE_ROTATE_180)
-               cntl |= CURSOR_ROTATE_180;
+               cntl |= MCURSOR_ROTATE_180;
 
        return cntl;
 }
@@ -9903,23 +9954,32 @@ static void i9xx_disable_cursor(struct intel_plane *plane,
        i9xx_update_cursor(plane, NULL, NULL);
 }
 
-static bool i9xx_cursor_get_hw_state(struct intel_plane *plane)
+static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
+                                    enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum intel_display_power_domain power_domain;
-       enum pipe pipe = plane->pipe;
        bool ret;
+       u32 val;
 
        /*
         * Not 100% correct for planes that can move between pipes,
         * but that's only the case for gen2-3 which don't have any
         * display power wells.
         */
-       power_domain = POWER_DOMAIN_PIPE(pipe);
+       power_domain = POWER_DOMAIN_PIPE(plane->pipe);
        if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
                return false;
 
-       ret = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
+       val = I915_READ(CURCNTR(plane->pipe));
+
+       ret = val & MCURSOR_MODE;
+
+       if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
+               *pipe = plane->pipe;
+       else
+               *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >>
+                       MCURSOR_PIPE_SELECT_SHIFT;
 
        intel_display_power_put(dev_priv, power_domain);
 
@@ -14124,14 +14184,15 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
+       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 
        drm_framebuffer_cleanup(fb);
 
-       i915_gem_object_lock(intel_fb->obj);
-       WARN_ON(!intel_fb->obj->framebuffer_references--);
-       i915_gem_object_unlock(intel_fb->obj);
+       i915_gem_object_lock(obj);
+       WARN_ON(!obj->framebuffer_references--);
+       i915_gem_object_unlock(obj);
 
-       i915_gem_object_put(intel_fb->obj);
+       i915_gem_object_put(obj);
 
        kfree(intel_fb);
 }
@@ -14140,8 +14201,7 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
                                                struct drm_file *file,
                                                unsigned int *handle)
 {
-       struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj = intel_fb->obj;
+       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 
        if (obj->userptr.mm) {
                DRM_DEBUG("attempting to use a userptr for a framebuffer, denied\n");
@@ -14411,9 +14471,9 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
                                      i, fb->pitches[i], stride_alignment);
                        goto err;
                }
-       }
 
-       intel_fb->obj = obj;
+               fb->obj[i] = &obj->base;
+       }
 
        ret = intel_fill_fb_info(dev_priv, fb);
        if (ret)
@@ -15095,8 +15155,8 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
        WARN_ON(I915_READ(DSPCNTR(PLANE_A)) & DISPLAY_PLANE_ENABLE);
        WARN_ON(I915_READ(DSPCNTR(PLANE_B)) & DISPLAY_PLANE_ENABLE);
        WARN_ON(I915_READ(DSPCNTR(PLANE_C)) & DISPLAY_PLANE_ENABLE);
-       WARN_ON(I915_READ(CURCNTR(PIPE_A)) & CURSOR_MODE);
-       WARN_ON(I915_READ(CURCNTR(PIPE_B)) & CURSOR_MODE);
+       WARN_ON(I915_READ(CURCNTR(PIPE_A)) & MCURSOR_MODE);
+       WARN_ON(I915_READ(CURCNTR(PIPE_B)) & MCURSOR_MODE);
 
        I915_WRITE(PIPECONF(pipe), 0);
        POSTING_READ(PIPECONF(pipe));
@@ -15110,12 +15170,12 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
 static bool intel_plane_mapping_ok(struct intel_crtc *crtc,
                                   struct intel_plane *plane)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       u32 val = I915_READ(DSPCNTR(i9xx_plane));
+       enum pipe pipe;
 
-       return (val & DISPLAY_PLANE_ENABLE) == 0 ||
-               (val & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE(crtc->pipe);
+       if (!plane->get_hw_state(plane, &pipe))
+               return true;
+
+       return pipe == crtc->pipe;
 }
 
 static void
@@ -15274,6 +15334,9 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
                connector->base.dpms = DRM_MODE_DPMS_OFF;
                connector->base.encoder = NULL;
        }
+
+       /* notify opregion of the sanitized encoder state */
+       intel_opregion_notify_encoder(encoder, connector && has_active_crtc);
 }
 
 void i915_redisable_vga_power_on(struct drm_i915_private *dev_priv)
@@ -15314,7 +15377,10 @@ static void readout_plane_state(struct intel_crtc *crtc)
        for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
-               bool visible = plane->get_hw_state(plane);
+               enum pipe pipe;
+               bool visible;
+
+               visible = plane->get_hw_state(plane, &pipe);
 
                intel_set_plane_visible(crtc_state, plane_state, visible);
        }
index 2ef31617614ab22972d9ce48acaf89724fdb6b09..c88185ed75944d7a4412446c2d762e98d299fbda 100644 (file)
@@ -126,6 +126,17 @@ enum port {
 
 #define port_name(p) ((p) + 'A')
 
+enum tc_port {
+       PORT_TC_NONE = -1,
+
+       PORT_TC1 = 0,
+       PORT_TC2,
+       PORT_TC3,
+       PORT_TC4,
+
+       I915_MAX_TC_PORTS
+};
+
 enum dpio_channel {
        DPIO_CH0,
        DPIO_CH1
index 8320f0e8e3bef8587b94a908bf87f3eecdf63fc5..37b9f62aeb6e80b5d27561282ce501efda026945 100644 (file)
@@ -56,7 +56,7 @@ struct dp_link_dpll {
        struct dpll dpll;
 };
 
-static const struct dp_link_dpll gen4_dpll[] = {
+static const struct dp_link_dpll g4x_dpll[] = {
        { 162000,
                { .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } },
        { 270000,
@@ -513,7 +513,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        uint32_t DP;
 
        if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN,
-                "skipping pipe %c power seqeuncer kick due to port %c being active\n",
+                "skipping pipe %c power sequencer kick due to port %c being active\n",
                 pipe_name(pipe), port_name(intel_dig_port->base.port)))
                return;
 
@@ -529,9 +529,9 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        DP |= DP_LINK_TRAIN_PAT_1;
 
        if (IS_CHERRYVIEW(dev_priv))
-               DP |= DP_PIPE_SELECT_CHV(pipe);
-       else if (pipe == PIPE_B)
-               DP |= DP_PIPEB_SELECT;
+               DP |= DP_PIPE_SEL_CHV(pipe);
+       else
+               DP |= DP_PIPE_SEL(pipe);
 
        pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE;
 
@@ -554,7 +554,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        /*
         * Similar magic as in intel_dp_enable_port().
         * We _must_ do this port enable + disable trick
-        * to make this power seqeuencer lock onto the port.
+        * to make this power sequencer lock onto the port.
         * Otherwise even VDD force bit won't work.
         */
        I915_WRITE(intel_dp->output_reg, DP);
@@ -1550,8 +1550,8 @@ intel_dp_set_clock(struct intel_encoder *encoder,
        int i, count = 0;
 
        if (IS_G4X(dev_priv)) {
-               divisor = gen4_dpll;
-               count = ARRAY_SIZE(gen4_dpll);
+               divisor = g4x_dpll;
+               count = ARRAY_SIZE(g4x_dpll);
        } else if (HAS_PCH_SPLIT(dev_priv)) {
                divisor = pch_dpll;
                count = ARRAY_SIZE(pch_dpll);
@@ -1964,7 +1964,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
 
        /* Split out the IBX/CPU vs CPT settings */
 
-       if (IS_GEN7(dev_priv) && port == PORT_A) {
+       if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
                if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
                        intel_dp->DP |= DP_SYNC_HS_HIGH;
                if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
@@ -1974,7 +1974,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
-               intel_dp->DP |= crtc->pipe << 29;
+               intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
        } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
                u32 trans_dp;
 
@@ -2000,9 +2000,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
                if (IS_CHERRYVIEW(dev_priv))
-                       intel_dp->DP |= DP_PIPE_SELECT_CHV(crtc->pipe);
-               else if (crtc->pipe == PIPE_B)
-                       intel_dp->DP |= DP_PIPEB_SELECT;
+                       intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe);
+               else
+                       intel_dp->DP |= DP_PIPE_SEL(crtc->pipe);
        }
 }
 
@@ -2624,52 +2624,66 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode)
                              mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
 }
 
+static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
+                                enum port port, enum pipe *pipe)
+{
+       enum pipe p;
+
+       for_each_pipe(dev_priv, p) {
+               u32 val = I915_READ(TRANS_DP_CTL(p));
+
+               if ((val & TRANS_DP_PORT_SEL_MASK) == TRANS_DP_PORT_SEL(port)) {
+                       *pipe = p;
+                       return true;
+               }
+       }
+
+       DRM_DEBUG_KMS("No pipe for DP port %c found\n", port_name(port));
+
+       /* must initialize pipe to something for the asserts */
+       *pipe = PIPE_A;
+
+       return false;
+}
+
+bool intel_dp_port_enabled(struct drm_i915_private *dev_priv,
+                          i915_reg_t dp_reg, enum port port,
+                          enum pipe *pipe)
+{
+       bool ret;
+       u32 val;
+
+       val = I915_READ(dp_reg);
+
+       ret = val & DP_PORT_EN;
+
+       /* asserts want to know the pipe even if the port is disabled */
+       if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
+               *pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
+       else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
+               ret &= cpt_dp_port_selected(dev_priv, port, pipe);
+       else if (IS_CHERRYVIEW(dev_priv))
+               *pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
+       else
+               *pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
+
+       return ret;
+}
+
 static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
                                  enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-       enum port port = encoder->port;
-       u32 tmp;
        bool ret;
 
        if (!intel_display_power_get_if_enabled(dev_priv,
                                                encoder->power_domain))
                return false;
 
-       ret = false;
-
-       tmp = I915_READ(intel_dp->output_reg);
-
-       if (!(tmp & DP_PORT_EN))
-               goto out;
-
-       if (IS_GEN7(dev_priv) && port == PORT_A) {
-               *pipe = PORT_TO_PIPE_CPT(tmp);
-       } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
-               enum pipe p;
-
-               for_each_pipe(dev_priv, p) {
-                       u32 trans_dp = I915_READ(TRANS_DP_CTL(p));
-                       if (TRANS_DP_PIPE_TO_PORT(trans_dp) == port) {
-                               *pipe = p;
-                               ret = true;
-
-                               goto out;
-                       }
-               }
-
-               DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n",
-                             i915_mmio_reg_offset(intel_dp->output_reg));
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               *pipe = DP_PORT_TO_PIPE_CHV(tmp);
-       } else {
-               *pipe = PORT_TO_PIPE(tmp);
-       }
+       ret = intel_dp_port_enabled(dev_priv, intel_dp->output_reg,
+                                   encoder->port, pipe);
 
-       ret = true;
-
-out:
        intel_display_power_put(dev_priv, encoder->power_domain);
 
        return ret;
@@ -2883,7 +2897,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp,
                }
                I915_WRITE(DP_TP_CTL(port), temp);
 
-       } else if ((IS_GEN7(dev_priv) && port == PORT_A) ||
+       } else if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
                   (HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
                *DP &= ~DP_LINK_TRAIN_MASK_CPT;
 
@@ -3041,11 +3055,11 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
        edp_panel_vdd_off_sync(intel_dp);
 
        /*
-        * VLV seems to get confused when multiple power seqeuencers
+        * VLV seems to get confused when multiple power sequencers
         * have the same port selected (even if only one has power/vdd
         * enabled). The failure manifests as vlv_wait_port_ready() failing
         * CHV on the other hand doesn't seem to mind having the same port
-        * selected in multiple power seqeuencers, but let's clear the
+        * selected in multiple power sequencers, but let's clear the
         * port select always when logically disconnecting a power sequencer
         * from a port.
         */
@@ -3195,14 +3209,14 @@ uint8_t
 intel_dp_voltage_max(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
-       enum port port = dp_to_dig_port(intel_dp)->base.port;
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       enum port port = encoder->port;
 
-       if (INTEL_GEN(dev_priv) >= 9) {
-               struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       if (HAS_DDI(dev_priv))
                return intel_ddi_dp_voltage_max(encoder);
-       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+       else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
-       else if (IS_GEN7(dev_priv) && port == PORT_A)
+       else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
        else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
                return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
@@ -3214,33 +3228,11 @@ uint8_t
 intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
-       enum port port = dp_to_dig_port(intel_dp)->base.port;
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       enum port port = encoder->port;
 
-       if (INTEL_GEN(dev_priv) >= 9) {
-               switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_3;
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_2;
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_1;
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL_3:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_0;
-               default:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_0;
-               }
-       } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-               switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
-                       return DP_TRAIN_PRE_EMPH_LEVEL_3;
-               case DP_TRAIN_VOLTAGE_SWING_LEVEL