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

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

Merge tag 'drm-intel-next-2012-02-16-merge-resolved' of...

Merge tag 'drm-intel-next-2012-02-16-merge-resolved' of git://people.freedesktop.org/~danvet/drm-intel into drm-core-next

* tag 'drm-intel-next-2012-02-16-merge-resolved' of git://people.freedesktop.org/~danvet/drm-intel: (45 commits)
  Revert "drivers/gpu/drm/i915/intel_overlay.c needs seq_file.h"
  drm/i915/lvds: Always use the presence pin for LVDS on PCH
  drm/i915: Record the position of the request upon error
  drm/i915: Record the in-flight requests at the time of a hang
  drm/i915: Record the tail at each request and use it to estimate the head
  drm/i915: add missing SDVO bits for interlaced modes on ILK
  drm/i915: Fix race condition in accessing GMBUS
  drm/i915: add a "force-dvi" HDMI audio mode
  drm/i915: Don't lock panel registers when downclocking
  drm/i915: fix up locking inconsistency around gem_do_init
  drm/i915: enable forcewake voodoo also for gen6
  drm/i915: fixup seqno allocation logic for lazy_request
  drm/i915: outstanding_lazy_request is a u32
  drm/i915: check gtfifodbg after possibly failed writes
  drm/i915: catch gtfifo errors on forcewake_put
  drm/i915: use gtfifodbg
  drm/i915: set interlaced bits for TRANSCONF
  drm/i915: fixup overlay checks for interlaced modes
  drm/i915: allow interlaced mode output on the HDMI connector
  drm/i915: allow interlaced mode output on the SDVO connector
  ...
parents 019d96cb ff5f4b05
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -76,7 +76,6 @@ static struct _intel_private {
	struct resource ifp_resource;
	int resource_valid;
	struct page *scratch_page;
	dma_addr_t scratch_page_dma;
} intel_private;

#define INTEL_GTT_GEN	intel_private.driver->gen
@@ -306,9 +305,9 @@ static int intel_gtt_setup_scratch_page(void)
		if (pci_dma_mapping_error(intel_private.pcidev, dma_addr))
			return -EINVAL;

		intel_private.scratch_page_dma = dma_addr;
		intel_private.base.scratch_page_dma = dma_addr;
	} else
		intel_private.scratch_page_dma = page_to_phys(page);
		intel_private.base.scratch_page_dma = page_to_phys(page);

	intel_private.scratch_page = page;

@@ -631,7 +630,7 @@ static unsigned int intel_gtt_mappable_entries(void)
static void intel_gtt_teardown_scratch_page(void)
{
	set_pages_wb(intel_private.scratch_page, 1);
	pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,
	pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma,
		       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
	put_page(intel_private.scratch_page);
	__free_page(intel_private.scratch_page);
@@ -681,6 +680,7 @@ static int intel_gtt_init(void)
		iounmap(intel_private.registers);
		return -ENOMEM;
	}
	intel_private.base.gtt = intel_private.gtt;

	global_cache_flush();   /* FIXME: ? */

