summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/gvt/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/render.c')
-rw-r--r--drivers/gpu/drm/i915/gvt/render.c102
1 files changed, 77 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/gvt/render.c b/drivers/gpu/drm/i915/gvt/render.c
index a5e11d89df2f..2ea542257f03 100644
--- a/drivers/gpu/drm/i915/gvt/render.c
+++ b/drivers/gpu/drm/i915/gvt/render.c
@@ -35,6 +35,7 @@
#include "i915_drv.h"
#include "gvt.h"
+#include "trace.h"
struct render_mmio {
int ring_id;
@@ -206,18 +207,16 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) {
- gen9_render_mocs[ring_id][i] = I915_READ(offset);
+ gen9_render_mocs[ring_id][i] = I915_READ_FW(offset);
I915_WRITE(offset, vgpu_vreg(vgpu, offset));
- POSTING_READ(offset);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- gen9_render_mocs_L3[i] = I915_READ(l3_offset);
- I915_WRITE(l3_offset, vgpu_vreg(vgpu, l3_offset));
- POSTING_READ(l3_offset);
+ gen9_render_mocs_L3[i] = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, vgpu_vreg(vgpu, l3_offset));
l3_offset.reg += 4;
}
}
@@ -241,18 +240,16 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
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]);
- POSTING_READ(offset);
+ vgpu_vreg(vgpu, offset) = I915_READ_FW(offset);
+ I915_WRITE_FW(offset, gen9_render_mocs[ring_id][i]);
offset.reg += 4;
}
if (ring_id == RCS) {
l3_offset.reg = 0xb020;
for (i = 0; i < 32; i++) {
- vgpu_vreg(vgpu, l3_offset) = I915_READ(l3_offset);
- I915_WRITE(l3_offset, gen9_render_mocs_L3[i]);
- POSTING_READ(l3_offset);
+ vgpu_vreg(vgpu, l3_offset) = I915_READ_FW(l3_offset);
+ I915_WRITE_FW(l3_offset, gen9_render_mocs_L3[i]);
l3_offset.reg += 4;
}
}
@@ -260,7 +257,8 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
#define CTX_CONTEXT_CONTROL_VAL 0x03
-void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id)
+/* Switch ring mmio values (context) from host to a vgpu. */
+static void switch_mmio_to_vgpu(struct intel_vgpu *vgpu, int ring_id)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct render_mmio *mmio;
@@ -270,6 +268,7 @@ void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id)
u32 ctx_ctrl = reg_state[CTX_CONTEXT_CONTROL_VAL];
u32 inhibit_mask =
_MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
+ i915_reg_t last_reg = _MMIO(0);
if (IS_SKYLAKE(vgpu->gvt->dev_priv)
|| IS_KABYLAKE(vgpu->gvt->dev_priv)) {
@@ -285,7 +284,7 @@ void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- mmio->value = I915_READ(mmio->reg);
+ mmio->value = I915_READ_FW(mmio->reg);
/*
* if it is an inhibit context, load in_context mmio
@@ -302,20 +301,27 @@ void intel_gvt_load_render_mmio(struct intel_vgpu *vgpu, int ring_id)
else
v = vgpu_vreg(vgpu, mmio->reg);
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
- gvt_dbg_render("load reg %x old %x new %x\n",
- i915_mmio_reg_offset(mmio->reg),
- mmio->value, v);
+ trace_render_mmio(vgpu->id, "load",
+ i915_mmio_reg_offset(mmio->reg),
+ mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
+
handle_tlb_pending_event(vgpu, ring_id);
}
-void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id)
+/* Switch ring mmio values (context) from vgpu to host. */
+static void switch_mmio_to_host(struct intel_vgpu *vgpu, int ring_id)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct render_mmio *mmio;
+ i915_reg_t last_reg = _MMIO(0);
u32 v;
int i, array_size;
@@ -332,7 +338,7 @@ void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id)
if (mmio->ring_id != ring_id)
continue;
- vgpu_vreg(vgpu, mmio->reg) = I915_READ(mmio->reg);
+ vgpu_vreg(vgpu, mmio->reg) = I915_READ_FW(mmio->reg);
if (mmio->mask) {
vgpu_vreg(vgpu, mmio->reg) &= ~(mmio->mask << 16);
@@ -343,11 +349,57 @@ void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id)
if (mmio->in_context)
continue;
- I915_WRITE(mmio->reg, v);
- POSTING_READ(mmio->reg);
+ I915_WRITE_FW(mmio->reg, v);
+ last_reg = mmio->reg;
- gvt_dbg_render("restore reg %x old %x new %x\n",
- i915_mmio_reg_offset(mmio->reg),
- mmio->value, v);
+ trace_render_mmio(vgpu->id, "restore",
+ i915_mmio_reg_offset(mmio->reg),
+ mmio->value, v);
}
+
+ /* Make sure the swiched MMIOs has taken effect. */
+ if (likely(INTEL_GVT_MMIO_OFFSET(last_reg)))
+ I915_READ_FW(last_reg);
+}
+
+/**
+ * intel_gvt_switch_render_mmio - switch mmio context of specific engine
+ * @pre: the last vGPU that own the engine
+ * @next: the vGPU to switch to
+ * @ring_id: specify the engine
+ *
+ * If pre is null indicates that host own the engine. If next is null
+ * indicates that we are switching to host workload.
+ */
+void intel_gvt_switch_mmio(struct intel_vgpu *pre,
+ struct intel_vgpu *next, int ring_id)
+{
+ struct drm_i915_private *dev_priv;
+
+ if (WARN_ON(!pre && !next))
+ return;
+
+ gvt_dbg_render("switch ring %d from %s to %s\n", ring_id,
+ pre ? "vGPU" : "host", next ? "vGPU" : "HOST");
+
+ dev_priv = pre ? pre->gvt->dev_priv : next->gvt->dev_priv;
+
+ /**
+ * We are using raw mmio access wrapper to improve the
+ * performace for batch mmio read/write, so we need
+ * handle forcewake mannually.
+ */
+ intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+ /**
+ * TODO: Optimize for vGPU to vGPU switch by merging
+ * switch_mmio_to_host() and switch_mmio_to_vgpu().
+ */
+ if (pre)
+ switch_mmio_to_host(pre, ring_id);
+
+ if (next)
+ switch_mmio_to_vgpu(next, ring_id);
+
+ intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
}