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

Commit de96355c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (55 commits)
  Revert "drm/i915: Try enabling RC6 by default (again)"
  drm/radeon: Extended DDC Probing for ECS A740GM-M DVI-D Connector
  drm/radeon: Log Subsystem Vendor and Device Information
  drm/radeon: Extended DDC Probing for Connectors with Improperly Wired DDC Lines (here: Asus M2A-VM HDMI)
  drm: Separate EDID Header Check from EDID Block Check
  drm: Add NULL check about irq functions
  drm: Fix irq install error handling
  drm/radeon: fix potential NULL dereference in drivers/gpu/drm/radeon/atom.c
  drm/radeon: clean reg header files
  drm/debugfs: Initialise empty variable
  drm/radeon/kms: add thermal chip quirk for asus 9600xt
  drm/radeon: off by one in check_reg() functions
  drm/radeon/kms: fix version comment due to merge timing
  drm/i915: allow cache sharing policy control
  drm/i915/hdmi: HDMI source product description infoframe support
  drm/i915/hdmi: split infoframe setting from infoframe type code
  drm: track CEA version number if present
  drm/i915: Try enabling RC6 by default (again)
  Revert "drm/i915/dp: Zero the DPCD data before connection probe"
  drm/i915/dp: wait for previous AUX channel activity to clear
  ...
parents 8cd290a0 39060a07
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -90,7 +90,6 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
	struct drm_device *dev = minor->dev;
	struct dentry *ent;
	struct drm_info_node *tmp;
	char name[64];
	int i, ret;

	for (i = 0; i < count; i++) {
@@ -108,6 +107,9 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count,
		ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
					  root, tmp, &drm_debugfs_fops);
		if (!ent) {
			char name[64];
			strncpy(name, root->d_name.name,
						min(root->d_name.len, 64U));
			DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n",
				  name, files[i].name);
			kfree(tmp);
+27 −6
Original line number Diff line number Diff line
@@ -127,6 +127,23 @@ static const u8 edid_header[] = {
	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
};

 /*
 * Sanity check the header of the base EDID block.  Return 8 if the header
 * is perfect, down to 0 if it's totally wrong.
 */
int drm_edid_header_is_valid(const u8 *raw_edid)
{
	int i, score = 0;

	for (i = 0; i < sizeof(edid_header); i++)
		if (raw_edid[i] == edid_header[i])
			score++;

	return score;
}
EXPORT_SYMBOL(drm_edid_header_is_valid);


/*
 * Sanity check the EDID block (base or extension).  Return 0 if the block
 * doesn't check out, or 1 if it's valid.
@@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid)
	struct edid *edid = (struct edid *)raw_edid;

	if (raw_edid[0] == 0x00) {
		int score = 0;

		for (i = 0; i < sizeof(edid_header); i++)
			if (raw_edid[i] == edid_header[i])
				score++;

		int score = drm_edid_header_is_valid(raw_edid);
		if (score == 8) ;
		else if (score >= 6) {
			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
@@ -1439,6 +1451,8 @@ EXPORT_SYMBOL(drm_detect_monitor_audio);
static void drm_add_display_info(struct edid *edid,
				 struct drm_display_info *info)
{
	u8 *edid_ext;

	info->width_mm = edid->width_cm * 10;
	info->height_mm = edid->height_cm * 10;

@@ -1483,6 +1497,13 @@ static void drm_add_display_info(struct edid *edid,
		info->color_formats = DRM_COLOR_FORMAT_YCRCB444;
	if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422)
		info->color_formats = DRM_COLOR_FORMAT_YCRCB422;

	/* Get data from CEA blocks if present */
	edid_ext = drm_find_cea_extension(edid);
	if (!edid_ext)
		return;

	info->cea_rev = edid_ext[1];
}

/**
+18 −8
Original line number Diff line number Diff line
@@ -291,10 +291,13 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
	if (!dev->irq_enabled)
		return;

	if (state)
	if (state) {
		if (dev->driver->irq_uninstall)
			dev->driver->irq_uninstall(dev);
	else {
	} else {
		if (dev->driver->irq_preinstall)
			dev->driver->irq_preinstall(dev);
		if (dev->driver->irq_postinstall)
			dev->driver->irq_postinstall(dev);
	}
}
@@ -338,6 +341,7 @@ int drm_irq_install(struct drm_device *dev)
	DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));

	/* Before installing handler */
	if (dev->driver->irq_preinstall)
		dev->driver->irq_preinstall(dev);

	/* Install handler */
