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

Commit 399403c7 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-2013-03-23' of...

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

Daniel writes:
Highlights:
- Imre's for_each_sg_pages rework (now also with the stolen mem backed
  case fixed with a hack) plus the drm prime sg list coalescing patch from
  Rahul Sharma. I have some follow-up cleanups pending, already acked by
  Andrew Morton.
- Some prep-work for the crazy no-pch/display-less platform by Ben.
- Some vlv patches, by far not all (Jesse et al).
- Clean up the HDMI/SDVO #define confusion (Paulo)
- gen2-4 vblank fixes from Ville.
- Unclaimed register warning fixes for hsw (Paulo). More still to come ...
- Complete pageflips which have been stuck in a gpu hang, should prevent
  stuck gl compositors (Ville).
- pm patches for vt-switchless resume (Jesse). Note that the i915 enabling
  is not (yet) included, that took a bit longer to settle. PM patches are
  acked by Rafael Wysocki.
- Minor fixlets all over from various people.

* tag 'drm-intel-next-2013-03-23' of git://people.freedesktop.org/~danvet/drm-intel: (79 commits)
  drm/i915: Implement WaSwitchSolVfFArbitrationPriority
  drm/i915: Set the VIC in AVI infoframe for SDVO
  drm/i915: Kill a strange comment about DPMS functions
  drm/i915: Correct sandybrige overclocking
  drm/i915: Introduce GEN7_FEATURES for device info
  drm/i915: Move num_pipes to intel info
  drm/i915: fixup pd vs pt confusion in gen6 ppgtt code
  style nit: Align function parameter continuation properly.
  drm/i915: VLV doesn't have HDMI on port C
  drm/i915: DSPFW and BLC regs are in the display offset range
  drm/i915: set conservative clock gating values on VLV v2
  drm/i915: fix WaDisablePSDDualDispatchEnable on VLV v2
  drm/i915: add more VLV IDs
  drm/i915: use VLV DIP routines on VLV v2
  drm/i915: add media well to VLV force wake routines v2
  drm/i915: don't use plane pipe select on VLV
  drm: modify pages_to_sg prime helper to create optimized SG table
  drm/i915: use for_each_sg_page for setting up the gtt ptes
  drm/i915: create compact dma scatter lists for gem objects
  drm/i915: handle walking compact dma scatter lists
  ...
parents b6a9b7f6 e3dff585
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -105,12 +105,11 @@ drm_clflush_sg(struct sg_table *st)
{
#if defined(CONFIG_X86)
	if (cpu_has_clflush) {
		struct scatterlist *sg;
		int i;
		struct sg_page_iter sg_iter;

		mb();
		for_each_sg(st->sgl, sg, st->nents, i)
			drm_clflush_page(sg_page(sg));
		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
			drm_clflush_page(sg_iter.page);
		mb();

		return;
+2 −6
Original line number Diff line number Diff line
@@ -401,21 +401,17 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
{
	struct sg_table *sg = NULL;
	struct scatterlist *iter;
	int i;
	int ret;

	sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
	if (!sg)
		goto out;

	ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL);
	ret = sg_alloc_table_from_pages(sg, pages, nr_pages, 0,
				nr_pages << PAGE_SHIFT, GFP_KERNEL);
	if (ret)
		goto out;

	for_each_sg(sg->sgl, iter, nr_pages, i)
		sg_set_page(iter, pages[i], PAGE_SIZE, 0);

	return sg;
out:
	kfree(sg);
+121 −302
Original line number Diff line number Diff line
@@ -772,6 +772,23 @@ static int i915_error_state(struct seq_file *m, void *unused)
				}
			}
		}

		obj = error->ring[i].ctx;
		if (obj) {
			seq_printf(m, "%s --- HW Context = 0x%08x\n",
				   dev_priv->ring[i].name,
				   obj->gtt_offset);
			offset = 0;
			for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
				seq_printf(m, "[%04x] %08x %08x %08x %08x\n",
					   offset,
					   obj->pages[0][elt],
					   obj->pages[0][elt+1],
					   obj->pages[0][elt+2],
					   obj->pages[0][elt+3]);
					offset += 16;
			}
		}
	}

	if (error->overlay)
