Commit bc9ebca2 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-fixes-2018-04-19' of...

Merge tag 'drm-intel-next-fixes-2018-04-19' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Fix for FDO #105549: Avoid OOPS on bad VBT (Jani)
- Fix rare pre-emption race (Chris)
- Fix RC6 race against PM transitions (Tvrtko)

* tag 'drm-intel-next-fixes-2018-04-19' of git://anongit.freedesktop.org/drm/drm-intel:
  drm/i915/audio: Fix audio detection issue on GLK
  drm/i915: Call i915_perf_fini() on init_hw error unwind
  drm/i915/bios: filter out invalid DDC pins from VBT child devices
  drm/i915/pmu: Inspect runtime PM state more carefully while estimating RC6
  drm/i915: Do no use kfree() to free a kmem_cache_alloc() return value
  drm/i915/execlists: Clear user-active flag on preemption completion
  drm/i915/gvt: Add drm_format_mod update
  drm/i915/gvt: Disable primary/sprite/cursor plane at virtual display initialization
  drm/i915/gvt: Delete redundant error message in fb_decode.c
  drm/i915/gvt: Cancel dma map when resetting ggtt entries
  drm/i915/gvt: Missed to cancel dma map for ggtt entries
  drm/i915/gvt: Make MI_USER_INTERRUPT nop in cmd parser
  drm/i915/gvt: Mark expected switch fall-through in handle_g2v_notification
  drm/i915/gvt: throw error on unhandled vfio ioctls
