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

Commit 64aa7e34 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2015-02-11' of...

Merge tag 'drm-intel-next-fixes-2015-02-11' of git://anongit.freedesktop.org/drm-intel into drm-next

Here's a batch of i915 fixes for drm-next, with more cc: stable material
than fixes specific to drm-next.

* tag 'drm-intel-next-fixes-2015-02-11' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: Clamp efficient frequency to valid range
  drm/i915: Really ignore long HPD pulses on eDP
  drm/i915: Correct the base value while updating LP_OUTPUT_HOLD in MIPI_PORT_CTRL
  drm/i915: Insert a command barrier on BLT/BSD cache flushes
  drm/i915: Drop vblank wait from intel_dp_link_down
  drm/i915: Squelch overzealous uncore reset WARN_ON
  drm/i915: Take runtime pm reference on hangcheck_info
  drm/i915: Correct the IOSF Dev_FN field for IOSF transfers
  drm/i915: Prevent use-after-free in invalidate_range_start callback
parents 85840c76 46efa4ab
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -1223,8 +1223,11 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
static int i915_hangcheck_info(struct seq_file *m, void *unused)
{
	struct drm_info_node *node = m->private;
	struct drm_i915_private *dev_priv = to_i915(node->minor->dev);
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_engine_cs *ring;
	u64 acthd[I915_NUM_RINGS];
	u32 seqno[I915_NUM_RINGS];
	int i;

	if (!i915.enable_hangcheck) {
@@ -1232,6 +1235,15 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
		return 0;
	}

	intel_runtime_pm_get(dev_priv);

	for_each_ring(ring, dev_priv, i) {
		seqno[i] = ring->get_seqno(ring, false);
		acthd[i] = intel_ring_get_active_head(ring);
	}

	intel_runtime_pm_put(dev_priv);

	if (delayed_work_pending(&dev_priv->gpu_error.hangcheck_work)) {
		seq_printf(m, "Hangcheck active, fires in %dms\n",
			   jiffies_to_msecs(dev_priv->gpu_error.hangcheck_work.timer.expires -
@@ -1242,14 +1254,14 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
	for_each_ring(ring, dev_priv, i) {
		seq_printf(m, "%s:\n", ring->name);
		seq_printf(m, "\tseqno = %x [current %x]\n",
			   ring->hangcheck.seqno, ring->get_seqno(ring, false));
		seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
		seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
			   ring->hangcheck.seqno, seqno[i]);
		seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n",
			   (long long)ring->hangcheck.acthd,
			   (long long)intel_ring_get_active_head(ring));
			   (long long)acthd[i]);
		seq_printf(m, "\tmax ACTHD = 0x%08llx\n",
			   (long long)ring->hangcheck.max_acthd);
		seq_printf(m, "\tscore = %d\n", ring->hangcheck.score);
		seq_printf(m, "\taction = %d\n", ring->hangcheck.action);
	}

	return 0;
+18 −2
Original line number Diff line number Diff line
@@ -113,7 +113,10 @@ static void *invalidate_range__linear(struct i915_mmu_notifier *mn,
			continue;

		obj = mo->obj;
		drm_gem_object_reference(&obj->base);

		if (!kref_get_unless_zero(&obj->base.refcount))
			continue;

		spin_unlock(&mn->lock);

		cancel_userptr(obj);
@@ -149,7 +152,20 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
			it = interval_tree_iter_first(&mn->objects, start, end);
		if (it != NULL) {
			obj = container_of(it, struct i915_mmu_object, it)->obj;
			drm_gem_object_reference(&obj->base);

			/* The mmu_object is released late when destroying the
			 * GEM object so it is entirely possible to gain a
			 * reference on an object in the process of being freed
			 * since our serialisation is via the spinlock and not
			 * the struct_mutex - and consequently use it after it
			 * is freed and then double free it.
			 */
			if (!kref_get_unless_zero(&obj->base.refcount)) {
				spin_unlock(&mn->lock);
				serial = 0;
				continue;
			}

			serial = mn->serial;
		}
		spin_unlock(&mn->lock);
+2 −17
Original line number Diff line number Diff line
@@ -3521,8 +3521,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
	enum port port = intel_dig_port->port;
	struct drm_device *dev = intel_dig_port->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc =
		to_intel_crtc(intel_dig_port->base.base.crtc);
	uint32_t DP = intel_dp->DP;

	if (WARN_ON(HAS_DDI(dev)))
@@ -3547,8 +3545,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)

	if (HAS_PCH_IBX(dev) &&
	    I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
		struct drm_crtc *crtc = intel_dig_port->base.base.crtc;

		/* Hardware workaround: leaving our transcoder select
		 * set to transcoder B while it's off will prevent the
		 * corresponding HDMI output on transcoder A.
@@ -3559,18 +3555,7 @@ intel_dp_link_down(struct intel_dp *intel_dp)
		 */
		DP &= ~DP_PIPEB_SELECT;
		I915_WRITE(intel_dp->output_reg, DP);

		/* Changes to enable or select take place the vblank
		 * after being written.
		 */
		if (WARN_ON(crtc == NULL)) {
			/* We should never try to disable a port without a crtc
			 * attached. For paranoia keep the code around for a
			 * bit. */
		POSTING_READ(intel_dp->output_reg);
			msleep(50);
		} else
			intel_wait_for_vblank(dev, intel_crtc->pipe);
	}

	DP &= ~DP_AUDIO_OUTPUT_ENABLE;
@@ -4446,7 +4431,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
		 */
		DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n",
			      port_name(intel_dig_port->port));
		return false;
		return IRQ_HANDLED;
	}

	DRM_DEBUG_KMS("got hpd irq on port %c - %s\n",
+2 −3
Original line number Diff line number Diff line
@@ -360,12 +360,11 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
		I915_WRITE(MIPI_DEVICE_READY(port), ULPS_STATE_ENTER);
		usleep_range(2500, 3000);

		val = I915_READ(MIPI_PORT_CTRL(port));

		/* Enable MIPI PHY transparent latch
		 * Common bit for both MIPI Port A & MIPI Port C
		 * No similar bit in MIPI Port C reg
		 */
		val = I915_READ(MIPI_PORT_CTRL(PORT_A));
		I915_WRITE(MIPI_PORT_CTRL(PORT_A), val | LP_OUTPUT_HOLD);
		usleep_range(1000, 1500);

@@ -543,10 +542,10 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
							== 0x00000), 30))
			DRM_ERROR("DSI LP not going Low\n");

		val = I915_READ(MIPI_PORT_CTRL(port));
		/* Disable MIPI PHY transparent latch
		 * Common bit for both MIPI Port A & MIPI Port C
		 */
		val = I915_READ(MIPI_PORT_CTRL(PORT_A));
		I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD);
		usleep_range(1000, 1500);

+11 −9
Original line number Diff line number Diff line
@@ -1211,15 +1211,17 @@ static int gen8_emit_flush(struct intel_ringbuffer *ringbuf,

	cmd = MI_FLUSH_DW + 1;

	if (ring == &dev_priv->ring[VCS]) {
		if (invalidate_domains & I915_GEM_GPU_DOMAINS)
			cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD |
				MI_FLUSH_DW_STORE_INDEX |
				MI_FLUSH_DW_OP_STOREDW;
	} else {
		if (invalidate_domains & I915_GEM_DOMAIN_RENDER)
			cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX |
				MI_FLUSH_DW_OP_STOREDW;
	/* We always require a command barrier so that subsequent
	 * commands, such as breadcrumb interrupts, are strictly ordered
	 * wrt the contents of the write cache being flushed to memory
	 * (and thus being coherent from the CPU).
	 */
	cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;

	if (invalidate_domains & I915_GEM_GPU_DOMAINS) {
		cmd |= MI_INVALIDATE_TLB;
		if (ring == &dev_priv->ring[VCS])
			cmd |= MI_INVALIDATE_BSD;
	}

	intel_logical_ring_emit(ringbuf, cmd);
Loading