@@ -849,76 +866,42 @@ static const struct file_operations i915_error_state_fops = {
	.release = i915_error_state_release,
};

static ssize_t
i915_next_seqno_read(struct file *filp,
		 char __user *ubuf,
		 size_t max,
		 loff_t *ppos)
static int
i915_next_seqno_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len;
	int ret;

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
		return ret;

	len = snprintf(buf, sizeof(buf),
		       "next_seqno :  0x%x\n",
		       dev_priv->next_seqno);

	*val = dev_priv->next_seqno;
	mutex_unlock(&dev->struct_mutex);

	if (len > sizeof(buf))
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_next_seqno_write(struct file *filp,
		      const char __user *ubuf,
		      size_t cnt,
		      loff_t *ppos)
static int
i915_next_seqno_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	char buf[20];
	u32 val = 1;
	struct drm_device *dev = data;
	int ret;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		ret = kstrtouint(buf, 0, &val);
		if (ret < 0)
			return ret;
	}

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
		return ret;

	ret = i915_gem_set_seqno(dev, val);

	mutex_unlock(&dev->struct_mutex);

	return ret ?: cnt;
	return ret;
}

static const struct file_operations i915_next_seqno_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_next_seqno_read,
	.write = i915_next_seqno_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
			i915_next_seqno_get, i915_next_seqno_set,
			"next_seqno :  0x%llx\n");

static int i915_rstdby_delays(struct seq_file *m, void *unused)
{
@@ -1680,105 +1663,51 @@ static int i915_dpio_info(struct seq_file *m, void *data)
	return 0;
}

static ssize_t
i915_wedged_read(struct file *filp,
		 char __user *ubuf,
		 size_t max,
		 loff_t *ppos)
static int
i915_wedged_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len;

	len = snprintf(buf, sizeof(buf),
		       "wedged :  %d\n",
		       atomic_read(&dev_priv->gpu_error.reset_counter));

	if (len > sizeof(buf))
		len = sizeof(buf);
	*val = atomic_read(&dev_priv->gpu_error.reset_counter);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_wedged_write(struct file *filp,
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
static int
i915_wedged_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	char buf[20];
	int val = 1;
	struct drm_device *dev = data;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	DRM_INFO("Manually setting wedged to %d\n", val);
	DRM_INFO("Manually setting wedged to %llu\n", val);
	i915_handle_error(dev, val);

	return cnt;
	return 0;
}

static const struct file_operations i915_wedged_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_wedged_read,
	.write = i915_wedged_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops,
			i915_wedged_get, i915_wedged_set,
			"wedged :  %llu\n");

static ssize_t
i915_ring_stop_read(struct file *filp,
		    char __user *ubuf,
		    size_t max,
		    loff_t *ppos)
static int
i915_ring_stop_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[20];
	int len;

	len = snprintf(buf, sizeof(buf),
		       "0x%08x\n", dev_priv->gpu_error.stop_rings);
	*val = dev_priv->gpu_error.stop_rings;

	if (len > sizeof(buf))
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_ring_stop_write(struct file *filp,
		     const char __user *ubuf,
		     size_t cnt,
		     loff_t *ppos)
static int
i915_ring_stop_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int val = 0, ret;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}
	int ret;

	DRM_DEBUG_DRIVER("Stopping rings 0x%08x\n", val);
	DRM_DEBUG_DRIVER("Stopping rings 0x%08llx\n", val);

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
@@ -1787,16 +1716,12 @@ i915_ring_stop_write(struct file *filp,
	dev_priv->gpu_error.stop_rings = val;
	mutex_unlock(&dev->struct_mutex);

	return cnt;
	return 0;
}

static const struct file_operations i915_ring_stop_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_ring_stop_read,
	.write = i915_ring_stop_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops,
			i915_ring_stop_get, i915_ring_stop_set,
			"0x%08llx\n");

#define DROP_UNBOUND 0x1
#define DROP_BOUND 0x2
@@ -1806,46 +1731,23 @@ static const struct file_operations i915_ring_stop_fops = {
		  DROP_BOUND | \
		  DROP_RETIRE | \
		  DROP_ACTIVE)