parents e1898f99 b4615730
...@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s) ...@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
{ {
set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt, set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
s->workload->pending_events); s->workload->pending_events);
patch_value(s, cmd_ptr(s, 0), MI_NOOP);
return 0; return 0;
} }
......
...@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = { ...@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
static void emulate_monitor_status_change(struct intel_vgpu *vgpu) static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
{ {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
int pipe;
vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT | vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
SDE_PORTC_HOTPLUG_CPT | SDE_PORTC_HOTPLUG_CPT |
SDE_PORTD_HOTPLUG_CPT); SDE_PORTD_HOTPLUG_CPT);
...@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu) ...@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
if (IS_BROADWELL(dev_priv)) if (IS_BROADWELL(dev_priv))
vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
/* Disable Primary/Sprite/Cursor plane */
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, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
} }
......
...@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf, ...@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
struct intel_vgpu_fb_info *fb_info) struct intel_vgpu_fb_info *fb_info)
{ {
gvt_dmabuf->drm_format = fb_info->drm_format; gvt_dmabuf->drm_format = fb_info->drm_format;
gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
gvt_dmabuf->width = fb_info->width; gvt_dmabuf->width = fb_info->width;
gvt_dmabuf->height = fb_info->height; gvt_dmabuf->height = fb_info->height;
gvt_dmabuf->stride = fb_info->stride; gvt_dmabuf->stride = fb_info->stride;
......
...@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, ...@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
plane->hw_format = fmt; plane->hw_format = fmt;
plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK; plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
return -EINVAL; return -EINVAL;
}
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n", gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
(unsigned long)plane->base); plane->base);
return -EINVAL; return -EINVAL;
} }
...@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, ...@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
alpha_plane, alpha_force); alpha_plane, alpha_force);
plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK; plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
return -EINVAL; return -EINVAL;
}
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n", gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
(unsigned long)plane->base); plane->base);
return -EINVAL; return -EINVAL;
} }
...@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu, ...@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
plane->drm_format = drm_format; plane->drm_format = drm_format;
plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK; plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) { if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
return -EINVAL; return -EINVAL;
}
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n", gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
(unsigned long)plane->base); plane->base);
return -EINVAL; return -EINVAL;
} }
......
...@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm, ...@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm,
false, 0, mm->vgpu); false, 0, mm->vgpu);
} }
static void ggtt_get_host_entry(struct intel_vgpu_mm *mm,
struct intel_gvt_gtt_entry *entry, unsigned long index)
{
struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);
pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu);
}
static void ggtt_set_host_entry(struct intel_vgpu_mm *mm, static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
struct intel_gvt_gtt_entry *entry, unsigned long index) struct intel_gvt_gtt_entry *entry, unsigned long index)
{ {
...@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off, ...@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off,
return ret; return ret;
} }
static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,
struct intel_gvt_gtt_entry *entry)
{
struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
unsigned long pfn;
pfn = pte_ops->get_pfn(entry);
if (pfn != vgpu->gvt->gtt.scratch_mfn)
intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
pfn << PAGE_SHIFT);
}
static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
void *p_data, unsigned int bytes) void *p_data, unsigned int bytes)
{ {
...@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
bytes); bytes);
m = e;
if (ops->test_present(&e)) { if (ops->test_present(&e)) {
gfn = ops->get_pfn(&e); gfn = ops->get_pfn(&e);
m = e;
/* one PTE update may be issued in multiple writes and the /* one PTE update may be issued in multiple writes and the
* first write may not construct a valid gfn * first write may not construct a valid gfn
...@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, ...@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
ops->set_pfn(&m, gvt->gtt.scratch_mfn); ops->set_pfn(&m, gvt->gtt.scratch_mfn);
} else } else
ops->set_pfn(&m, dma_addr >> PAGE_SHIFT); ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
} else } else {
ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
ggtt_invalidate_pte(vgpu, &m);
ops->set_pfn(&m, gvt->gtt.scratch_mfn); ops->set_pfn(&m, gvt->gtt.scratch_mfn);
ops->clear_present(&m);
}
out: out:
ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index); ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
...@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu) ...@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
return PTR_ERR(gtt->ggtt_mm); return PTR_ERR(gtt->ggtt_mm);
} }
intel_vgpu_reset_ggtt(vgpu); intel_vgpu_reset_ggtt(vgpu, false);
return create_scratch_page_tree(vgpu); return create_scratch_page_tree(vgpu);
} }
...@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu) ...@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu)
/** /**
* intel_vgpu_reset_ggtt - reset the GGTT entry * intel_vgpu_reset_ggtt - reset the GGTT entry
* @vgpu: a vGPU * @vgpu: a vGPU
* @invalidate_old: invalidate old entries
* *
* This function is called at the vGPU create stage * This function is called at the vGPU create stage
* to reset all the GGTT entries. * to reset all the GGTT entries.
* *
*/ */
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
{ {
struct intel_gvt *gvt = vgpu->gvt; struct intel_gvt *gvt = vgpu->gvt;
struct drm_i915_private *dev_priv = gvt->dev_priv; struct drm_i915_private *dev_priv = gvt->dev_priv;
struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops; struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE}; struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
struct intel_gvt_gtt_entry old_entry;
u32 index; u32 index;
u32 num_entries; u32 num_entries;
...@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu) ...@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT; index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT; num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
while (num_entries--) while (num_entries--) {
if (invalidate_old) {
ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
ggtt_invalidate_pte(vgpu, &old_entry);
}
ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++); ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
}
index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT; index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT; num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
while (num_entries--) while (num_entries--) {
if (invalidate_old) {
ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
ggtt_invalidate_pte(vgpu, &old_entry);
}
ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++); ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
}
ggtt_invalidate(dev_priv); ggtt_invalidate(dev_priv);
} }
...@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) ...@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
* removing the shadow pages. * removing the shadow pages.
*/ */
intel_vgpu_destroy_all_ppgtt_mm(vgpu); intel_vgpu_destroy_all_ppgtt_mm(vgpu);
intel_vgpu_reset_ggtt(vgpu); intel_vgpu_reset_ggtt(vgpu, true);
} }
...@@ -193,7 +193,7 @@ struct intel_vgpu_gtt { ...@@ -193,7 +193,7 @@ struct intel_vgpu_gtt {
extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu); extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu); extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu); void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
extern int intel_gvt_init_gtt(struct intel_gvt *gvt); extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
......
...@@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification) ...@@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)
switch (notification) { switch (notification) {
case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE: case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE:
root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY; root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY;
/* fall through */
case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE: case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE:
mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps); mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps);
return PTR_ERR_OR_ZERO(mm); return PTR_ERR_OR_ZERO(mm);
......
...@@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd, ...@@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
} }
return 0; return -ENOTTY;
} }
static ssize_t static ssize_t
......
...@@ -1102,30 +1102,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1102,30 +1102,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
ret = i915_ggtt_probe_hw(dev_priv); ret = i915_ggtt_probe_hw(dev_priv);
if (ret) if (ret)
return ret; goto err_perf;
/* WARNING: Apparently we must kick fbdev drivers before vgacon, /*
* otherwise the vga fbdev driver falls over. */ * WARNING: Apparently we must kick fbdev drivers before vgacon,
* otherwise the vga fbdev driver falls over.
*/
ret = i915_kick_out_firmware_fb(dev_priv); ret = i915_kick_out_firmware_fb(dev_priv);
if (ret) { if (ret) {
DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
goto out_ggtt; goto err_ggtt;
} }
ret = i915_kick_out_vgacon(dev_priv); ret = i915_kick_out_vgacon(dev_priv);
if (ret) { if (ret) {
DRM_ERROR("failed to remove conflicting VGA console\n"); DRM_ERROR("failed to remove conflicting VGA console\n");
goto out_ggtt; goto err_ggtt;
} }
ret = i915_ggtt_init_hw(dev_priv); ret = i915_ggtt_init_hw(dev_priv);
if (ret) if (ret)
return ret; goto err_ggtt;
ret = i915_ggtt_enable_hw(dev_priv); ret = i915_ggtt_enable_hw(dev_priv);
if (ret) { if (ret) {
DRM_ERROR("failed to enable GGTT\n"); DRM_ERROR("failed to enable GGTT\n");
goto out_ggtt; goto err_ggtt;
} }
pci_set_master(pdev); pci_set_master(pdev);
...@@ -1136,7 +1138,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1136,7 +1138,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
if (ret) { if (ret) {
DRM_ERROR("failed to set DMA mask\n"); DRM_ERROR("failed to set DMA mask\n");
goto out_ggtt; goto err_ggtt;
} }
} }
...@@ -1154,7 +1156,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1154,7 +1156,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
if (ret) { if (ret) {
DRM_ERROR("failed to set DMA mask\n"); DRM_ERROR("failed to set DMA mask\n");
goto out_ggtt; goto err_ggtt;
} }
} }
...@@ -1187,13 +1189,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) ...@@ -1187,13 +1189,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
ret = intel_gvt_init(dev_priv); ret = intel_gvt_init(dev_priv);
if (ret) if (ret)
goto out_ggtt; goto err_ggtt;
return 0; return 0;
out_ggtt: err_ggtt:
i915_ggtt_cleanup_hw(dev_priv); i915_ggtt_cleanup_hw(dev_priv);
err_perf:
i915_perf_fini(dev_priv);
return ret; return ret;
} }
......
...@@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb) ...@@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
err = radix_tree_insert(handles_vma, handle, vma); err = radix_tree_insert(handles_vma, handle, vma);
if (unlikely(err)) { if (unlikely(err)) {
kfree(lut); kmem_cache_free(eb->i915->luts, lut);
goto err_obj; goto err_obj;
} }
......
...@@ -473,6 +473,18 @@ static u64 get_rc6(struct drm_i915_private *i915) ...@@ -473,6 +473,18 @@ static u64 get_rc6(struct drm_i915_private *i915)
spin_lock_irqsave(&i915->pmu.lock, flags); spin_lock_irqsave(&i915->pmu.lock, flags);
spin_lock(&kdev->power.lock); spin_lock(&kdev->power.lock);
/*
* After the above branch intel_runtime_pm_get_if_in_use failed
* to get the runtime PM reference we cannot assume we are in
* runtime suspend since we can either: a) race with coming out
* of it before we took the power.lock, or b) there are other
* states than suspended which can bring us here.
*
* We need to double-check that we are indeed currently runtime
* suspended and if not we cannot do better than report the last
* known RC6 value.
*/
if (kdev->power.runtime_status == RPM_SUSPENDED) {
if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
i915->pmu.suspended_jiffies_last = i915->pmu.suspended_jiffies_last =
kdev->power.suspended_jiffies; kdev->power.suspended_jiffies;
...@@ -481,12 +493,17 @@ static u64 get_rc6(struct drm_i915_private *i915) ...@@ -481,12 +493,17 @@ static u64 get_rc6(struct drm_i915_private *i915)
i915->pmu.suspended_jiffies_last; i915->pmu.suspended_jiffies_last;
val += jiffies - kdev->power.accounting_timestamp; val += jiffies - kdev->power.accounting_timestamp;
spin_unlock(&kdev->power.lock);
val = jiffies_to_nsecs(val); val = jiffies_to_nsecs(val);
val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
} else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
} else {
val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
}
spin_unlock(&kdev->power.lock);
spin_unlock_irqrestore(&i915->pmu.lock, flags); spin_unlock_irqrestore(&i915->pmu.lock, flags);
} }
......
...@@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev, ...@@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
struct drm_i915_private *dev_priv = kdev_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
u32 tmp; u32 tmp;
if (!IS_GEN9_BC(dev_priv)) if (!IS_GEN9(dev_priv))
return; return;
i915_audio_component_get_power(kdev); i915_audio_component_get_power(kdev);
......
...@@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, ...@@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
return; return;
aux_channel = child->aux_channel; aux_channel = child->aux_channel;
ddc_pin = child->ddc_pin;
is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING; is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT; is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
...@@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, ...@@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port)); DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
if (is_dvi) { if (is_dvi) {
info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin); ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin);
if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) {
info->alternate_ddc_pin = ddc_pin;
sanitize_ddc_pin(dev_priv, port); sanitize_ddc_pin(dev_priv, port);
} else {
DRM_DEBUG_KMS("Port %c has invalid DDC pin %d, "
"sticking to defaults\n",
port_name(port), ddc_pin);
}
} }
if (is_dp) { if (is_dp) {
......
...@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) ...@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
* know the next preemption status we see corresponds * know the next preemption status we see corresponds
* to this ELSP update. * to this ELSP update.
*/ */
GEM_BUG_ON(!execlists_is_active(execlists,
EXECLISTS_ACTIVE_USER));
GEM_BUG_ON(!port_count(&port[0])); GEM_BUG_ON(!port_count(&port[0]));
if (port_count(&port[0]) > 1) if (port_count(&port[0]) > 1)
goto unlock; goto unlock;
...@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) ...@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
memset(port, 0, sizeof(*port)); memset(port, 0, sizeof(*port));
port++; port++;
} }
execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
} }
static void execlists_cancel_requests(struct intel_engine_cs *engine) static void execlists_cancel_requests(struct intel_engine_cs *engine)
...@@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data) ...@@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data)
if (fw) if (fw)
intel_uncore_forcewake_put(dev_priv, execlists->fw_domains); intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);
/* If the engine is now idle, so should be the flag; and vice versa. */
GEM_BUG_ON(execlists_is_active(&engine->execlists,
EXECLISTS_ACTIVE_USER) ==
!port_isset(engine->execlists.port));
} }
static void queue_request(struct intel_engine_cs *engine, static void queue_request(struct intel_engine_cs *engine,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment