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

Commit 4a490b78 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull DRM update from Dave Airlie:
 "This is a bit larger due to me not bothering to do anything since
  before Xmas, and other people working too hard after I had clearly
  given up.

  It's got the 3 main x86 driver fixes pulls, and a bunch of tegra
  fixes, doesn't fix the Ironlake bug yet, but that does seem to be
  getting closer.

   - radeon: gpu reset fixes and userspace packet support
   - i915: watermark fixes, workarounds, i830/845 fix,
   - nouveau: nvd9/kepler microcode fixes, accel is now enabled and
     working, gk106 support
   - tegra: misc fixes."

* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (34 commits)
  Revert "drm: tegra: protect DC register access with mutex"
  drm: tegra: program only one window during modeset
  drm: tegra: clean out old gem prototypes
  drm: tegra: remove redundant tegra2_tmds_config entry
  drm: tegra: protect DC register access with mutex
  drm: tegra: don't leave clients host1x member uninitialized
  drm: tegra: fix front_porch <-> back_porch mixup
  drm/nve0/graph: fix fuc, and enable acceleration on all known chipsets
  drm/nvc0/graph: fix fuc, and enable acceleration on GF119
  drm/nouveau/bios: cache ramcfg strap on later chipsets
  drm/nouveau/mxm: silence output if no bios data
  drm/nouveau/bios: parse/display extra version component
  drm/nouveau/bios: implement opcode 0xa9
  drm/nouveau/bios: update gpio parsing apis to match current design
  drm/nouveau: initial support for GK106
  drm/radeon: add WAIT_UNTIL to evergreen VM safe reg list
  drm/i915: disable shrinker lock stealing for create_mmap_offset
  drm/i915: optionally disable shrinker lock stealing
  drm/i915: fix flags in dma buf exporting
  drm/radeon: add support for MEM_WRITE packet
  ...
parents 8d91a42e d5757dbe
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -184,19 +184,27 @@ EXPORT_SYMBOL(drm_mm_get_block_generic);
 * -ENOSPC if no suitable free area is available. The preallocated memory node
 * must be cleared.
 */
int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
		       unsigned long size, unsigned alignment)
int drm_mm_insert_node_generic(struct drm_mm *mm, struct drm_mm_node *node,
			       unsigned long size, unsigned alignment,
			       unsigned long color)
{
	struct drm_mm_node *hole_node;

	hole_node = drm_mm_search_free(mm, size, alignment, false);
	hole_node = drm_mm_search_free_generic(mm, size, alignment,
					       color, 0);
	if (!hole_node)
		return -ENOSPC;

	drm_mm_insert_helper(hole_node, node, size, alignment, 0);

	drm_mm_insert_helper(hole_node, node, size, alignment, color);
	return 0;
}
EXPORT_SYMBOL(drm_mm_insert_node_generic);

int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
		       unsigned long size, unsigned alignment)
{
	return drm_mm_insert_node_generic(mm, node, size, alignment, 0);
}
EXPORT_SYMBOL(drm_mm_insert_node);

static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
@@ -275,22 +283,31 @@ EXPORT_SYMBOL(drm_mm_get_block_range_generic);
 * -ENOSPC if no suitable free area is available. This is for range
 * restricted allocations. The preallocated memory node must be cleared.
 */
int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
				unsigned long size, unsigned alignment,
int drm_mm_insert_node_in_range_generic(struct drm_mm *mm, struct drm_mm_node *node,
					unsigned long size, unsigned alignment, unsigned long color,
					unsigned long start, unsigned long end)
{
	struct drm_mm_node *hole_node;

	hole_node = drm_mm_search_free_in_range(mm, size, alignment,
						start, end, false);
	hole_node = drm_mm_search_free_in_range_generic(mm,
							size, alignment, color,
							start, end, 0);
	if (!hole_node)
		return -ENOSPC;

	drm_mm_insert_helper_range(hole_node, node, size, alignment, 0,
	drm_mm_insert_helper_range(hole_node, node,
				   size, alignment, color,
				   start, end);

	return 0;
}
EXPORT_SYMBOL(drm_mm_insert_node_in_range_generic);

int drm_mm_insert_node_in_range(struct drm_mm *mm, struct drm_mm_node *node,
				unsigned long size, unsigned alignment,
				unsigned long start, unsigned long end)
{
	return drm_mm_insert_node_in_range_generic(mm, node, size, alignment, 0, start, end);
}
EXPORT_SYMBOL(drm_mm_insert_node_in_range);

/**
+3 −0
Original line number Diff line number Diff line
@@ -989,6 +989,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
	case I915_PARAM_HAS_SECURE_BATCHES:
		value = capable(CAP_SYS_ADMIN);
		break;
	case I915_PARAM_HAS_PINNED_BATCHES:
		value = 1;
		break;
	default:
		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
				 param->param);
+8 −0
Original line number Diff line number Diff line
@@ -780,6 +780,7 @@ typedef struct drm_i915_private {
		struct i915_hw_ppgtt *aliasing_ppgtt;

		struct shrinker inactive_shrinker;
		bool shrinker_no_lock_stealing;

		/**
		 * List of objects currently involved in rendering.
@@ -1100,6 +1101,7 @@ struct drm_i915_gem_object {
	 */
	atomic_t pending_flip;
};
#define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)

#define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)