@@ -975,7 +975,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
	unsigned int i;

	for (i = first_entry; i < (first_entry + num_entries); i++) {
		intel_private.driver->write_entry(intel_private.scratch_page_dma,
		intel_private.driver->write_entry(intel_private.base.scratch_page_dma,
						  i, 0);
	}
	readl(intel_private.gtt+i-1);
+2 −1
Original line number Diff line number Diff line
@@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
	if (err)
		return err;

	if (__get_user(c32.auth, &client->auth)
	if (__get_user(c32.idx, &client->idx)
	    || __get_user(c32.auth, &client->auth)
	    || __get_user(c32.pid, &client->pid)
	    || __get_user(c32.uid, &client->uid)
	    || __get_user(c32.magic, &client->magic)
+74 −8
Original line number Diff line number Diff line
@@ -721,8 +721,14 @@ static void i915_ring_error_state(struct seq_file *m,
	if (INTEL_INFO(dev)->gen >= 6) {
		seq_printf(m, "  FADDR: 0x%08x\n", error->faddr[ring]);
		seq_printf(m, "  FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
		seq_printf(m, "  SYNC_0: 0x%08x\n",
			   error->semaphore_mboxes[ring][0]);
		seq_printf(m, "  SYNC_1: 0x%08x\n",
			   error->semaphore_mboxes[ring][1]);
	}
	seq_printf(m, "  seqno: 0x%08x\n", error->seqno[ring]);
	seq_printf(m, "  ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
	seq_printf(m, "  ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
}

static int i915_error_state(struct seq_file *m, void *unused)
@@ -732,7 +738,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_i915_error_state *error;
	unsigned long flags;
	int i, page, offset, elt;
	int i, j, page, offset, elt;

	spin_lock_irqsave(&dev_priv->error_lock, flags);
	if (!dev_priv->first_error) {
@@ -772,10 +778,10 @@ static int i915_error_state(struct seq_file *m, void *unused)
				    error->pinned_bo,
				    error->pinned_bo_count);

	for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
		if (error->batchbuffer[i]) {
			struct drm_i915_error_object *obj = error->batchbuffer[i];
	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
		struct drm_i915_error_object *obj;

		if ((obj = error->ring[i].batchbuffer)) {
			seq_printf(m, "%s --- gtt_offset = 0x%08x\n",
				   dev_priv->ring[i].name,
				   obj->gtt_offset);
@@ -787,11 +793,20 @@ static int i915_error_state(struct seq_file *m, void *unused)
				}
			}
		}

		if (error->ring[i].num_requests) {
			seq_printf(m, "%s --- %d requests\n",
				   dev_priv->ring[i].name,
				   error->ring[i].num_requests);
			for (j = 0; j < error->ring[i].num_requests; j++) {
				seq_printf(m, "  seqno 0x%08x, emitted %ld, tail 0x%08x\n",
					   error->ring[i].requests[j].seqno,
					   error->ring[i].requests[j].jiffies,
					   error->ring[i].requests[j].tail);
			}
		}

	for (i = 0; i < ARRAY_SIZE(error->ringbuffer); i++) {
		if (error->ringbuffer[i]) {
			struct drm_i915_error_object *obj = error->ringbuffer[i];
		if ((obj = error->ring[i].ringbuffer)) {
			seq_printf(m, "%s --- ringbuffer = 0x%08x\n",
				   dev_priv->ring[i].name,
				   obj->gtt_offset);
@@ -1431,7 +1446,57 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
			   I915_READ16(C0DRB3));
		seq_printf(m, "C1DRB3 = 0x%04x\n",
			   I915_READ16(C1DRB3));
	} else if (IS_GEN6(dev) || IS_GEN7(dev)) {
		seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
			   I915_READ(MAD_DIMM_C0));
		seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
			   I915_READ(MAD_DIMM_C1));
		seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
			   I915_READ(MAD_DIMM_C2));
		seq_printf(m, "TILECTL = 0x%08x\n",
			   I915_READ(TILECTL));
		seq_printf(m, "ARB_MODE = 0x%08x\n",
			   I915_READ(ARB_MODE));
		seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
			   I915_READ(DISP_ARB_CTL));
	}
	mutex_unlock(&dev->struct_mutex);

	return 0;
}

static int i915_ppgtt_info(struct seq_file *m, void *data)
{
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_ring_buffer *ring;
	int i, ret;


	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
		return ret;
	if (INTEL_INFO(dev)->gen == 6)
		seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));

	for (i = 0; i < I915_NUM_RINGS; i++) {
		ring = &dev_priv->ring[i];

		seq_printf(m, "%s\n", ring->name);
		if (INTEL_INFO(dev)->gen == 7)
			seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
		seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring)));
		seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring)));
		seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring)));
	}
	if (dev_priv->mm.aliasing_ppgtt) {
		struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;

		seq_printf(m, "aliasing PPGTT:\n");
		seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
	}
	seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
	mutex_unlock(&dev->struct_mutex);

	return 0;
