]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
Merge tag 'gvt-next-2016-10-27' of https://github.com/01org/gvt-linux into drm-intel...
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 27 Oct 2016 08:33:17 +0000 (10:33 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 27 Oct 2016 08:33:17 +0000 (10:33 +0200)
gvt-next-2016-10-27

- Resolve current left build issue with ACPI=n and 32bit kernel
- TLB workaround from Arkadiusz
- vGPU reset fix from Ping
- workload scheduler nesting sleep fix from Changbin
- more misc fixes for sparse warnings and cleanups

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
drivers/gpu/drm/i915/Kconfig
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/gvt.c
drivers/gpu/drm/i915/gvt/gvt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/opregion.c
drivers/gpu/drm/i915/gvt/render.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/gvt/vgpu.c

index af13c624de9dda3391b839d3f33ef650f5490934..df96aed6975a8caa613156839e98b1bde8c6349c 100644 (file)
@@ -87,6 +87,7 @@ config DRM_I915_USERPTR
 config DRM_I915_GVT
         bool "Enable Intel GVT-g graphics virtualization host support"
         depends on DRM_I915
+        depends on 64BIT
         default n
         help
          Choose this option if you want to enable Intel GVT-g graphics
index aafb57e26288d8d69b0af4a51de500fa54815738..0084ece8d8ffd17b24225e64a14384c9eec416bb 100644 (file)
@@ -1145,7 +1145,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s,
                info->event = PRIMARY_B_FLIP_DONE;
                break;
        case MI_DISPLAY_FLIP_SKL_PLANE_1_C:
-               info->pipe = PIPE_B;
+               info->pipe = PIPE_C;
                info->event = PRIMARY_C_FLIP_DONE;
                break;
        default:
@@ -1201,20 +1201,19 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
        struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
        struct intel_vgpu *vgpu = s->vgpu;
 
-#define write_bits(reg, e, s, v) do { \
-       vgpu_vreg(vgpu, reg) &= ~GENMASK(e, s); \
-       vgpu_vreg(vgpu, reg) |= (v << s); \
-} while (0)
-
-       write_bits(info->surf_reg, 31, 12, info->surf_val);
-       if (IS_SKYLAKE(dev_priv))
-               write_bits(info->stride_reg, 9, 0, info->stride_val);
-       else
-               write_bits(info->stride_reg, 15, 6, info->stride_val);
-       write_bits(info->ctrl_reg, IS_SKYLAKE(dev_priv) ? 12 : 10,
-                  10, info->tile_val);
-
-#undef write_bits
+       set_mask_bits(&vgpu_vreg(vgpu, info->surf_reg), GENMASK(31, 12),
+                     info->surf_val << 12);
+       if (IS_SKYLAKE(dev_priv)) {
+               set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(9, 0),
+                             info->stride_val);
+               set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(12, 10),
+                             info->tile_val << 10);
+       } else {
+               set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(15, 6),
+                             info->stride_val << 6);
+               set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(10, 10),
+                             info->tile_val << 10);
+       }
 
        vgpu_vreg(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++;
        intel_vgpu_trigger_virtual_event(vgpu, info->event);
index 2cc761328569c972cc7cb48962dfe7b53acec5f4..6554da9f9f5b7f753bce659c7d12c425d38cd368 100644 (file)
@@ -276,7 +276,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
        pte = readq(addr);
 #else
        pte = ioread32(addr);
-       pte |= ioread32(addr + 4) << 32;
+       pte |= (u64)ioread32(addr + 4) << 32;
 #endif
        return pte;
 }