@@ -1166,6 +1168,9 @@ struct drm_i915_file_private {
#define IS_IVB_GT1(dev)		((dev)->pci_device == 0x0156 || \
				 (dev)->pci_device == 0x0152 ||	\
				 (dev)->pci_device == 0x015a)
#define IS_SNB_GT1(dev)		((dev)->pci_device == 0x0102 || \
				 (dev)->pci_device == 0x0106 ||	\
				 (dev)->pci_device == 0x010A)
#define IS_VALLEYVIEW(dev)	(INTEL_INFO(dev)->is_valleyview)
#define IS_HASWELL(dev)	(INTEL_INFO(dev)->is_haswell)
#define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
@@ -1196,6 +1201,9 @@ struct drm_i915_file_private {
#define HAS_OVERLAY(dev)		(INTEL_INFO(dev)->has_overlay)
#define OVERLAY_NEEDS_PHYSICAL(dev)	(INTEL_INFO(dev)->overlay_needs_physical)

/* Early gen2 have a totally busted CS tlb and require pinned batches. */
#define HAS_BROKEN_CS_TLB(dev)		(IS_I830(dev) || IS_845G(dev))

/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
 * rows, which changed the alignment requirements and fence programming.
 */
+37 −40
Original line number Diff line number Diff line
@@ -1517,9 +1517,11 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
	if (obj->base.map_list.map)
		return 0;

	dev_priv->mm.shrinker_no_lock_stealing = true;

	ret = drm_gem_create_mmap_offset(&obj->base);
	if (ret != -ENOSPC)
		return ret;
		goto out;

	/* Badly fragmented mmap space? The only way we can recover
	 * space is by destroying unwanted objects. We can't randomly release
@@ -1531,10 +1533,14 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
	i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT);
	ret = drm_gem_create_mmap_offset(&obj->base);
	if (ret != -ENOSPC)
		return ret;
		goto out;

	i915_gem_shrink_all(dev_priv);
	return drm_gem_create_mmap_offset(&obj->base);
	ret = drm_gem_create_mmap_offset(&obj->base);
out:
	dev_priv->mm.shrinker_no_lock_stealing = false;

	return ret;
}

static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
@@ -2890,7 +2896,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
{
	struct drm_device *dev = obj->base.dev;
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct drm_mm_node *free_space;
	struct drm_mm_node *node;
	u32 size, fence_size, fence_alignment, unfenced_alignment;
	bool mappable, fenceable;
	int ret;
@@ -2936,66 +2942,54 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,

	i915_gem_object_pin_pages(obj);

 search_free:
	if (map_and_fenceable)
		free_space = drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space,
							       size, alignment, obj->cache_level,
							       0, dev_priv->mm.gtt_mappable_end,
							       false);
	else
		free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space,
						      size, alignment, obj->cache_level,
						      false);
	node = kzalloc(sizeof(*node), GFP_KERNEL);
	if (node == NULL) {
		i915_gem_object_unpin_pages(obj);
		return -ENOMEM;
	}

	if (free_space != NULL) {
 search_free:
	if (map_and_fenceable)
			free_space =
				drm_mm_get_block_range_generic(free_space,
		ret = drm_mm_insert_node_in_range_generic(&dev_priv->mm.gtt_space, node,
							  size, alignment, obj->cache_level,
							       0, dev_priv->mm.gtt_mappable_end,
							       false);
							  0, dev_priv->mm.gtt_mappable_end);
	else
			free_space =
				drm_mm_get_block_generic(free_space,
							 size, alignment, obj->cache_level,
							 false);
	}
	if (free_space == NULL) {
		ret = drm_mm_insert_node_generic(&dev_priv->mm.gtt_space, node,
						 size, alignment, obj->cache_level);
	if (ret) {
		ret = i915_gem_evict_something(dev, size, alignment,
					       obj->cache_level,
					       map_and_fenceable,
					       nonblocking);
		if (ret) {
		if (ret == 0)
			goto search_free;

		i915_gem_object_unpin_pages(obj);
		kfree(node);
		return ret;
	}

		goto search_free;
	}
	if (WARN_ON(!i915_gem_valid_gtt_space(dev,
					      free_space,
					      obj->cache_level))) {
	if (WARN_ON(!i915_gem_valid_gtt_space(dev, node, obj->cache_level))) {
		i915_gem_object_unpin_pages(obj);
		drm_mm_put_block(free_space);
		drm_mm_put_block(node);
		return -EINVAL;
	}

	ret = i915_gem_gtt_prepare_object(obj);
	if (ret) {
		i915_gem_object_unpin_pages(obj);
		drm_mm_put_block(free_space);
		drm_mm_put_block(node);
		return ret;
	}

	list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
	list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);

	obj->gtt_space = free_space;
	obj->gtt_offset = free_space->start;
	obj->gtt_space = node;
	obj->gtt_offset = node->start;

	fenceable =
		free_space->size == fence_size &&
		(free_space->start & (fence_alignment - 1)) == 0;
		node->size == fence_size &&
		(node->start & (fence_alignment - 1)) == 0;

	mappable =
		obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
@@ -4392,6 +4386,9 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
		if (!mutex_is_locked_by(&dev->struct_mutex, current))
			return 0;

		if (dev_priv->mm.shrinker_no_lock_stealing)
			return 0;

		unlock = false;
	}

+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
{
	struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);

	return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, 0600);
	return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, flags);
}

static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
Loading