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

Commit af13e867 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Radeon, imx, msm, and i915 fixes.

  The msm, imx and i915 ones are fairly run of the mill.

  Radeon had some DP audio and posting reads for irq fixes, along with a
  fix for 32-bit kernels with new cards, we were using unsigned long to
  represent GPU side memory space, but since that changed size on 32 vs
  64 cards with lots of VRAM failed, so the change has no effect on
  x86-64, just moves to using uint64_t instead"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (35 commits)
  drm/msm: kexec fixes
  drm/msm/mdp5: fix cursor blending
  drm/msm/mdp5: fix cursor ROI
  drm/msm/atomic: Don't leak atomic commit object when commit fails
  drm/msm/mdp5: Avoid flushing registers when CRTC is disabled
  drm/msm: update generated headers (add 6th lm.base entry)
  drm/msm/mdp5: fixup "drm/msm: fix fallout of atomic dpms changes"
  drm/ttm: device address space != CPU address space
  drm/mm: Support 4 GiB and larger ranges
  drm/i915: gen4: work around hang during hibernation
  drm/i915: Check for driver readyness before handling an underrun interrupt
  drm/radeon: fix interlaced modes on DCE8
  drm/radeon: fix DRM_IOCTL_RADEON_CS oops
  drm/radeon: do a posting read in cik_set_irq
  drm/radeon: do a posting read in si_set_irq
  drm/radeon: do a posting read in evergreen_set_irq
  drm/radeon: do a posting read in r600_set_irq
  drm/radeon: do a posting read in rs600_set_irq
  drm/radeon: do a posting read in r100_set_irq
  radeon/audio: fix DP audio on DCE6
  ...
parents 84399bb0 f6bec6ea
Loading
Loading
Loading
Loading
+79 −73
Original line number Diff line number Diff line
@@ -91,29 +91,29 @@
 */

static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
						unsigned long size,
						u64 size,
						unsigned alignment,
						unsigned long color,
						enum drm_mm_search_flags flags);
static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
						unsigned long size,
						u64 size,
						unsigned alignment,
						unsigned long color,
						unsigned long start,
						unsigned long end,
						u64 start,
						u64 end,
						enum drm_mm_search_flags flags);

static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
				 struct drm_mm_node *node,
				 unsigned long size, unsigned alignment,
				 u64 size, unsigned alignment,
				 unsigned long color,
				 enum drm_mm_allocator_flags flags)
{
	struct drm_mm *mm = hole_node->mm;
	unsigned long hole_start = drm_mm_hole_node_start(hole_node);
	unsigned long hole_end = drm_mm_hole_node_end(hole_node);
	unsigned long adj_start = hole_start;
	unsigned long adj_end = hole_end;
	u64 hole_start = drm_mm_hole_node_start(hole_node);
	u64 hole_end = drm_mm_hole_node_end(hole_node);
	u64 adj_start = hole_start;
	u64 adj_end = hole_end;

	BUG_ON(node->allocated);

@@ -124,12 +124,15 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
		adj_start = adj_end - size;

	if (alignment) {
		unsigned tmp = adj_start % alignment;
		if (tmp) {
		u64 tmp = adj_start;
		unsigned rem;

		rem = do_div(tmp, alignment);
		if (rem) {
			if (flags & DRM_MM_CREATE_TOP)
				adj_start -= tmp;
				adj_start -= rem;
			else
				adj_start += alignment - tmp;
				adj_start += alignment - rem;
		}
	}

@@ -176,9 +179,9 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
{
	struct drm_mm_node *hole;
	unsigned long end = node->start + node->size;
	unsigned long hole_start;
	unsigned long hole_end;
	u64 end = node->start + node->size;
	u64 hole_start;
	u64 hole_end;

	BUG_ON(node == NULL);

@@ -227,7 +230,7 @@ EXPORT_SYMBOL(drm_mm_reserve_node);
 * 0 on success, -ENOSPC if there's no suitable hole.
 */
int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
			       unsigned long size, unsigned alignment,
			       u64 size, unsigned alignment,
			       unsigned long color,
			       enum drm_mm_search_flags sflags,
			       enum drm_mm_allocator_flags aflags)
@@ -246,16 +249,16 @@ EXPORT_SYMBOL(drm_mm_insert_node_generic);

static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
				       struct drm_mm_node *node,
				       unsigned long size, unsigned alignment,
				       u64 size, unsigned alignment,
				       unsigned long color,
				       unsigned long start, unsigned long end,
				       u64 start, u64 end,
				       enum drm_mm_allocator_flags flags)
{
	struct drm_mm *mm = hole_node->mm;
	unsigned long hole_start = drm_mm_hole_node_start(hole_node);
	unsigned long hole_end = drm_mm_hole_node_end(hole_node);
	unsigned long adj_start = hole_start;
	unsigned long adj_end = hole_end;
	u64 hole_start = drm_mm_hole_node_start(hole_node);
	u64 hole_end = drm_mm_hole_node_end(hole_node);
	u64 adj_start = hole_start;
	u64 adj_end = hole_end;

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

@@ -271,12 +274,15 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
		mm->color_adjust(hole_node, color, &adj_start, &adj_end);