@@ -1944,7 +1944,7 @@ static int create_scratch_page(struct intel_vgpu *vgpu)
        mfn = intel_gvt_hypervisor_virt_to_mfn(vaddr);
 
        if (mfn == INTEL_GVT_INVALID_ADDR) {
-               gvt_err("fail to translate vaddr:0x%llx\n", (u64)vaddr);
+               gvt_err("fail to translate vaddr: 0x%p\n", vaddr);
                __free_page(gtt->scratch_page);
                gtt->scratch_page = NULL;
                return -ENXIO;
index 31b59d40f3fb41ad86293812ba160b2ec1129fe8..385969a8921680f71e1f57a0843f605d20538cea 100644 (file)
@@ -65,6 +65,8 @@ struct intel_gvt_io_emulation_ops intel_gvt_io_emulation_ops = {
  */
 int intel_gvt_init_host(void)
 {
+       int ret;
+
        if (intel_gvt_host.initialized)
                return 0;
 
@@ -90,7 +92,8 @@ int intel_gvt_init_host(void)
                return -EINVAL;
 
        /* Try to detect if we're running in host instead of VM. */
-       if (!intel_gvt_hypervisor_detect_host())
+       ret = intel_gvt_hypervisor_detect_host();
+       if (ret)
                return -ENODEV;
 
        gvt_dbg_core("Running with hypervisor %s in host mode\n",
@@ -103,19 +106,20 @@ int intel_gvt_init_host(void)
 static void init_device_info(struct intel_gvt *gvt)
 {
        struct intel_gvt_device_info *info = &gvt->device_info;
+       struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
 
        if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
                info->max_support_vgpus = 8;
                info->cfg_space_size = 256;
                info->mmio_size = 2 * 1024 * 1024;
                info->mmio_bar = 0;
-               info->msi_cap_offset = IS_SKYLAKE(gvt->dev_priv) ? 0xac : 0x90;
                info->gtt_start_offset = 8 * 1024 * 1024;
                info->gtt_entry_size = 8;
                info->gtt_entry_size_shift = 3;
                info->gmadr_bytes_in_cmd = 8;
                info->max_surface_size = 36 * 1024 * 1024;
        }
+       info->msi_cap_offset = pdev->msi_cap;
 }
 
 static int gvt_service_thread(void *data)
index 11df62b542b19655e2dcc9c7e53caa13aa28491e..62fc9e3ac5c6d324d0fba10ea530a678c0c3400a 100644 (file)
@@ -382,6 +382,8 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu);
 int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa);
 
 int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
+int setup_vgpu_mmio(struct intel_vgpu *vgpu);
+void populate_pvinfo_page(struct intel_vgpu *vgpu);
 
 #include "mpt.h"
 
index 3e74fb3d4aa93398381e5a032398886f3a313dda..9ab1f95dddc5dd73eb272d9f5806955841d6b1e9 100644 (file)
@@ -239,7 +239,11 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset,
        vgpu->resetting = true;
 
        intel_vgpu_stop_schedule(vgpu);
-       if (scheduler->current_vgpu == vgpu) {
+       /*
+        * The current_vgpu will set to NULL after stopping the
+        * scheduler when the reset is triggered by current vgpu.
+        */
+       if (scheduler->current_vgpu == NULL) {
                mutex_unlock(&vgpu->gvt->lock);
                intel_gvt_wait_vgpu_idle(vgpu);
                mutex_lock(&vgpu->gvt->lock);
@@ -247,6 +251,16 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset,
 
        intel_vgpu_reset_execlist(vgpu, bitmap);
 
+       /* full GPU reset */
+       if (bitmap == 0xff) {
+               mutex_unlock(&vgpu->gvt->lock);
+               intel_vgpu_clean_gtt(vgpu);
+               mutex_lock(&vgpu->gvt->lock);
+               setup_vgpu_mmio(vgpu);
+               populate_pvinfo_page(vgpu);
+               intel_vgpu_init_gtt(vgpu);
+       }
+
        vgpu->resetting = false;
 
        return 0;
@@ -258,6 +272,7 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
        u32 data;
        u64 bitmap = 0;
 
+       write_vreg(vgpu, offset, p_data, bytes);
        data = vgpu_vreg(vgpu, offset);
 
        if (data & GEN6_GRDOM_FULL) {
@@ -1305,7 +1320,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
        int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
        struct intel_vgpu_execlist *execlist;
        u32 data = *(u32 *)p_data;
-       int ret;
+       int ret = 0;
 
        if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1))
                return -EINVAL;
@@ -1313,12 +1328,15 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
        execlist = &vgpu->execlist[ring_id];
 
        execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data;
-       if (execlist->elsp_dwords.index == 3)
+       if (execlist->elsp_dwords.index == 3) {
                ret = intel_vgpu_submit_execlist(vgpu, ring_id);
+               if(ret)
+                       gvt_err("fail submit workload on ring %d\n", ring_id);
+       }
 
        ++execlist->elsp_dwords.index;
        execlist->elsp_dwords.index &= 0x3;
-       return 0;
+       return ret;
 }
 
 static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
index 973c8a9d0b1534c9125a00a2a6b584997871fbf5..95218913b0bc19f089fa71c0c21ed445f5c96096 100644 (file)
@@ -163,7 +163,7 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa)
  */
 void intel_gvt_clean_opregion(struct intel_gvt *gvt)
 {
-       iounmap(gvt->opregion.opregion_va);
+       memunmap(gvt->opregion.opregion_va);
        gvt->opregion.opregion_va = NULL;
 }
 
@@ -181,8 +181,8 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt)
        pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION,
                        &gvt->opregion.opregion_pa);
 
