summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/gvt/mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/mmio.c')
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio.c121
1 files changed, 25 insertions, 96 deletions
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
index 1ba3bdb09341..980ec8906b1e 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.c
+++ b/drivers/gpu/drm/i915/gvt/mmio.c
@@ -123,7 +123,6 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
void *p_data, unsigned int bytes)
{
struct intel_gvt *gvt = vgpu->gvt;
- struct intel_gvt_mmio_info *mmio;
unsigned int offset = 0;
int ret = -EINVAL;
@@ -187,32 +186,8 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
goto err;
}
- mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4));
- if (mmio) {
- if (!intel_gvt_mmio_is_unalign(gvt, mmio->offset)) {
- if (WARN_ON(offset + bytes > mmio->offset + mmio->size))
- goto err;
- if (WARN_ON(mmio->offset != offset))
- goto err;
- }
- ret = mmio->read(vgpu, offset, p_data, bytes);
- } else {
- ret = intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
-
- if (!vgpu->mmio.disable_warn_untrack) {
- gvt_vgpu_err("read untracked MMIO %x(%dB) val %x\n",
- offset, bytes, *(u32 *)p_data);
-
- if (offset == 0x206c) {
- gvt_vgpu_err("------------------------------------------\n");
- gvt_vgpu_err("likely triggers a gfx reset\n");
- gvt_vgpu_err("------------------------------------------\n");
- vgpu->mmio.disable_warn_untrack = true;
- }
- }
- }
-
- if (ret)
+ ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, true);
+ if (ret < 0)
goto err;
intel_gvt_mmio_set_accessed(gvt, offset);
@@ -239,9 +214,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
void *p_data, unsigned int bytes)
{
struct intel_gvt *gvt = vgpu->gvt;
- struct intel_gvt_mmio_info *mmio;
unsigned int offset = 0;
- u32 old_vreg = 0, old_sreg = 0;
int ret = -EINVAL;
if (vgpu->failsafe) {
@@ -296,66 +269,10 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
return ret;
}
- mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4));
- if (!mmio && !vgpu->mmio.disable_warn_untrack)
- gvt_dbg_mmio("vgpu%d: write untracked MMIO %x len %d val %x\n",
- vgpu->id, offset, bytes, *(u32 *)p_data);
-
- if (!intel_gvt_mmio_is_unalign(gvt, offset)) {
- if (WARN_ON(!IS_ALIGNED(offset, bytes)))
- goto err;
- }
-
- if (mmio) {
- u64 ro_mask = mmio->ro_mask;
-
- if (!intel_gvt_mmio_is_unalign(gvt, mmio->offset)) {
- if (WARN_ON(offset + bytes > mmio->offset + mmio->size))
- goto err;
- if (WARN_ON(mmio->offset != offset))
- goto err;
- }
-
- if (intel_gvt_mmio_has_mode_mask(gvt, mmio->offset)) {
- old_vreg = vgpu_vreg(vgpu, offset);
- old_sreg = vgpu_sreg(vgpu, offset);
- }
-
- if (!ro_mask) {
- ret = mmio->write(vgpu, offset, p_data, bytes);
- } else {
- /* Protect RO bits like HW */
- u64 data = 0;
-
- /* all register bits are RO. */
- if (ro_mask == ~(u64)0) {
- gvt_vgpu_err("try to write RO reg %x\n",
- offset);
- ret = 0;
- goto out;
- }
- /* keep the RO bits in the virtual register */
- memcpy(&data, p_data, bytes);
- data &= ~mmio->ro_mask;
- data |= vgpu_vreg(vgpu, offset) & mmio->ro_mask;
- ret = mmio->write(vgpu, offset, &data, bytes);
- }
-
- /* higher 16bits of mode ctl regs are mask bits for change */
- if (intel_gvt_mmio_has_mode_mask(gvt, mmio->offset)) {
- u32 mask = vgpu_vreg(vgpu, offset) >> 16;
-
- vgpu_vreg(vgpu, offset) = (old_vreg & ~mask)
- | (vgpu_vreg(vgpu, offset) & mask);
- vgpu_sreg(vgpu, offset) = (old_sreg & ~mask)
- | (vgpu_sreg(vgpu, offset) & mask);
- }
- } else
- ret = intel_vgpu_default_mmio_write(vgpu, offset, p_data,
- bytes);
- if (ret)
+ ret = intel_vgpu_mmio_reg_rw(vgpu, offset, p_data, bytes, false);
+ if (ret < 0)
goto err;
-out:
+
intel_gvt_mmio_set_accessed(gvt, offset);
mutex_unlock(&gvt->lock);
return 0;
@@ -372,20 +289,32 @@ err:
* @vgpu: a vGPU
*
*/
-void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu)
+void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr)
{
struct intel_gvt *gvt = vgpu->gvt;
const struct intel_gvt_device_info *info = &gvt->device_info;
+ void *mmio = gvt->firmware.mmio;
+
+ if (dmlr) {
+ memcpy(vgpu->mmio.vreg, mmio, info->mmio_size);
+ memcpy(vgpu->mmio.sreg, mmio, info->mmio_size);
- memcpy(vgpu->mmio.vreg, gvt->firmware.mmio, info->mmio_size);
- memcpy(vgpu->mmio.sreg, gvt->firmware.mmio, info->mmio_size);
+ vgpu_vreg(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0;
- vgpu_vreg(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0;
+ /* set the bit 0:2(Core C-State ) to C0 */
+ vgpu_vreg(vgpu, GEN6_GT_CORE_STATUS) = 0;
- /* set the bit 0:2(Core C-State ) to C0 */
- vgpu_vreg(vgpu, GEN6_GT_CORE_STATUS) = 0;
+ vgpu->mmio.disable_warn_untrack = false;
+ } else {
+#define GVT_GEN8_MMIO_RESET_OFFSET (0x44200)
+ /* only reset the engine related, so starting with 0x44200
+ * interrupt include DE,display mmio related will not be
+ * touched
+ */
+ memcpy(vgpu->mmio.vreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET);
+ memcpy(vgpu->mmio.sreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET);
+ }
- vgpu->mmio.disable_warn_untrack = false;
}
/**
@@ -405,7 +334,7 @@ int intel_vgpu_init_mmio(struct intel_vgpu *vgpu)
vgpu->mmio.sreg = vgpu->mmio.vreg + info->mmio_size;
- intel_vgpu_reset_mmio(vgpu);
+ intel_vgpu_reset_mmio(vgpu, true);
return 0;
}