	if (alignment) {
		unsigned tmp = adj_start % alignment;
		if (tmp) {
		u64 tmp = adj_start;
		unsigned rem;

		rem = do_div(tmp, alignment);
		if (rem) {
			if (flags & DRM_MM_CREATE_TOP)
				adj_start -= tmp;
				adj_start -= rem;
			else
				adj_start += alignment - tmp;
				adj_start += alignment - rem;
		}
	}

@@ -324,9 +330,9 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
 * 0 on success, -ENOSPC if there's no suitable hole.
 */
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node,
					unsigned long size, unsigned alignment,
					u64 size, unsigned alignment,
					unsigned long color,
					unsigned long start, unsigned long end,
					u64 start, u64 end,
					enum drm_mm_search_flags sflags,
					enum drm_mm_allocator_flags aflags)
{
@@ -387,32 +393,34 @@ void drm_mm_remove_node(struct drm_mm_node *node)
}
EXPORT_SYMBOL(drm_mm_remove_node);

static int check_free_hole(unsigned long start, unsigned long end,
			   unsigned long size, unsigned alignment)
static int check_free_hole(u64 start, u64 end, u64 size, unsigned alignment)
{
	if (end - start < size)
		return 0;

	if (alignment) {
		unsigned tmp = start % alignment;
		u64 tmp = start;
		unsigned rem;

		rem = do_div(tmp, alignment);
		if (tmp)
			start += alignment - tmp;
			start += alignment - rem;
	}

	return end >= start + size;
}

static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
						      unsigned long size,
						      u64 size,
						      unsigned alignment,
						      unsigned long color,
						      enum drm_mm_search_flags flags)
{
	struct drm_mm_node *entry;
	struct drm_mm_node *best;
	unsigned long adj_start;
	unsigned long adj_end;
	unsigned long best_size;
	u64 adj_start;
	u64 adj_end;
	u64 best_size;

	BUG_ON(mm->scanned_blocks);

@@ -421,7 +429,7 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,

	__drm_mm_for_each_hole(entry, mm, adj_start, adj_end,
			       flags & DRM_MM_SEARCH_BELOW) {
		unsigned long hole_size = adj_end - adj_start;
		u64 hole_size = adj_end - adj_start;

		if (mm->color_adjust) {
			mm->color_adjust(entry, color, &adj_start, &adj_end);
@@ -445,18 +453,18 @@ static struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,
}

static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,
							unsigned long size,
							u64 size,
							unsigned alignment,
							unsigned long color,
							unsigned long start,
							unsigned long end,
							u64 start,
							u64 end,
							enum drm_mm_search_flags flags)
{
	struct drm_mm_node *entry;
	struct drm_mm_node *best;
	unsigned long adj_start;
	unsigned long adj_end;
	unsigned long best_size;
	u64 adj_start;
	u64 adj_end;
	u64 best_size;

	BUG_ON(mm->scanned_blocks);

@@ -465,7 +473,7 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_

