Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96980844 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-fixes-2017-12-07' of...

Merge tag 'drm-intel-fixes-2017-12-07' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

- Fix for fd.o bug #103997 CNL eDP + HDMI causing a machine hard hang (James)
- Fix to allow suspending with a wedged GPU to hopefully unwedge it (Chris)
- Fix for Gen2 vblank timestap/frame counter jumps (Ville)
- Revert of a W/A for enabling FBC on CNL/GLK for certain images
  and sizes (Rodrigo)
- Lockdep fix for i915 userptr code (Chris)

gvt-fixes-2017-12-06

- Fix invalid hw reg read value for vGPU (Xiong)
- Fix qemu warning on PCI ROM bar missing (Changbin)
- Workaround preemption regression (Zhenyu)

* tag 'drm-intel-fixes-2017-12-07' of git://anongit.freedesktop.org/drm/drm-intel:
  Revert "drm/i915: Display WA #1133 WaFbcSkipSegments:cnl, glk"
  drm/i915: Call i915_gem_init_userptr() before taking struct_mutex
  drm/i915/gvt: set max priority for gvt context
  drm/i915/gvt: Don't mark vgpu context as inactive when preempted
  drm/i915/gvt: Limit read hw reg to active vgpu
  drm/i915/gvt: Export intel_gvt_render_mmio_to_ring_id()
  drm/i915/gvt: Emulate PCI expansion ROM base address register
  drm/i915/cnl: Mask previous DDI - PLL mapping
  drm/i915: Fix vblank timestamp/frame counter jumps on gen2
  drm/i915: Skip switch-to-kernel-context on suspend when wedged
parents c2ef3a67 d85936ab
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -208,6 +208,20 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
	return 0;
}

static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu,
	unsigned int offset, void *p_data, unsigned int bytes)
{
	u32 *pval = (u32 *)(vgpu_cfg_space(vgpu) + offset);
	u32 new = *(u32 *)(p_data);

	if ((new & PCI_ROM_ADDRESS_MASK) == PCI_ROM_ADDRESS_MASK)
		/* We don't have rom, return size of 0. */
		*pval = 0;
	else
		vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
	return 0;
}

static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
	void *p_data, unsigned int bytes)
{
@@ -300,6 +314,11 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
	}

	switch (rounddown(offset, 4)) {
	case PCI_ROM_ADDRESS:
		if (WARN_ON(!IS_ALIGNED(offset, 4)))
			return -EINVAL;
		return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes);

	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
		if (WARN_ON(!IS_ALIGNED(offset, 4)))
			return -EINVAL;
@@ -375,6 +394,8 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
				pci_resource_len(gvt->dev_priv->drm.pdev, 0);
	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size =
				pci_resource_len(gvt->dev_priv->drm.pdev, 2);

	memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
}

/**
+37 −10
Original line number Diff line number Diff line
@@ -137,17 +137,26 @@ static int new_mmio_info(struct intel_gvt *gvt,
	return 0;
}

static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg)
/**
 * intel_gvt_render_mmio_to_ring_id - convert a mmio offset into ring id
 * @gvt: a GVT device
 * @offset: register offset
 *
 * Returns:
 * Ring ID on success, negative error code if failed.
 */
int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
		unsigned int offset)
{
	enum intel_engine_id id;
	struct intel_engine_cs *engine;

	reg &= ~GENMASK(11, 0);
	offset &= ~GENMASK(11, 0);
	for_each_engine(engine, gvt->dev_priv, id) {
		if (engine->mmio_base == reg)
		if (engine->mmio_base == offset)
			return id;
	}
	return -1;
	return -ENODEV;
}

#define offset_to_fence_num(offset) \
@@ -1398,18 +1407,36 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset,
static int mmio_read_from_hw(struct intel_vgpu *vgpu,
		unsigned int offset, void *p_data, unsigned int bytes)
{
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	struct intel_gvt *gvt = vgpu->gvt;
	struct drm_i915_private *dev_priv = gvt->dev_priv;
	int ring_id;
	u32 ring_base;

	ring_id = intel_gvt_render_mmio_to_ring_id(gvt, offset);
	/**
	 * Read HW reg in following case
	 * a. the offset isn't a ring mmio
	 * b. the offset's ring is running on hw.
	 * c. the offset is ring time stamp mmio
	 */
	if (ring_id >= 0)
		ring_base = dev_priv->engine[ring_id]->mmio_base;

	if (ring_id < 0 || vgpu  == gvt->scheduler.engine_owner[ring_id] ||
	    offset == i915_mmio_reg_offset(RING_TIMESTAMP(ring_base)) ||
	    offset == i915_mmio_reg_offset(RING_TIMESTAMP_UDW(ring_base))) {
		mmio_hw_access_pre(dev_priv);
		vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
		mmio_hw_access_post(dev_priv);
	}

	return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
}

