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

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

Merge tag 'drm-intel-fixes-2013-07-03' of...

Merge tag 'drm-intel-fixes-2013-07-03' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Pile of fixes for 3.11. A bit large in patch count, but that's simply due
to two fixes being split up into really small parts. Also I've included a
few more vlv patches than I'd have included for other platforms. But since
vlv is officially supported for the first time only in 3.11 that shouldn't
result in unbearable risks.

Highlights:
- ghost eDP fixes for hsw from Paulo
- fix PCH detection in virtualized enviroments (Rui Guo)
- duct-tape dma sg construction when swiotlb is in use (Konrad), dupe with
  a patch in your drm-fixes branch
- fix sdvo hotplug on i965g
- tune down a bunch of dmesg ERRORs which can be hit under normal
  conditions
- detect invalid pitches for tiled scanout buffers (Chris)
- a pile of vlv fixes from Ville: rps improvements, fixes for the dpll
  LPF, fixup the sprite mmio offsets
- fix context size on hsw (Ben)
- locking fixes for the hotplug code, specifically the storm handling
- fix get_config on CPT (Xiong Zhang)
- Fix the domain tracking when an unlocked seqno wait was interrupt
  (Chris), this seems to explain tons of little corruption bugs in the
  ddx. Chris also added a nice igt to exercise this.
- work around stack-corrupting vnsprintf in our error state dumper

* tag 'drm-intel-fixes-2013-07-03' of git://people.freedesktop.org/~danvet/drm-intel: (39 commits)
  drm/i915: Don't try to tear down the stolen drm_mm if it's not there
  drm/i915: Break up the large vsnprintf() in print_error_buffers()
  drm/i915: Refactor the wait_rendering completion into a common routine
  drm/i915: Only clear write-domains after a successful wait-seqno
  drm/i915: correct intel_dp_get_config() function for DevCPT
  drm/i915: fix hpd interrupt register locking
  drm/i915: fold the no-irq check into intel_hpd_irq_handler
  drm/i915: fold the queue_work into intel_hpd_irq_handler
  drm/i915: fold the hpd_irq_setup call into intel_hpd_irq_handler
  drm/i915: s/hotplug_irq_storm_detect/intel_hpd_irq_handler/
  drm/i915: close tiny race in the ilk pcu even interrupt setup
  drm/i915: fix locking around ironlake_enable|disable_display_irq
  drm/i915: Fix context sizes on HSW
  drm/i915: Fix VLV sprite register offsets
  Revert "drm/i915: Don't use the HDMI port color range bit on Valleyview"
  drm/i915: s/LFP/LPF in DPIO PLL register names
  drm/i915: Fix VLV PLL LPF coefficients for DAC
  drm/i915: Jump to at least RPe on VLV when increasing the GPU frequency
  drm/i915: Don't increase the GPU frequency from the delayed VLV rps timer
  drm/i915: GEN6_RP_INTERRUPT_LIMITS doesn't seem to exist on VLV
  ...
parents 1586ba72 446f8d81
Loading
Loading
Loading
Loading
+84 −35
Original line number Diff line number Diff line
@@ -647,41 +647,44 @@ static const char *purgeable_flag(int purgeable)
	return purgeable ? " purgeable" : "";
}

static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
			       const char *f, va_list args)
static bool __i915_error_ok(struct drm_i915_error_state_buf *e)
{
	unsigned len;

	if (!e->err && WARN(e->bytes > (e->size - 1), "overflow")) {
		e->err = -ENOSPC;
		return;
		return false;
	}

	if (e->bytes == e->size - 1 || e->err)
		return;
		return false;

	/* Seek the first printf which is hits start position */
	if (e->pos < e->start) {
		len = vsnprintf(NULL, 0, f, args);
	return true;
}

static bool __i915_error_seek(struct drm_i915_error_state_buf *e,
			      unsigned len)
{
	if (e->pos + len <= e->start) {
		e->pos += len;
			return;
		return false;
	}

		/* First vsnprintf needs to fit in full for memmove*/
	/* First vsnprintf needs to fit in its entirety for memmove */
	if (len >= e->size) {
		e->err = -EIO;
			return;
		}
		return false;
	}

	len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args);
	if (len >= e->size - e->bytes)
		len = e->size - e->bytes - 1;
	return true;
}