@@ -1778,6 +1843,7 @@ static struct drm_info_list i915_debugfs_list[] = {
	{"i915_context_status", i915_context_status, 0},
	{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
	{"i915_swizzle_info", i915_swizzle_info, 0},
	{"i915_ppgtt_info", i915_ppgtt_info, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)

+32 −13
Original line number Diff line number Diff line
@@ -1196,22 +1196,39 @@ static int i915_load_gem_init(struct drm_device *dev)
	/* Basic memrange allocator for stolen space */
	drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size);

	mutex_lock(&dev->struct_mutex);
	if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) {
		/* PPGTT pdes are stolen from global gtt ptes, so shrink the
		 * aperture accordingly when using aliasing ppgtt. */
		gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
		/* For paranoia keep the guard page in between. */
		gtt_size -= PAGE_SIZE;

		i915_gem_do_init(dev, 0, mappable_size, gtt_size);

		ret = i915_gem_init_aliasing_ppgtt(dev);
		if (ret)
			return ret;
	} else {
		/* Let GEM Manage all of the aperture.
		 *
	 * However, leave one page at the end still bound to the scratch page.
	 * There are a number of places where the hardware apparently
	 * prefetches past the end of the object, and we've seen multiple
	 * hangs with the GPU head pointer stuck in a batchbuffer bound
	 * at the last page of the aperture.  One page should be enough to
	 * keep any prefetching inside of the aperture.
		 * However, leave one page at the end still bound to the scratch
		 * page.  There are a number of places where the hardware
		 * apparently prefetches past the end of the object, and we've
		 * seen multiple hangs with the GPU head pointer stuck in a
		 * batchbuffer bound at the last page of the aperture.  One page
		 * should be enough to keep any prefetching inside of the
		 * aperture.
		 */
		i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE);
	}

	mutex_lock(&dev->struct_mutex);
	ret = i915_gem_init_ringbuffer(dev);
	ret = i915_gem_init_hw(dev);
	mutex_unlock(&dev->struct_mutex);
	if (ret)
	if (ret) {
		i915_gem_cleanup_aliasing_ppgtt(dev);
		return ret;
	}

	/* Try to set up FBC with a reasonable compressed buffer size */
	if (I915_HAS_FBC(dev) && i915_powersave) {
@@ -1298,6 +1315,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
	mutex_lock(&dev->struct_mutex);
	i915_gem_cleanup_ringbuffer(dev);
	mutex_unlock(&dev->struct_mutex);
	i915_gem_cleanup_aliasing_ppgtt(dev);
cleanup_vga_switcheroo:
	vga_switcheroo_unregister_client(dev->pdev);
cleanup_vga_client:
@@ -2187,6 +2205,7 @@ int i915_driver_unload(struct drm_device *dev)
		i915_gem_free_all_phys_object(dev);
		i915_gem_cleanup_ringbuffer(dev);
		mutex_unlock(&dev->struct_mutex);
		i915_gem_cleanup_aliasing_ppgtt(dev);
		if (I915_HAS_FBC(dev) && i915_powersave)
			i915_cleanup_compression(dev);
		drm_mm_takedown(&dev_priv->mm.stolen);
+35 −6
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@ MODULE_PARM_DESC(enable_hangcheck,
		"WARNING: Disabling this can cause system wide hangs. "
		"(default: true)");

bool i915_enable_ppgtt __read_mostly = 1;
module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600);
MODULE_PARM_DESC(i915_enable_ppgtt,
		"Enable PPGTT (default: true)");

static struct drm_driver driver;
extern int intel_agp_enabled;

@@ -380,16 +385,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
{
	u32 gtfifodbg;
	gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
	if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK,
	     "MMIO read or write has been dropped %x\n", gtfifodbg))
		I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
}

void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
	I915_WRITE_NOTRACE(FORCEWAKE, 0);
	POSTING_READ(FORCEWAKE);
	/* The below doubles as a POSTING_READ */
	gen6_gt_check_fifodbg(dev_priv);
}

void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
{
	I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
	POSTING_READ(FORCEWAKE_MT);
	/* The below doubles as a POSTING_READ */
	gen6_gt_check_fifodbg(dev_priv);
}

/*
@@ -405,8 +421,10 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
{
	int ret = 0;

	if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
		int loop = 500;
		u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
@@ -414,10 +432,13 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
			udelay(10);
			fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
		}
		WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES);
		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
			++ret;
		dev_priv->gt_fifo_count = fifo;
	}
	dev_priv->gt_fifo_count--;

	return ret;
}

static int i915_drm_freeze(struct drm_device *dev)
@@ -498,7 +519,7 @@ static int i915_drm_thaw(struct drm_device *dev)
		mutex_lock(&dev->struct_mutex);
		dev_priv->mm.suspended = 0;

		error = i915_gem_init_ringbuffer(dev);
		error = i915_gem_init_hw(dev);
		mutex_unlock(&dev->struct_mutex);

		if (HAS_PCH_SPLIT(dev))
@@ -713,12 +734,16 @@ int i915_reset(struct drm_device *dev, u8 flags)
			!dev_priv->mm.suspended) {
		dev_priv->mm.suspended = 0;

		i915_gem_init_swizzling(dev);

		dev_priv->ring[RCS].init(&dev_priv->ring[RCS]);
		if (HAS_BSD(dev))
		    dev_priv->ring[VCS].init(&dev_priv->ring[VCS]);
		if (HAS_BLT(dev))
		    dev_priv->ring[BCS].init(&dev_priv->ring[BCS]);

		i915_gem_init_ppgtt(dev);

		mutex_unlock(&dev->struct_mutex);
		drm_irq_uninstall(dev);
		drm_mode_config_reset(dev);
@@ -981,11 +1006,15 @@ __i915_read(64, q)

#define __i915_write(x, y) \
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
	u32 __fifo_ret = 0; \
	trace_i915_reg_rw(true, reg, val, sizeof(val)); \
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
		__gen6_gt_wait_for_fifo(dev_priv); \
		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
	} \
	write##y(val, dev_priv->regs + reg); \
	if (unlikely(__fifo_ret)) { \
		gen6_gt_check_fifodbg(dev_priv); \
	} \
}
__i915_write(8, b)
__i915_write(16, w)
Loading