static ssize_t
i915_drop_caches_read(struct file *filp,
		      char __user *ubuf,
		      size_t max,
		      loff_t *ppos)
static int
i915_drop_caches_get(void *data, u64 *val)
{
	char buf[20];
	int len;

	len = snprintf(buf, sizeof(buf), "0x%08x\n", DROP_ALL);
	if (len > sizeof(buf))
		len = sizeof(buf);
	*val = DROP_ALL;

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_drop_caches_write(struct file *filp,
		       const char __user *ubuf,
		       size_t cnt,
		       loff_t *ppos)
static int
i915_drop_caches_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj, *next;
	char buf[20];
	int val = 0, ret;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}
	int ret;

	DRM_DEBUG_DRIVER("Dropping caches: 0x%08x\n", val);
	DRM_DEBUG_DRIVER("Dropping caches: 0x%08llx\n", val);

	/* No need to check and wait for gpu resets, only libdrm auto-restarts
	 * on ioctls on -EAGAIN. */
@@ -1883,27 +1785,19 @@ i915_drop_caches_write(struct file *filp,
unlock:
	mutex_unlock(&dev->struct_mutex);

	return ret ?: cnt;
	return ret;
}

static const struct file_operations i915_drop_caches_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_drop_caches_read,
	.write = i915_drop_caches_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
			i915_drop_caches_get, i915_drop_caches_set,
			"0x%08llx\n");

static ssize_t
i915_max_freq_read(struct file *filp,
		   char __user *ubuf,
		   size_t max,
		   loff_t *ppos)
static int
i915_max_freq_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len, ret;
	int ret;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
@@ -1912,42 +1806,23 @@ i915_max_freq_read(struct file *filp,
	if (ret)
		return ret;

	len = snprintf(buf, sizeof(buf),
		       "max freq: %d\n", dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER);
	*val = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
	mutex_unlock(&dev_priv->rps.hw_lock);

	if (len > sizeof(buf))
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_max_freq_write(struct file *filp,
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
static int
i915_max_freq_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int val = 1, ret;
	int ret;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val);
	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
@@ -1956,30 +1831,24 @@ i915_max_freq_write(struct file *filp,
	/*
	 * Turbo will still be enabled, but won't go above the set value.
	 */
	dev_priv->rps.max_delay = val / GT_FREQUENCY_MULTIPLIER;

	gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
	do_div(val, GT_FREQUENCY_MULTIPLIER);
	dev_priv->rps.max_delay = val;
	gen6_set_rps(dev, val);
	mutex_unlock(&dev_priv->rps.hw_lock);

	return cnt;
	return 0;
}

static const struct file_operations i915_max_freq_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_max_freq_read,
	.write = i915_max_freq_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_max_freq_fops,
			i915_max_freq_get, i915_max_freq_set,
			"max freq: %llu\n");

static ssize_t
i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max,
		   loff_t *ppos)
static int
i915_min_freq_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	int len, ret;
	int ret;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
@@ -1988,40 +1857,23 @@ i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max,
	if (ret)
		return ret;

	len = snprintf(buf, sizeof(buf),
		       "min freq: %d\n", dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER);
	*val = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
	mutex_unlock(&dev_priv->rps.hw_lock);

	if (len > sizeof(buf))
		len = sizeof(buf);

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
		    loff_t *ppos)
static int
i915_min_freq_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	int val = 1, ret;
	int ret;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
			return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val);
	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);

	ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock);
	if (ret)
@@ -2030,33 +1882,25 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt,
	/*
	 * Turbo will still be enabled, but won't go below the set value.
	 */
	dev_priv->rps.min_delay = val / GT_FREQUENCY_MULTIPLIER;

	gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER);
	do_div(val, GT_FREQUENCY_MULTIPLIER);
	dev_priv->rps.min_delay = val;
	gen6_set_rps(dev, val);
	mutex_unlock(&dev_priv->rps.hw_lock);

	return cnt;
	return 0;
}

static const struct file_operations i915_min_freq_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_min_freq_read,
	.write = i915_min_freq_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops,
			i915_min_freq_get, i915_min_freq_set,
			"min freq: %llu\n");