static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
		void *p_data, unsigned int bytes)
{
	int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
	int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
	struct intel_vgpu_execlist *execlist;
	u32 data = *(u32 *)p_data;
	int ret = 0;
@@ -1436,7 +1463,7 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
		void *p_data, unsigned int bytes)
{
	u32 data = *(u32 *)p_data;
	int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
	int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
	bool enable_execlist;

	write_vreg(vgpu, offset, p_data, bytes);
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ struct intel_gvt_mmio_info {
	struct hlist_node node;
};

int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
		unsigned int reg);
unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt);
bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);

+21 −1
Original line number Diff line number Diff line
@@ -131,6 +131,20 @@ static inline bool is_gvt_request(struct drm_i915_gem_request *req)
	return i915_gem_context_force_single_submission(req->ctx);
}

static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id)
{
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	u32 ring_base = dev_priv->engine[ring_id]->mmio_base;
	i915_reg_t reg;

	reg = RING_INSTDONE(ring_base);
	vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
	reg = RING_ACTHD(ring_base);
	vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
	reg = RING_ACTHD_UDW(ring_base);
	vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
}

static int shadow_context_status_change(struct notifier_block *nb,
		unsigned long action, void *data)
{
@@ -175,9 +189,12 @@ static int shadow_context_status_change(struct notifier_block *nb,
		atomic_set(&workload->shadow_ctx_active, 1);
		break;
	case INTEL_CONTEXT_SCHEDULE_OUT:
	case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
		save_ring_hw_state(workload->vgpu, ring_id);
		atomic_set(&workload->shadow_ctx_active, 0);
		break;
	case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
		save_ring_hw_state(workload->vgpu, ring_id);
		break;
	default:
		WARN_ON(1);
		return NOTIFY_OK;
@@ -740,6 +757,9 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
	if (IS_ERR(vgpu->shadow_ctx))
		return PTR_ERR(vgpu->shadow_ctx);

	if (INTEL_INFO(vgpu->gvt->dev_priv)->has_logical_ring_preemption)
		vgpu->shadow_ctx->priority = INT_MAX;

	vgpu->shadow_ctx->engine[RCS].initialised = true;

	bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);
+16 −15
Original line number Diff line number Diff line
@@ -4712,6 +4712,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
	 * state. Fortunately, the kernel_context is disposable and we do
	 * not rely on its state.
	 */
	if (!i915_terminally_wedged(&dev_priv->gpu_error)) {
		ret = i915_gem_switch_to_kernel_context(dev_priv);
		if (ret)
			goto err_unlock;
@@ -4723,6 +4724,7 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
			goto err_unlock;

		assert_kernel_context_is_current(dev_priv);
	}
	i915_gem_contexts_lost(dev_priv);
	mutex_unlock(&dev->struct_mutex);

@@ -4946,8 +4948,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
{
	int ret;

	mutex_lock(&dev_priv->drm.struct_mutex);

	/*
	 * We need to fallback to 4K pages since gvt gtt handling doesn't
	 * support huge page entries - we will need to check either hypervisor
@@ -4967,18 +4967,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
		dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup;
	}

	ret = i915_gem_init_userptr(dev_priv);
	if (ret)
		return ret;

	/* This is just a security blanket to placate dragons.
	 * On some systems, we very sporadically observe that the first TLBs
	 * used by the CS may be stale, despite us poking the TLB reset. If
	 * we hold the forcewake during initialisation these problems
	 * just magically go away.
	 */
	mutex_lock(&dev_priv->drm.struct_mutex);
	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);

	ret = i915_gem_init_userptr(dev_priv);
	if (ret)
		goto out_unlock;

	ret = i915_gem_init_ggtt(dev_priv);
	if (ret)
		goto out_unlock;
Loading