-       gvt->opregion.opregion_va = acpi_os_ioremap(gvt->opregion.opregion_pa,
-                       INTEL_GVT_OPREGION_SIZE);
+       gvt->opregion.opregion_va = memremap(gvt->opregion.opregion_pa,
+                                            INTEL_GVT_OPREGION_SIZE, MEMREMAP_WB);
        if (!gvt->opregion.opregion_va) {
                gvt_err("fail to map host opregion\n");
                return -EFAULT;
index feebb65ba6417c8df4268aa9f9904f2cb54cb89a..3af894b3d257c9012682912437b105512680cf83 100644 (file)
@@ -118,6 +118,7 @@ static u32 gen9_render_mocs_L3[32];
 static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
 {
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+       enum forcewake_domains fw;
        i915_reg_t reg;
        u32 regs[] = {
                [RCS] = 0x4260,
@@ -135,11 +136,25 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
 
        reg = _MMIO(regs[ring_id]);
 
-       I915_WRITE(reg, 0x1);
+       /* WaForceWakeRenderDuringMmioTLBInvalidate:skl
+        * we need to put a forcewake when invalidating RCS TLB caches,
+        * otherwise device can go to RC6 state and interrupt invalidation
+        * process
+        */
+       fw = intel_uncore_forcewake_for_reg(dev_priv, reg,
+                                           FW_REG_READ | FW_REG_WRITE);
+       if (ring_id == RCS && IS_SKYLAKE(dev_priv))
+               fw |= FORCEWAKE_RENDER;
 
-       if (wait_for_atomic((I915_READ(reg) == 0), 50))
+       intel_uncore_forcewake_get(dev_priv, fw);
+
+       I915_WRITE_FW(reg, 0x1);
+
+       if (wait_for_atomic((I915_READ_FW(reg) == 0), 50))
                gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id);
 
+       intel_uncore_forcewake_put(dev_priv, fw);
+
        gvt_dbg_core("invalidate TLB for ring %d\n", ring_id);
 }
 
@@ -162,6 +177,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
        if (!IS_SKYLAKE(dev_priv))
                return;
 
+       offset.reg = regs[ring_id];
        for (i = 0; i < 64; i++) {
                gen9_render_mocs[ring_id][i] = I915_READ(offset);
                I915_WRITE(offset, vgpu_vreg(vgpu, offset));
@@ -199,6 +215,7 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
        if (!IS_SKYLAKE(dev_priv))
                return;
 
+       offset.reg = regs[ring_id];
        for (i = 0; i < 64; i++) {
                vgpu_vreg(vgpu, offset) = I915_READ(offset);
                I915_WRITE(offset, gen9_render_mocs[ring_id][i]);
index e96eaeebeb0a4f41a6ce6acfe670748a292621f0..f7e320b9b17a3178c0d93040aac186a720427635 100644 (file)
@@ -402,19 +402,24 @@ static int workload_thread(void *priv)
        struct intel_vgpu_workload *workload = NULL;
        int ret;
        bool need_force_wake = IS_SKYLAKE(gvt->dev_priv);
+       DEFINE_WAIT_FUNC(wait, woken_wake_function);
 
        kfree(p);
 
        gvt_dbg_core("workload thread for ring %d started\n", ring_id);
 
        while (!kthread_should_stop()) {
-               ret = wait_event_interruptible(scheduler->waitq[ring_id],
-                               kthread_should_stop() ||
-                               (workload = pick_next_workload(gvt, ring_id)));
-
-               WARN_ON_ONCE(ret);
-
-               if (kthread_should_stop())
+               add_wait_queue(&scheduler->waitq[ring_id], &wait);
+               do {
+                       workload = pick_next_workload(gvt, ring_id);
+                       if (workload)
+                               break;
+                       wait_woken(&wait, TASK_INTERRUPTIBLE,
+                                  MAX_SCHEDULE_TIMEOUT);
+               } while (!kthread_should_stop());
+               remove_wait_queue(&scheduler->waitq[ring_id], &wait);
+
+               if (!workload)
                        break;
 
                mutex_lock(&scheduler_mutex);
index 9401436d721fe922adde13d1f281026e50bf8c16..4f54005b976d4f5308845deea643ec03ff9dfb7a 100644 (file)
@@ -41,7 +41,7 @@ static void clean_vgpu_mmio(struct intel_vgpu *vgpu)
        vgpu->mmio.vreg = vgpu->mmio.sreg = NULL;
 }
 
-static int setup_vgpu_mmio(struct intel_vgpu *vgpu)
+int setup_vgpu_mmio(struct intel_vgpu *vgpu)
 {
        struct intel_gvt *gvt = vgpu->gvt;
        const struct intel_gvt_device_info *info = &gvt->device_info;
@@ -103,7 +103,7 @@ static void setup_vgpu_cfg_space(struct intel_vgpu *vgpu,
        }
 }
 
-static void populate_pvinfo_page(struct intel_vgpu *vgpu)
+void populate_pvinfo_page(struct intel_vgpu *vgpu)
 {
        /* setup the ballooning information */
        vgpu_vreg64(vgpu, vgtif_reg(magic)) = VGT_MAGIC;