static ssize_t
i915_cache_sharing_read(struct file *filp,
		   char __user *ubuf,
		   size_t max,
		   loff_t *ppos)
static int
i915_cache_sharing_get(void *data, u64 *val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	drm_i915_private_t *dev_priv = dev->dev_private;
	char buf[80];
	u32 snpcr;
	int len, ret;
	int ret;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;
@@ -2068,46 +1912,25 @@ i915_cache_sharing_read(struct file *filp,
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
	mutex_unlock(&dev_priv->dev->struct_mutex);

	len = snprintf(buf, sizeof(buf),
		       "%d\n", (snpcr & GEN6_MBC_SNPCR_MASK) >>
		       GEN6_MBC_SNPCR_SHIFT);

	if (len > sizeof(buf))
		len = sizeof(buf);
	*val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT;

	return simple_read_from_buffer(ubuf, max, ppos, buf, len);
	return 0;
}

static ssize_t
i915_cache_sharing_write(struct file *filp,
		  const char __user *ubuf,
		  size_t cnt,
		  loff_t *ppos)
static int
i915_cache_sharing_set(void *data, u64 val)
{
	struct drm_device *dev = filp->private_data;
	struct drm_device *dev = data;
	struct drm_i915_private *dev_priv = dev->dev_private;
	char buf[20];
	u32 snpcr;
	int val = 1;

	if (!(IS_GEN6(dev) || IS_GEN7(dev)))
		return -ENODEV;

	if (cnt > 0) {
		if (cnt > sizeof(buf) - 1)
	if (val > 3)
		return -EINVAL;

		if (copy_from_user(buf, ubuf, cnt))
			return -EFAULT;
		buf[cnt] = 0;

		val = simple_strtoul(buf, NULL, 0);
	}

	if (val < 0 || val > 3)
		return -EINVAL;

	DRM_DEBUG_DRIVER("Manually setting uncore sharing to %d\n", val);
	DRM_DEBUG_DRIVER("Manually setting uncore sharing to %llu\n", val);

	/* Update the cache sharing policy here as well */
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
@@ -2115,16 +1938,12 @@ i915_cache_sharing_write(struct file *filp,
	snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);

	return cnt;
	return 0;
}

static const struct file_operations i915_cache_sharing_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = i915_cache_sharing_read,
	.write = i915_cache_sharing_write,
	.llseek = default_llseek,
};
DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops,
			i915_cache_sharing_get, i915_cache_sharing_set,
			"%llu\n");

/* As the drm_debugfs_init() routines are called before dev->dev_private is
 * allocated we need to hook into the minor for release. */
+19 −8
Original line number Diff line number Diff line
@@ -1452,6 +1452,22 @@ static void i915_dump_device_info(struct drm_i915_private *dev_priv)
#undef DEV_INFO_SEP
}

/**
 * intel_early_sanitize_regs - clean up BIOS state
 * @dev: DRM device
 *
 * This function must be called before we do any I915_READ or I915_WRITE. Its
 * purpose is to clean up any state left by the BIOS that may affect us when
 * reading and/or writing registers.
 */
static void intel_early_sanitize_regs(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (IS_HASWELL(dev))
		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
}