	__drm_mm_for_each_hole(entry, mm, adj_start, adj_end,
			       flags & DRM_MM_SEARCH_BELOW) {
		unsigned long hole_size = adj_end - adj_start;
		u64 hole_size = adj_end - adj_start;

		if (adj_start < start)
			adj_start = start;
@@ -561,7 +569,7 @@ EXPORT_SYMBOL(drm_mm_replace_node);
 * adding/removing nodes to/from the scan list are allowed.
 */
void drm_mm_init_scan(struct drm_mm *mm,
		      unsigned long size,
		      u64 size,
		      unsigned alignment,
		      unsigned long color)
{
@@ -594,11 +602,11 @@ EXPORT_SYMBOL(drm_mm_init_scan);
 * adding/removing nodes to/from the scan list are allowed.
 */
void drm_mm_init_scan_with_range(struct drm_mm *mm,
				 unsigned long size,
				 u64 size,
				 unsigned alignment,
				 unsigned long color,
				 unsigned long start,
				 unsigned long end)
				 u64 start,
				 u64 end)
{
	mm->scan_color = color;
	mm->scan_alignment = alignment;
@@ -627,8 +635,8 @@ bool drm_mm_scan_add_block(struct drm_mm_node *node)
{
	struct drm_mm *mm = node->mm;
	struct drm_mm_node *prev_node;
	unsigned long hole_start, hole_end;
	unsigned long adj_start, adj_end;
	u64 hole_start, hole_end;
	u64 adj_start, adj_end;

	mm->scanned_blocks++;

@@ -731,7 +739,7 @@ EXPORT_SYMBOL(drm_mm_clean);
 *
 * Note that @mm must be cleared to 0 before calling this function.
 */
void drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
void drm_mm_init(struct drm_mm * mm, u64 start, u64 size)
{
	INIT_LIST_HEAD(&mm->hole_stack);
	mm->scanned_blocks = 0;
@@ -766,18 +774,17 @@ void drm_mm_takedown(struct drm_mm * mm)
}
EXPORT_SYMBOL(drm_mm_takedown);

static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry,
static u64 drm_mm_debug_hole(struct drm_mm_node *entry,
				     const char *prefix)
{
	unsigned long hole_start, hole_end, hole_size;
	u64 hole_start, hole_end, hole_size;

	if (entry->hole_follows) {
		hole_start = drm_mm_hole_node_start(entry);
		hole_end = drm_mm_hole_node_end(entry);
		hole_size = hole_end - hole_start;
		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: free\n",
			prefix, hole_start, hole_end,
			hole_size);
		pr_debug("%s %#llx-%#llx: %llu: free\n", prefix, hole_start,
			 hole_end, hole_size);
		return hole_size;
	}

@@ -792,35 +799,34 @@ static unsigned long drm_mm_debug_hole(struct drm_mm_node *entry,
void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
{
	struct drm_mm_node *entry;
	unsigned long total_used = 0, total_free = 0, total = 0;
	u64 total_used = 0, total_free = 0, total = 0;

	total_free += drm_mm_debug_hole(&mm->head_node, prefix);

	drm_mm_for_each_node(entry, mm) {
		printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8lu: used\n",
			prefix, entry->start, entry->start + entry->size,
			entry->size);
		pr_debug("%s %#llx-%#llx: %llu: used\n", prefix, entry->start,
			 entry->start + entry->size, entry->size);
		total_used += entry->size;
		total_free += drm_mm_debug_hole(entry, prefix);
	}
	total = total_free + total_used;

	printk(KERN_DEBUG "%s total: %lu, used %lu free %lu\n", prefix, total,
	pr_debug("%s total: %llu, used %llu free %llu\n", prefix, total,
		 total_used, total_free);
}
EXPORT_SYMBOL(drm_mm_debug_table);

#if defined(CONFIG_DEBUG_FS)
static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry)
static u64 drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry)
{
	unsigned long hole_start, hole_end, hole_size;
	u64 hole_start, hole_end, hole_size;

	if (entry->hole_follows) {
		hole_start = drm_mm_hole_node_start(entry);
		hole_end = drm_mm_hole_node_end(entry);
		hole_size = hole_end - hole_start;
		seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",
				hole_start, hole_end, hole_size);
		seq_printf(m, "%#llx-%#llx: %llu: free\n", hole_start,
			   hole_end, hole_size);
		return hole_size;
	}

@@ -835,20 +841,20 @@ static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *en
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
{
	struct drm_mm_node *entry;
	unsigned long total_used = 0, total_free = 0, total = 0;
	u64 total_used = 0, total_free = 0, total = 0;

	total_free += drm_mm_dump_hole(m, &mm->head_node);

	drm_mm_for_each_node(entry, mm) {
		seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n",
				entry->start, entry->start + entry->size,
				entry->size);
		seq_printf(m, "%#016llx-%#016llx: %llu: used\n", entry->start,
			   entry->start + entry->size, entry->size);
		total_used += entry->size;
		total_free += drm_mm_dump_hole(m, entry);
	}
	total = total_free + total_used;

	seq_printf(m, "total: %lu, used %lu free %lu\n", total, total_used, total_free);
	seq_printf(m, "total: %llu, used %llu free %llu\n", total,
		   total_used, total_free);
	return 0;
}
EXPORT_SYMBOL(drm_mm_dump_table);
+2 −2
Original line number Diff line number Diff line
@@ -152,12 +152,12 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
			seq_puts(m, " (pp");
		else
			seq_puts(m, " (g");
		seq_printf(m, "gtt offset: %08lx, size: %08lx, type: %u)",
		seq_printf(m, "gtt offset: %08llx, size: %08llx, type: %u)",
			   vma->node.start, vma->node.size,
			   vma->ggtt_view.type);
	}
	if (obj->stolen)
		seq_printf(m, " (stolen: %08lx)", obj->stolen->start);
		seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
	if (obj->pin_mappable || obj->fault_mappable) {
		char s[3], *t = s;
		if (obj->pin_mappable)
+25 −5
Original line number Diff line number Diff line
@@ -622,7 +622,7 @@ static int i915_drm_suspend(struct drm_device *dev)
	return 0;
}

static int i915_drm_suspend_late(struct drm_device *drm_dev)
static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
{
	struct drm_i915_private *dev_priv = drm_dev->dev_private;
	int ret;
@@ -636,6 +636,16 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev)
	}

