diff options
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/mmio.c')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/mmio.c | 121 |
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; } |