/**
 * i915_driver_load - setup chip and create an initial config
 * @dev: DRM device
@@ -1542,6 +1558,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
		goto put_gmch;
	}

	intel_early_sanitize_regs(dev);

	aperture_size = dev_priv->gtt.mappable_end;

	dev_priv->gtt.mappable =
@@ -1612,14 +1630,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	mutex_init(&dev_priv->rps.hw_lock);
	mutex_init(&dev_priv->modeset_restore_lock);

	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
		dev_priv->num_pipe = 3;
	else if (IS_MOBILE(dev) || !IS_GEN2(dev))
		dev_priv->num_pipe = 2;
	else
		dev_priv->num_pipe = 1;

	ret = drm_vblank_init(dev, dev_priv->num_pipe);
	ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
	if (ret)
		goto out_gem_unload;

+68 −64
Original line number Diff line number Diff line
@@ -121,9 +121,7 @@ MODULE_PARM_DESC(i915_enable_ppgtt,
unsigned int i915_preliminary_hw_support __read_mostly = 0;
module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
MODULE_PARM_DESC(preliminary_hw_support,
		"Enable preliminary hardware support. "
		"Enable Haswell and ValleyView Support. "
		"(default: false)");
		"Enable preliminary hardware support. (default: false)");

int i915_disable_power_well __read_mostly = 0;
module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
@@ -143,74 +141,74 @@ extern int intel_agp_enabled;
	.driver_data = (unsigned long) info }

static const struct intel_device_info intel_i830_info = {
	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1,
	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2,
	.has_overlay = 1, .overlay_needs_physical = 1,
};

static const struct intel_device_info intel_845g_info = {
	.gen = 2,
	.gen = 2, .num_pipes = 1,
	.has_overlay = 1, .overlay_needs_physical = 1,
};

static const struct intel_device_info intel_i85x_info = {
	.gen = 2, .is_i85x = 1, .is_mobile = 1,
	.gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2,
	.cursor_needs_physical = 1,
	.has_overlay = 1, .overlay_needs_physical = 1,
};

static const struct intel_device_info intel_i865g_info = {
	.gen = 2,
	.gen = 2, .num_pipes = 1,
	.has_overlay = 1, .overlay_needs_physical = 1,
};

static const struct intel_device_info intel_i915g_info = {
	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2,
	.has_overlay = 1, .overlay_needs_physical = 1,
};
static const struct intel_device_info intel_i915gm_info = {
	.gen = 3, .is_mobile = 1,
	.gen = 3, .is_mobile = 1, .num_pipes = 2,
	.cursor_needs_physical = 1,
	.has_overlay = 1, .overlay_needs_physical = 1,
	.supports_tv = 1,
};
static const struct intel_device_info intel_i945g_info = {
	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2,
	.has_overlay = 1, .overlay_needs_physical = 1,
};
static const struct intel_device_info intel_i945gm_info = {
	.gen = 3, .is_i945gm = 1, .is_mobile = 1,
	.gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2,
	.has_hotplug = 1, .cursor_needs_physical = 1,
	.has_overlay = 1, .overlay_needs_physical = 1,
	.supports_tv = 1,
};

static const struct intel_device_info intel_i965g_info = {
	.gen = 4, .is_broadwater = 1,
	.gen = 4, .is_broadwater = 1, .num_pipes = 2,
	.has_hotplug = 1,
	.has_overlay = 1,
};

static const struct intel_device_info intel_i965gm_info = {
	.gen = 4, .is_crestline = 1,
	.gen = 4, .is_crestline = 1, .num_pipes = 2,
	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
	.has_overlay = 1,
	.supports_tv = 1,
};

static const struct intel_device_info intel_g33_info = {
	.gen = 3, .is_g33 = 1,
	.gen = 3, .is_g33 = 1, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_overlay = 1,
};

static const struct intel_device_info intel_g45_info = {
	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2,
	.has_pipe_cxsr = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
};

static const struct intel_device_info intel_gm45_info = {
	.gen = 4, .is_g4x = 1,
	.gen = 4, .is_g4x = 1, .num_pipes = 2,
	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
	.has_pipe_cxsr = 1, .has_hotplug = 1,
	.supports_tv = 1,
@@ -218,26 +216,26 @@ static const struct intel_device_info intel_gm45_info = {
};

static const struct intel_device_info intel_pineview_info = {
	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_overlay = 1,
};

static const struct intel_device_info intel_ironlake_d_info = {
	.gen = 5,
	.gen = 5, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
};

static const struct intel_device_info intel_ironlake_m_info = {
	.gen = 5, .is_mobile = 1,
	.gen = 5, .is_mobile = 1, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_fbc = 1,
	.has_bsd_ring = 1,
};

static const struct intel_device_info intel_sandybridge_d_info = {
	.gen = 6,
	.gen = 6, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
@@ -246,7 +244,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
};

static const struct intel_device_info intel_sandybridge_m_info = {
	.gen = 6, .is_mobile = 1,
	.gen = 6, .is_mobile = 1, .num_pipes = 2,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_fbc = 1,
	.has_bsd_ring = 1,
@@ -255,61 +253,49 @@ static const struct intel_device_info intel_sandybridge_m_info = {
	.has_force_wake = 1,
};

#define GEN7_FEATURES  \
	.gen = 7, .num_pipes = 3, \
	.need_gfx_hws = 1, .has_hotplug = 1, \
	.has_bsd_ring = 1, \
	.has_blt_ring = 1, \
	.has_llc = 1, \
	.has_force_wake = 1

static const struct intel_device_info intel_ivybridge_d_info = {
	.is_ivybridge = 1, .gen = 7,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	.has_llc = 1,
	.has_force_wake = 1,
	GEN7_FEATURES,
	.is_ivybridge = 1,
};

static const struct intel_device_info intel_ivybridge_m_info = {
	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	.has_llc = 1,
	.has_force_wake = 1,
	GEN7_FEATURES,
	.is_ivybridge = 1,
	.is_mobile = 1,
};

static const struct intel_device_info intel_valleyview_m_info = {
	.gen = 7, .is_mobile = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_fbc = 0,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	GEN7_FEATURES,
	.is_mobile = 1,
	.num_pipes = 2,
	.is_valleyview = 1,
	.display_mmio_offset = VLV_DISPLAY_BASE,
};

static const struct intel_device_info intel_valleyview_d_info = {
	.gen = 7,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_fbc = 0,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	GEN7_FEATURES,
	.num_pipes = 2,
	.is_valleyview = 1,
	.display_mmio_offset = VLV_DISPLAY_BASE,
};

static const struct intel_device_info intel_haswell_d_info = {
	.is_haswell = 1, .gen = 7,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	.has_llc = 1,
	.has_force_wake = 1,
	GEN7_FEATURES,
	.is_haswell = 1,
};

static const struct intel_device_info intel_haswell_m_info = {
	.is_haswell = 1, .gen = 7, .is_mobile = 1,
	.need_gfx_hws = 1, .has_hotplug = 1,
	.has_bsd_ring = 1,
	.has_blt_ring = 1,
	.has_llc = 1,
	.has_force_wake = 1,
	GEN7_FEATURES,
	.is_haswell = 1,
	.is_mobile = 1,
};

static const struct pci_device_id pciidlist[] = {		/* aka */
@@ -394,6 +380,9 @@ static const struct pci_device_id pciidlist[] = { /* aka */
	INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
	INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
	INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
	INTEL_VGA_DEVICE(0x0f31, &intel_valleyview_m_info),
	INTEL_VGA_DEVICE(0x0f32, &intel_valleyview_m_info),
	INTEL_VGA_DEVICE(0x0f33, &intel_valleyview_m_info),
	INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
	INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
	{0, 0, 0}
@@ -1147,6 +1136,27 @@ ilk_dummy_write(struct drm_i915_private *dev_priv)
	I915_WRITE_NOTRACE(MI_MODE, 0);
}