	pci_disable_device(drm_dev->pdev);
	/*
	 * During hibernation on some GEN4 platforms the BIOS may try to access
	 * the device even though it's already in D3 and hang the machine. So
	 * leave the device in D0 on those platforms and hope the BIOS will
	 * power down the device properly. Platforms where this was seen:
	 * Lenovo Thinkpad X301, X61s
	 */
	if (!(hibernation &&
	      drm_dev->pdev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
	      INTEL_INFO(dev_priv)->gen == 4))
		pci_set_power_state(drm_dev->pdev, PCI_D3hot);

	return 0;
@@ -662,7 +672,7 @@ int i915_suspend_legacy(struct drm_device *dev, pm_message_t state)
	if (error)
		return error;

	return i915_drm_suspend_late(dev);
	return i915_drm_suspend_late(dev, false);
}

static int i915_drm_resume(struct drm_device *dev)
@@ -950,7 +960,17 @@ static int i915_pm_suspend_late(struct device *dev)
	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	return i915_drm_suspend_late(drm_dev);
	return i915_drm_suspend_late(drm_dev, false);
}

static int i915_pm_poweroff_late(struct device *dev)
{
	struct drm_device *drm_dev = dev_to_i915(dev)->dev;

	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	return i915_drm_suspend_late(drm_dev, true);
}

static int i915_pm_resume_early(struct device *dev)
@@ -1520,7 +1540,7 @@ static const struct dev_pm_ops i915_pm_ops = {
	.thaw_early = i915_pm_resume_early,
	.thaw = i915_pm_resume,
	.poweroff = i915_pm_suspend,
	.poweroff_late = i915_pm_suspend_late,
	.poweroff_late = i915_pm_poweroff_late,
	.restore_early = i915_pm_resume_early,
	.restore = i915_pm_resume,

+3 −3
Original line number Diff line number Diff line
@@ -1145,7 +1145,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)

	ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);

	DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n",
	DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
			 ppgtt->node.size >> 20,
			 ppgtt->node.start / PAGE_SIZE);

@@ -1713,8 +1713,8 @@ void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj)

static void i915_gtt_color_adjust(struct drm_mm_node *node,
				  unsigned long color,
				  unsigned long *start,
				  unsigned long *end)
				  u64 *start,
				  u64 *end)
{
	if (node->color != color)
		*start += 4096;
+7 −11
Original line number Diff line number Diff line
@@ -282,16 +282,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
	return ret;
}

static bool
__cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv,
				      enum pipe pipe)
{
	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

	return !intel_crtc->cpu_fifo_underrun_disabled;
}

/**
 * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state
 * @dev_priv: i915 device instance
@@ -352,9 +342,15 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
					 enum pipe pipe)
{
	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];

	/* We may be called too early in init, thanks BIOS! */
	if (crtc == NULL)
		return;

	/* GMCH can't disable fifo underruns, filter them. */
	if (HAS_GMCH_DISPLAY(dev_priv->dev) &&
	    !__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe))
	    to_intel_crtc(crtc)->cpu_fifo_underrun_disabled)
		return;

	if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))
Loading