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

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

Merge tag 'drm-intel-next-2012-12-21' of...

Merge tag 'drm-intel-next-2012-12-21' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Daniel writes:
- seqno wrap fixes and debug infrastructure from Mika Kuoppala and Chris
  Wilson
- some leftover kill-agp on gen6+ patches from Ben
- hotplug improvements from Damien
- clear fb when allocated from stolen, avoids dirt on the fbcon (Chris)
- Stolen mem support from Chris Wilson, one of the many steps to get to
  real fastboot support.
- Some DDI code cleanups from Paulo.
- Some refactorings around lvds and dp code.
- some random little bits&pieces

* tag 'drm-intel-next-2012-12-21' of git://people.freedesktop.org/~danvet/drm-intel: (93 commits)
  drm/i915: Return the real error code from intel_set_mode()
  drm/i915: Make GSM void
  drm/i915: Move GSM mapping into dev_priv
  drm/i915: Move even more gtt code to i915_gem_gtt
  drm/i915: Make next_seqno debugs entry to use i915_gem_set_seqno
  drm/i915: Introduce i915_gem_set_seqno()
  drm/i915: Always clear semaphore mboxes on seqno wrap
  drm/i915: Initialize hardware semaphore state on ring init
  drm/i915: Introduce ring set_seqno
  drm/i915: Missed conversion to gtt_pte_t
  drm/i915: Bug on unsupported swizzled platforms
  drm/i915: BUG() if fences are used on unsupported platform
  drm/i915: fixup overlay stolen memory leak
  drm/i915: clean up PIPECONF bpc #defines
  drm/i915: add intel_dp_set_signal_levels
  drm/i915: remove leftover display.update_wm assignment
  drm/i915: check for the PCH when setting pch_transcoder
  drm/i915: Clear the stolen fb before enabling
  drm/i915: Access to snooped system memory through the GTT is incoherent
  drm/i915: Remove stale comment about intel_dp_detect()
  ...

Conflicts:
	drivers/gpu/drm/i915/intel_display.c
parents 9931faca c0c36b94
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -602,7 +602,6 @@ static int intel_gtt_init(void)
		iounmap(intel_private.registers);
		return -ENOMEM;
	}
	intel_private.base.gtt = intel_private.gtt;

	global_cache_flush();   /* FIXME: ? */

+63 −33
Original line number Diff line number Diff line
@@ -102,20 +102,6 @@ int drm_mm_pre_get(struct drm_mm *mm)
}
EXPORT_SYMBOL(drm_mm_pre_get);

static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
{
	return hole_node->start + hole_node->size;
}

static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
{
	struct drm_mm_node *next_node =
		list_entry(hole_node->node_list.next, struct drm_mm_node,
			   node_list);

	return next_node->start;
}

static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
				 struct drm_mm_node *node,
				 unsigned long size, unsigned alignment,
@@ -127,7 +113,7 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
	unsigned long adj_start = hole_start;
	unsigned long adj_end = hole_end;

	BUG_ON(!hole_node->hole_follows || node->allocated);
	BUG_ON(node->allocated);

	if (mm->color_adjust)
		mm->color_adjust(hole_node, color, &adj_start, &adj_end);
@@ -155,12 +141,57 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
	BUG_ON(node->start + node->size > adj_end);

	node->hole_follows = 0;
	if (node->start + node->size < hole_end) {
	if (__drm_mm_hole_node_start(node) < hole_end) {
		list_add(&node->hole_stack, &mm->hole_stack);
		node->hole_follows = 1;
	}
}

struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm,
					unsigned long start,
					unsigned long size,
					bool atomic)
{
	struct drm_mm_node *hole, *node;
	unsigned long end = start + size;
	unsigned long hole_start;
	unsigned long hole_end;

	drm_mm_for_each_hole(hole, mm, hole_start, hole_end) {
		if (hole_start > start || hole_end < end)
			continue;

		node = drm_mm_kmalloc(mm, atomic);
		if (unlikely(node == NULL))
			return NULL;

		node->start = start;
		node->size = size;
		node->mm = mm;
		node->allocated = 1;

		INIT_LIST_HEAD(&node->hole_stack);
		list_add(&node->node_list, &hole->node_list);

		if (start == hole_start) {
			hole->hole_follows = 0;
			list_del_init(&hole->hole_stack);
		}

		node->hole_follows = 0;
		if (end != hole_end) {
			list_add(&node->hole_stack, &mm->hole_stack);
			node->hole_follows = 1;
		}

		return node;
	}

	WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size);
	return NULL;
}
EXPORT_SYMBOL(drm_mm_create_block);

struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,
					     unsigned long size,
					     unsigned alignment,
@@ -251,7 +282,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
	BUG_ON(node->start + node->size > end);

	node->hole_follows = 0;
	if (node->start + node->size < hole_end) {
	if (__drm_mm_hole_node_start(node) < hole_end) {
		list_add(&node->hole_stack, &mm->hole_stack);
		node->hole_follows = 1;
	}
@@ -325,12 +356,13 @@ void drm_mm_remove_node(struct drm_mm_node *node)
	    list_entry(node->node_list.prev, struct drm_mm_node, node_list);

	if (node->hole_follows) {
		BUG_ON(drm_mm_hole_node_start(node)
				== drm_mm_hole_node_end(node));
		BUG_ON(__drm_mm_hole_node_start(node) ==
		       __drm_mm_hole_node_end(node));
		list_del(&node->hole_stack);
	} else
		BUG_ON(drm_mm_hole_node_start(node)
				!= drm_mm_hole_node_end(node));
		BUG_ON(__drm_mm_hole_node_start(node) !=
		       __drm_mm_hole_node_end(node));


	if (!prev_node->hole_follows) {
		prev_node->hole_follows = 1;
@@ -388,6 +420,8 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
{
	struct drm_mm_node *entry;
	struct drm_mm_node *best;
	unsigned long adj_start;
	unsigned long adj_end;
	unsigned long best_size;

	BUG_ON(mm->scanned_blocks);
@@ -395,17 +429,13 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
	best = NULL;
	best_size = ~0UL;

	list_for_each_entry(entry, &mm->hole_stack, hole_stack) {
		unsigned long adj_start = drm_mm_hole_node_start(entry);
		unsigned long adj_end = drm_mm_hole_node_end(entry);

	drm_mm_for_each_hole(entry, mm, adj_start, adj_end) {
		if (mm->color_adjust) {
			mm->color_adjust(entry, color, &adj_start, &adj_end);
			if (adj_end <= adj_start)
				continue;
		}

		BUG_ON(!entry->hole_follows);
		if (!check_free_hole(adj_start, adj_end, size, alignment))
			continue;

@@ -432,6 +462,8 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
{
	struct drm_mm_node *entry;
	struct drm_mm_node *best;
	unsigned long adj_start;
	unsigned long adj_end;
	unsigned long best_size;

	BUG_ON(mm->scanned_blocks);
@@ -439,13 +471,11 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
	best = NULL;
	best_size = ~0UL;

	list_for_each_entry(entry, &mm->hole_stack, hole_stack) {
		unsigned long adj_start = drm_mm_hole_node_start(entry) < start ?
			start : drm_mm_hole_node_start(entry);
		unsigned long adj_end = drm_mm_hole_node_end(entry) > end ?
			end : drm_mm_hole_node_end(entry);

		BUG_ON(!entry->hole_follows);
	drm_mm_for_each_hole(entry, mm, adj_start, adj_end) {
		if (adj_start < start)
			adj_start = start;
		if (adj_end > end)
			adj_end = end;

		if (mm->color_adjust) {
			mm->color_adjust(entry, color, &adj_start, &adj_end);
+88 −7
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ static const char *cache_level_str(int type)
static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
	seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d %d%s%s%s",
	seq_printf(m, "%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
		   &obj->base,
		   get_pin_flag(obj),
		   get_tiling_flag(obj),
@@ -124,6 +124,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
	if (obj->gtt_space != NULL)
		seq_printf(m, " (gtt offset: %08x, size: %08x)",
			   obj->gtt_offset, (unsigned int)obj->gtt_space->size);
	if (obj->stolen)
		seq_printf(m, " (stolen: %08lx)", obj->stolen->start);
	if (obj->pin_mappable || obj->fault_mappable) {
		char s[3], *t = s;
		if (obj->pin_mappable)
@@ -387,7 +389,7 @@ static void i915_ring_seqno_info(struct seq_file *m,
				 struct intel_ring_buffer *ring)
{
	if (ring->get_seqno) {
		seq_printf(m, "Current sequence (%s): %d\n",
		seq_printf(m, "Current sequence (%s): %u\n",
			   ring->name, ring->get_seqno(ring, false));
	}
}
@@ -544,11 +546,11 @@ static int i915_hws_info(struct seq_file *m, void *data)
	struct drm_device *dev = node->minor->dev;
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct intel_ring_buffer *ring;
	const volatile u32 __iomem *hws;
	const u32 *hws;
	int i;

	ring = &dev_priv->ring[(uintptr_t)node->info_ent->data];
	hws = (volatile u32 __iomem *)ring->status_page.page_addr;
	hws = ring->status_page.page_addr;
	if (hws == NULL)
		return 0;

@@ -608,7 +610,7 @@ static void print_error_buffers(struct seq_file *m,
	seq_printf(m, "%s [%d]:\n", name, count);

	while (count--) {
		seq_printf(m, "  %08x %8u %04x %04x %x %x%s%s%s%s%s%s%s",
		seq_printf(m, "  %08x %8u %02x %02x %x %x%s%s%s%s%s%s%s",
			   err->gtt_offset,
			   err->size,
			   err->read_domains,
@@ -841,6 +843,77 @@ 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)
{
	struct drm_device *dev = filp->private_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);

	mutex_unlock(&dev->struct_mutex);

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

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

static ssize_t
i915_next_seqno_write(struct file *filp,
		      const char __user *ubuf,
		      size_t cnt,
		      loff_t *ppos)
{
	struct drm_device *dev = filp->private_data;
	char buf[20];
	u32 val = 1;
	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;
}

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

static int i915_rstdby_delays(struct seq_file *m, void *unused)
{
	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -1551,7 +1624,7 @@ static int i915_dpio_info(struct seq_file *m, void *data)
		return 0;
	}

	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
	ret = mutex_lock_interruptible(&dev_priv->dpio_lock);
	if (ret)
		return ret;

@@ -1580,7 +1653,7 @@ static int i915_dpio_info(struct seq_file *m, void *data)
	seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
		   intel_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));

	mutex_unlock(&dev->mode_config.mutex);
	mutex_unlock(&dev_priv->dpio_lock);

	return 0;
}
@@ -2105,6 +2178,12 @@ int i915_debugfs_init(struct drm_minor *minor)
	if (ret)
		return ret;

	ret = i915_debugfs_create(minor->debugfs_root, minor,
				 "i915_next_seqno",
				 &i915_next_seqno_fops);
	if (ret)
		return ret;

	return drm_debugfs_create_files(i915_debugfs_list,
					I915_DEBUGFS_ENTRIES,
					minor->debugfs_root, minor);
@@ -2128,6 +2207,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_error_state_fops,
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_next_seqno_fops,
				 1, minor);
}

#endif /* CONFIG_DEBUG_FS */
+34 −16
Original line number Diff line number Diff line
@@ -1297,19 +1297,21 @@ static int i915_load_modeset_init(struct drm_device *dev)
	if (ret)
		goto cleanup_vga_switcheroo;

	ret = drm_irq_install(dev);
	if (ret)
		goto cleanup_gem_stolen;

	/* Important: The output setup functions called by modeset_init need
	 * working irqs for e.g. gmbus and dp aux transfers. */
	intel_modeset_init(dev);

	ret = i915_gem_init(dev);
	if (ret)
		goto cleanup_gem_stolen;

	intel_modeset_gem_init(dev);
		goto cleanup_irq;

	INIT_WORK(&dev_priv->console_resume_work, intel_console_resume);

	ret = drm_irq_install(dev);
	if (ret)
		goto cleanup_gem;
	intel_modeset_gem_init(dev);

	/* Always safe in the mode setting case. */
	/* FIXME: do pre/post-mode set stuff in core KMS code */
@@ -1317,7 +1319,25 @@ static int i915_load_modeset_init(struct drm_device *dev)

	ret = intel_fbdev_init(dev);
	if (ret)
		goto cleanup_irq;
		goto cleanup_gem;

	/* Only enable hotplug handling once the fbdev is fully set up. */
	intel_hpd_init(dev);

	/*
	 * Some ports require correctly set-up hpd registers for detection to
	 * work properly (leading to ghost connected connector status), e.g. VGA
	 * on gm45.  Hence we can only set up the initial fbdev config after hpd
	 * irqs are fully enabled. Now we should scan for the initial config
	 * only once hotplug handling is enabled, but due to screwed-up locking
	 * around kms/fbdev init we can't protect the fdbev initial config
	 * scanning against hotplug events. Hence do this first and ignore the
	 * tiny window where we will loose hotplug notifactions.
	 */
	intel_fbdev_initial_config(dev);

	/* Only enable hotplug handling once the fbdev is fully set up. */
	dev_priv->enable_hotplug_processing = true;

	drm_kms_helper_poll_init(dev);

@@ -1326,13 +1346,13 @@ static int i915_load_modeset_init(struct drm_device *dev)

	return 0;

cleanup_irq:
	drm_irq_uninstall(dev);
cleanup_gem:
	mutex_lock(&dev->struct_mutex);
	i915_gem_cleanup_ringbuffer(dev);
	mutex_unlock(&dev->struct_mutex);
	i915_gem_cleanup_aliasing_ppgtt(dev);
cleanup_irq:
	drm_irq_uninstall(dev);
cleanup_gem_stolen:
	i915_gem_cleanup_stolen(dev);
cleanup_vga_switcheroo:
@@ -1582,7 +1602,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	spin_lock_init(&dev_priv->irq_lock);
	spin_lock_init(&dev_priv->error_lock);
	spin_lock_init(&dev_priv->rps.lock);
	spin_lock_init(&dev_priv->dpio_lock);
	mutex_init(&dev_priv->dpio_lock);

	mutex_init(&dev_priv->rps.hw_lock);

@@ -1614,9 +1634,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	intel_opregion_init(dev);
	acpi_video_register();

	setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
		    (unsigned long) dev);

	if (IS_GEN5(dev))
		intel_gpu_ips_init(dev_priv);

@@ -1723,9 +1740,6 @@ int i915_driver_unload(struct drm_device *dev)
		mutex_unlock(&dev->struct_mutex);
		i915_gem_cleanup_aliasing_ppgtt(dev);
		i915_gem_cleanup_stolen(dev);
		drm_mm_takedown(&dev_priv->mm.stolen);

		intel_cleanup_overlay(dev);

		if (!I915_NEED_GFX_HWS(dev))
			i915_free_hws(dev);
@@ -1738,6 +1752,10 @@ int i915_driver_unload(struct drm_device *dev)
	intel_teardown_mchbar(dev);

	destroy_workqueue(dev_priv->wq);
	pm_qos_remove_request(&dev_priv->pm_qos);

	if (dev_priv->slab)
		kmem_cache_destroy(dev_priv->slab);

	pci_dev_put(dev_priv->bridge_dev);
	kfree(dev->dev_private);
+2 −0
Original line number Diff line number Diff line
@@ -565,6 +565,7 @@ static int __i915_drm_thaw(struct drm_device *dev)
		intel_modeset_init_hw(dev);
		intel_modeset_setup_hw_state(dev, false);
		drm_irq_install(dev);
		intel_hpd_init(dev);
	}

	intel_opregion_init(dev);
@@ -870,6 +871,7 @@ int i915_reset(struct drm_device *dev)

		drm_irq_uninstall(dev);
		drm_irq_install(dev);
		intel_hpd_init(dev);
	} else {
		mutex_unlock(&dev->struct_mutex);
	}
Loading