static void
hsw_unclaimed_reg_clear(struct drm_i915_private *dev_priv, u32 reg)
{
	if (IS_HASWELL(dev_priv->dev) &&
	    (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
		DRM_ERROR("Unknown unclaimed register before writing to %x\n",
			  reg);
		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
	}
}

static void
hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg)
{
	if (IS_HASWELL(dev_priv->dev) &&
	    (I915_READ_NOTRACE(FPGA_DBG) & FPGA_DBG_RM_NOCLAIM)) {
		DRM_ERROR("Unclaimed write to %x\n", reg);
		I915_WRITE_NOTRACE(FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
	}
}

#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
	u##x val = 0; \
@@ -1183,18 +1193,12 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
	} \
	if (IS_GEN5(dev_priv->dev)) \
		ilk_dummy_write(dev_priv); \
	if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
		DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \
		I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \
	} \
	hsw_unclaimed_reg_clear(dev_priv, reg); \
	write##y(val, dev_priv->regs + reg); \
	if (unlikely(__fifo_ret)) { \
		gen6_gt_check_fifodbg(dev_priv); \
	} \
	if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
		DRM_ERROR("Unclaimed write to %x\n", reg); \
		writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT);	\
	} \
	hsw_unclaimed_reg_check(dev_priv, reg); \
}
__i915_write(8, b)
__i915_write(16, w)
Loading