static void __i915_error_advance(struct drm_i915_error_state_buf *e,
				 unsigned len)
{
	/* If this is first printf in this window, adjust it so that
	 * start position matches start of the buffer
	 */

	if (e->pos < e->start) {
		const size_t off = e->start - e->pos;

@@ -701,6 +704,51 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
	e->pos += len;
}

static void i915_error_vprintf(struct drm_i915_error_state_buf *e,
			       const char *f, va_list args)
{
	unsigned len;

	if (!__i915_error_ok(e))
		return;

	/* Seek the first printf which is hits start position */
	if (e->pos < e->start) {
		len = vsnprintf(NULL, 0, f, args);
		if (!__i915_error_seek(e, len))
			return;
	}

	len = vsnprintf(e->buf + e->bytes, e->size - e->bytes, f, args);
	if (len >= e->size - e->bytes)
		len = e->size - e->bytes - 1;

	__i915_error_advance(e, len);
}

static void i915_error_puts(struct drm_i915_error_state_buf *e,
			    const char *str)
{
	unsigned len;

	if (!__i915_error_ok(e))
		return;

	len = strlen(str);

	/* Seek the first printf which is hits start position */
	if (e->pos < e->start) {
		if (!__i915_error_seek(e, len))
			return;
	}

	if (len >= e->size - e->bytes)
		len = e->size - e->bytes - 1;
	memcpy(e->buf + e->bytes, str, len);

	__i915_error_advance(e, len);
}

void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
{
	va_list args;
@@ -711,6 +759,7 @@ void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...)
}

#define err_printf(e, ...) i915_error_printf(e, __VA_ARGS__)
#define err_puts(e, s) i915_error_puts(e, s)

static void print_error_buffers(struct drm_i915_error_state_buf *m,
				const char *name,
@@ -720,26 +769,26 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m,
	err_printf(m, "%s [%d]:\n", name, count);

	while (count--) {
		err_printf(m, "  %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s",
		err_printf(m, "  %08x %8u %02x %02x %x %x",
			   err->gtt_offset,
			   err->size,
			   err->read_domains,
			   err->write_domain,
			   err->rseqno, err->wseqno,
			   pin_flag(err->pinned),
			   tiling_flag(err->tiling),
			   dirty_flag(err->dirty),
			   purgeable_flag(err->purgeable),
			   err->ring != -1 ? " " : "",
			   ring_str(err->ring),
			   cache_level_str(err->cache_level));
			   err->rseqno, err->wseqno);
		err_puts(m, pin_flag(err->pinned));
		err_puts(m, tiling_flag(err->tiling));
		err_puts(m, dirty_flag(err->dirty));
		err_puts(m, purgeable_flag(err->purgeable));
		err_puts(m, err->ring != -1 ? " " : "");
		err_puts(m, ring_str(err->ring));
		err_puts(m, cache_level_str(err->cache_level));

		if (err->name)
			err_printf(m, " (name: %d)", err->name);
		if (err->fence_reg != I915_FENCE_REG_NONE)
			err_printf(m, " (fence: %d)", err->fence_reg);

		err_printf(m, "\n");
		err_puts(m, "\n");
		err++;
	}
}
@@ -1483,7 +1532,7 @@ static int i915_ips_status(struct seq_file *m, void *unused)
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (!IS_ULT(dev)) {
	if (!HAS_IPS(dev)) {
		seq_puts(m, "not supported\n");
		return 0;
	}
@@ -1862,10 +1911,10 @@ static int i915_dpio_info(struct seq_file *m, void *data)
	seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n",
		   vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B));

	seq_printf(m, "DPIO_LFP_COEFF_A: 0x%08x\n",
		   vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_A));
	seq_printf(m, "DPIO_LFP_COEFF_B: 0x%08x\n",
		   vlv_dpio_read(dev_priv, _DPIO_LFP_COEFF_B));
	seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n",
		   vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_A));
	seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n",
		   vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_B));

	seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
		   vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));
+16 −2
Original line number Diff line number Diff line
@@ -465,9 +465,15 @@ void intel_detect_pch(struct drm_device *dev)
	 * make graphics device passthrough work easy for VMM, that only
	 * need to expose ISA bridge to let driver know the real hardware
	 * underneath. This is a requirement from virtualization team.
	 *
	 * In some virtualized environments (e.g. XEN), there is irrelevant
	 * ISA bridge in the system. To work reliably, we should scan trhough
	 * all the ISA bridge devices and check for the first match, instead
	 * of only checking the first one.
	 */
	pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
	if (pch) {
	while (pch) {
		struct pci_dev *curr = pch;
		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
			unsigned short id;
			id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
@@ -496,10 +502,18 @@ void intel_detect_pch(struct drm_device *dev)
				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
				WARN_ON(!IS_HASWELL(dev));
				WARN_ON(!IS_ULT(dev));
			}
			} else {
				goto check_next;
			}
			pci_dev_put(pch);
			break;
		}