@@ -363,11 +367,16 @@ int drm_irq_install(struct drm_device *dev)
		vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);

	/* After installing handler */
	if (dev->driver->irq_postinstall)
		ret = dev->driver->irq_postinstall(dev);

	if (ret < 0) {
		mutex_lock(&dev->struct_mutex);
		dev->irq_enabled = 0;
		mutex_unlock(&dev->struct_mutex);
		if (!drm_core_check_feature(dev, DRIVER_MODESET))
			vga_client_register(dev->pdev, NULL, NULL, NULL);
		free_irq(drm_dev_to_irq(dev), dev);
	}

	return ret;
@@ -413,6 +422,7 @@ int drm_irq_uninstall(struct drm_device *dev)
	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		vga_client_register(dev->pdev, NULL, NULL, NULL);

	if (dev->driver->irq_uninstall)
		dev->driver->irq_uninstall(dev);

	free_irq(drm_dev_to_irq(dev), dev);
+189 −0
Original line number Diff line number Diff line
@@ -1338,6 +1338,155 @@ static const struct file_operations i915_wedged_fops = {
	.llseek = default_llseek,
};

static int
i915_max_freq_open(struct inode *inode,
		   struct file *filp)
{
	filp->private_data = inode->i_private;
	return 0;
}

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

	len = snprintf(buf, sizeof (buf),
		       "max freq: %d\n", dev_priv->max_delay * 50);

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

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

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

	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);

	/*
	 * Turbo will still be enabled, but won't go above the set value.
	 */
	dev_priv->max_delay = val / 50;

	gen6_set_rps(dev, val / 50);

	return cnt;
}

static const struct file_operations i915_max_freq_fops = {
	.owner = THIS_MODULE,
	.open = i915_max_freq_open,
	.read = i915_max_freq_read,
	.write = i915_max_freq_write,
	.llseek = default_llseek,
};

static int
i915_cache_sharing_open(struct inode *inode,
		   struct file *filp)
{
	filp->private_data = inode->i_private;
	return 0;
}

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

	mutex_lock(&dev_priv->dev->struct_mutex);
	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);

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

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

	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);
	}

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

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

	/* Update the cache sharing policy here as well */
	snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
	snpcr &= ~GEN6_MBC_SNPCR_MASK;
	snpcr |= (val << GEN6_MBC_SNPCR_SHIFT);
	I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);

	return cnt;
}

static const struct file_operations i915_cache_sharing_fops = {
	.owner = THIS_MODULE,
	.open = i915_cache_sharing_open,
	.read = i915_cache_sharing_read,
	.write = i915_cache_sharing_write,
	.llseek = default_llseek,
};

/* As the drm_debugfs_init() routines are called before dev->dev_private is
 * allocated we need to hook into the minor for release. */
static int
@@ -1437,6 +1586,36 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
	return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
}

static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor)
{
	struct drm_device *dev = minor->dev;
	struct dentry *ent;

	ent = debugfs_create_file("i915_max_freq",
				  S_IRUGO | S_IWUSR,
				  root, dev,
				  &i915_max_freq_fops);
	if (IS_ERR(ent))
		return PTR_ERR(ent);

	return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops);
}

static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor)
{
	struct drm_device *dev = minor->dev;
	struct dentry *ent;

	ent = debugfs_create_file("i915_cache_sharing",
				  S_IRUGO | S_IWUSR,
				  root, dev,
				  &i915_cache_sharing_fops);
	if (IS_ERR(ent))
		return PTR_ERR(ent);

	return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops);
}

static struct drm_info_list i915_debugfs_list[] = {
	{"i915_capabilities", i915_capabilities, 0},
	{"i915_gem_objects", i915_gem_object_info, 0},
@@ -1488,6 +1667,12 @@ int i915_debugfs_init(struct drm_minor *minor)
		return ret;

	ret = i915_forcewake_create(minor->debugfs_root, minor);
	if (ret)
		return ret;
	ret = i915_max_freq_create(minor->debugfs_root, minor);
	if (ret)
		return ret;
	ret = i915_cache_sharing_create(minor->debugfs_root, minor);
	if (ret)
		return ret;

@@ -1504,6 +1689,10 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops,
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops,
				 1, minor);
}

#endif /* CONFIG_DEBUG_FS */
+2 −4
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ static void i915_write_hws_pga(struct drm_device *dev)
static int i915_init_phys_hws(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct intel_ring_buffer *ring = LP_RING(dev_priv);

	/* Program Hardware Status Page */
	dev_priv->status_page_dmah =
@@ -71,10 +70,9 @@ static int i915_init_phys_hws(struct drm_device *dev)
		DRM_ERROR("Can not allocate hardware status page\n");
		return -ENOMEM;
	}
	ring->status_page.page_addr =
		(void __force __iomem *)dev_priv->status_page_dmah->vaddr;

	memset_io(ring->status_page.page_addr, 0, PAGE_SIZE);
	memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr,
		  0, PAGE_SIZE);

	i915_write_hws_pga(dev);

Loading