check_next:
		pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, curr);
		pci_dev_put(curr);
	}
	if (!pch)
		DRM_DEBUG_KMS("No PCH found?\n");
}

bool i915_semaphore_is_enabled(struct drm_device *dev)
+2 −0
Original line number Diff line number Diff line
@@ -1474,6 +1474,8 @@ struct drm_i915_file_private {
#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)

#define HAS_IPS(dev)		(IS_ULT(dev))

#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)

#define HAS_DDI(dev)		(INTEL_INFO(dev)->has_ddi)
+36 −28
Original line number Diff line number Diff line
@@ -1087,6 +1087,25 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
			    interruptible, NULL);
}

static int
i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj,
				     struct intel_ring_buffer *ring)
{
	i915_gem_retire_requests_ring(ring);

	/* Manually manage the write flush as we may have not yet
	 * retired the buffer.
	 *
	 * Note that the last_write_seqno is always the earlier of
	 * the two (read/write) seqno, so if we haved successfully waited,
	 * we know we have passed the last write.
	 */
	obj->last_write_seqno = 0;
	obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;

	return 0;
}

/**
 * Ensures that all rendering to the object has completed and the object is
 * safe to unbind from the GTT or access from the CPU.
@@ -1107,18 +1126,7 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
	if (ret)
		return ret;

	i915_gem_retire_requests_ring(ring);

	/* Manually manage the write flush as we may have not yet
	 * retired the buffer.
	 */
	if (obj->last_write_seqno &&
	    i915_seqno_passed(seqno, obj->last_write_seqno)) {
		obj->last_write_seqno = 0;
		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
	}

	return 0;
	return i915_gem_object_wait_rendering__tail(obj, ring);
}

/* A nonblocking variant of the above wait. This is a highly dangerous routine
@@ -1154,19 +1162,10 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
	mutex_unlock(&dev->struct_mutex);
	ret = __wait_seqno(ring, seqno, reset_counter, true, NULL);
	mutex_lock(&dev->struct_mutex);

	i915_gem_retire_requests_ring(ring);

	/* Manually manage the write flush as we may have not yet
	 * retired the buffer.
	 */
	if (obj->last_write_seqno &&
	    i915_seqno_passed(seqno, obj->last_write_seqno)) {
		obj->last_write_seqno = 0;
		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
	}

	if (ret)
		return ret;

	return i915_gem_object_wait_rendering__tail(obj, ring);
}

/**
@@ -1802,7 +1801,14 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
			gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
			gfp &= ~(__GFP_IO | __GFP_WAIT);
		}

#ifdef CONFIG_SWIOTLB
		if (swiotlb_nr_tbl()) {
			st->nents++;
			sg_set_page(sg, page, PAGE_SIZE, 0);
			sg = sg_next(sg);
			continue;
		}
#endif
		if (!i || page_to_pfn(page) != last_pfn + 1) {
			if (i)
				sg = sg_next(sg);
@@ -1813,7 +1819,9 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
		}
		last_pfn = page_to_pfn(page);
	}

#ifdef CONFIG_SWIOTLB
	if (!swiotlb_nr_tbl())
#endif
		sg_mark_end(sg);
	obj->pages = st;

@@ -3103,7 +3111,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
	 * before evicting everything in a vain attempt to find space.
	 */
	if (obj->base.size > gtt_max) {
		DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%ld\n",
		DRM_ERROR("Attempting to bind an object larger than the aperture: object=%zd > %s aperture=%zu\n",
			  obj->base.size,
			  map_and_fenceable ? "mappable" : "total",
			  gtt_max);
+1 −1
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ static int get_context_size(struct drm_device *dev)
	case 7:
		reg = I915_READ(GEN7_CXT_SIZE);
		if (IS_HASWELL(dev))
			ret = HSW_CXT_TOTAL_SIZE(reg) * 64;
			ret = HSW_CXT_TOTAL_SIZE;
		else
			ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
		break;
Loading