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

Commit 974e59ba authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2015-10-22' of...

Merge tag 'drm-intel-next-fixes-2015-10-22' of git://anongit.freedesktop.org/drm-intel into drm-next

Bunch of -fixes for 4.4. Well not just, I've left the mmio/register work
from Ville in here since it's low-risk but lots of churn all over.

* tag 'drm-intel-next-fixes-2015-10-22' of git://anongit.freedesktop.org/drm-intel: (23 commits)
  drm/i915: Use round to closest when computing the CEA 1.001 pixel clocks
  drm/i915: Kill the leftover RMW from ivb_sprite_disable()
  drm/i915: restore ggtt double-bind avoidance
  drm/i915/skl: Enable pipe gamma for sprite planes.
  drm/i915/skl+: Enable pipe CSC on cursor planes. (v2)
  MAINTAINERS: add link to the Intel Graphics for Linux web site
  drm/i915: Move skl/bxt gt specific workarounds to ring init
  drm/i915: Drop i915_gem_obj_is_pinned() from set-cache-level
  drm/i915: revert a few more watermark commits
  drm/i915: Remove dev_priv argument from NEEDS_FORCE_WAKE
  drm/i915: Clean up LVDS register handling
  drm/i915: Throw out some useless variables
  drm/i915: Parametrize and fix SWF registers
  drm/i915: s/PIPE_FRMCOUNT_GM45/PIPE_FRMCOUNT_G4X/ etc.
  drm/i915: Turn GEN5_ASSERT_IIR_IS_ZERO() into a function
  drm/i915: Fix a few bad hex numbers in register defines
  drm/i915: Protect register macro arguments
  drm/i915: Include gpio_mmio_base in GMBUS reg defines
  drm/i915: Parametrize HSW video DIP data registers
  drm/i915: Eliminate weird parameter inversion from BXT PPS registers
  ...
parents d7e1bc3f 606bb5e0
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -3584,6 +3584,7 @@ M: Daniel Vetter <daniel.vetter@intel.com>
M:	Jani Nikula <jani.nikula@linux.intel.com>
M:	Jani Nikula <jani.nikula@linux.intel.com>
L:	intel-gfx@lists.freedesktop.org
L:	intel-gfx@lists.freedesktop.org
L:	dri-devel@lists.freedesktop.org
L:	dri-devel@lists.freedesktop.org
W:	https://01.org/linuxgraphics/
Q:	http://patchwork.freedesktop.org/project/intel-gfx/
Q:	http://patchwork.freedesktop.org/project/intel-gfx/
T:	git git://anongit.freedesktop.org/drm-intel
T:	git git://anongit.freedesktop.org/drm-intel
S:	Supported
S:	Supported
+1 −1
Original line number Original line Diff line number Diff line
@@ -1850,7 +1850,7 @@ static int i915_opregion(struct seq_file *m, void *unused)
		goto out;
		goto out;


	if (opregion->header) {
	if (opregion->header) {
		memcpy_fromio(data, opregion->header, OPREGION_SIZE);
		memcpy(data, opregion->header, OPREGION_SIZE);
		seq_write(m, data, OPREGION_SIZE);
		seq_write(m, data, OPREGION_SIZE);
	}
	}


+11 −7
Original line number Original line Diff line number Diff line
@@ -450,14 +450,14 @@ struct opregion_swsci;
struct opregion_asle;
struct opregion_asle;


struct intel_opregion {
struct intel_opregion {
	struct opregion_header __iomem *header;
	struct opregion_header *header;
	struct opregion_acpi __iomem *acpi;
	struct opregion_acpi *acpi;
	struct opregion_swsci __iomem *swsci;
	struct opregion_swsci *swsci;
	u32 swsci_gbda_sub_functions;
	u32 swsci_gbda_sub_functions;
	u32 swsci_sbcb_sub_functions;
	u32 swsci_sbcb_sub_functions;
	struct opregion_asle __iomem *asle;
	struct opregion_asle *asle;
	void __iomem *vbt;
	void *vbt;
	u32 __iomem *lid_state;
	u32 *lid_state;
	struct work_struct asle_work;
	struct work_struct asle_work;
};
};
#define OPREGION_SIZE            (8*1024)
#define OPREGION_SIZE            (8*1024)
@@ -628,6 +628,10 @@ struct drm_i915_display_funcs {
			  struct dpll *match_clock,
			  struct dpll *match_clock,
			  struct dpll *best_clock);
			  struct dpll *best_clock);
	void (*update_wm)(struct drm_crtc *crtc);
	void (*update_wm)(struct drm_crtc *crtc);
	void (*update_sprite_wm)(struct drm_plane *plane,
				 struct drm_crtc *crtc,
				 uint32_t sprite_width, uint32_t sprite_height,
				 int pixel_size, bool enable, bool scaled);
	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
	int (*modeset_calc_cdclk)(struct drm_atomic_state *state);
	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
	void (*modeset_commit_cdclk)(struct drm_atomic_state *state);
	/* Returns the active state of the crtc, and if the crtc is active,
	/* Returns the active state of the crtc, and if the crtc is active,
@@ -1031,7 +1035,7 @@ struct i915_suspend_saved_registers {
	u32 saveMI_ARB_STATE;
	u32 saveMI_ARB_STATE;
	u32 saveSWF0[16];
	u32 saveSWF0[16];
	u32 saveSWF1[16];
	u32 saveSWF1[16];
	u32 saveSWF2[3];
	u32 saveSWF3[3];
	uint64_t saveFENCE[I915_MAX_NUM_FENCES];
	uint64_t saveFENCE[I915_MAX_NUM_FENCES];
	u32 savePCH_PORT_HOTPLUG;
	u32 savePCH_PORT_HOTPLUG;
	u16 saveGCDGMBUS;
	u16 saveGCDGMBUS;
+78 −21
Original line number Original line Diff line number Diff line
@@ -3657,50 +3657,103 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
	return 0;
	return 0;
}
}


/**
 * Changes the cache-level of an object across all VMA.
 *
 * After this function returns, the object will be in the new cache-level
 * across all GTT and the contents of the backing storage will be coherent,
 * with respect to the new cache-level. In order to keep the backing storage
 * coherent for all users, we only allow a single cache level to be set
 * globally on the object and prevent it from being changed whilst the
 * hardware is reading from the object. That is if the object is currently
 * on the scanout it will be set to uncached (or equivalent display
 * cache coherency) and all non-MOCS GPU access will also be uncached so
 * that all direct access to the scanout remains coherent.
 */
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
				    enum i915_cache_level cache_level)
				    enum i915_cache_level cache_level)
{
{
	struct drm_device *dev = obj->base.dev;
	struct drm_device *dev = obj->base.dev;
	struct i915_vma *vma, *next;
	struct i915_vma *vma, *next;
	bool bound = false;
	int ret = 0;
	int ret = 0;


	if (obj->cache_level == cache_level)
	if (obj->cache_level == cache_level)
		goto out;
		goto out;


	if (i915_gem_obj_is_pinned(obj)) {
	/* Inspect the list of currently bound VMA and unbind any that would
	 * be invalid given the new cache-level. This is principally to
	 * catch the issue of the CS prefetch crossing page boundaries and
	 * reading an invalid PTE on older architectures.
	 */
	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
		if (!drm_mm_node_allocated(&vma->node))
			continue;

		if (vma->pin_count) {
			DRM_DEBUG("can not change the cache level of pinned objects\n");
			DRM_DEBUG("can not change the cache level of pinned objects\n");
			return -EBUSY;
			return -EBUSY;
		}
		}


	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
		if (!i915_gem_valid_gtt_space(vma, cache_level)) {
		if (!i915_gem_valid_gtt_space(vma, cache_level)) {
			ret = i915_vma_unbind(vma);
			ret = i915_vma_unbind(vma);
			if (ret)
			if (ret)
				return ret;
				return ret;
		}
		} else
			bound = true;
	}
	}


	if (i915_gem_obj_bound_any(obj)) {
	/* We can reuse the existing drm_mm nodes but need to change the
	 * cache-level on the PTE. We could simply unbind them all and
	 * rebind with the correct cache-level on next use. However since
	 * we already have a valid slot, dma mapping, pages etc, we may as
	 * rewrite the PTE in the belief that doing so tramples upon less
	 * state and so involves less work.
	 */
	if (bound) {
		/* Before we change the PTE, the GPU must not be accessing it.
		 * If we wait upon the object, we know that all the bound
		 * VMA are no longer active.
		 */
		ret = i915_gem_object_wait_rendering(obj, false);
		ret = i915_gem_object_wait_rendering(obj, false);
		if (ret)
		if (ret)
			return ret;
			return ret;


		i915_gem_object_finish_gtt(obj);
		if (!HAS_LLC(dev) && cache_level != I915_CACHE_NONE) {
			/* Access to snoopable pages through the GTT is
			 * incoherent and on some machines causes a hard
			 * lockup. Relinquish the CPU mmaping to force
			 * userspace to refault in the pages and we can
			 * then double check if the GTT mapping is still
			 * valid for that pointer access.
			 */
			i915_gem_release_mmap(obj);


		/* Before SandyBridge, you could not use tiling or fence
			/* As we no longer need a fence for GTT access,
		 * registers with snooped memory, so relinquish any fences
			 * we can relinquish it now (and so prevent having
		 * currently pointing to our region in the aperture.
			 * to steal a fence from someone else on the next
			 * fence request). Note GPU activity would have
			 * dropped the fence as all snoopable access is
			 * supposed to be linear.
			 */
			 */
		if (INTEL_INFO(dev)->gen < 6) {
			ret = i915_gem_object_put_fence(obj);
			ret = i915_gem_object_put_fence(obj);
			if (ret)
			if (ret)
				return ret;
				return ret;
		} else {
			/* We either have incoherent backing store and
			 * so no GTT access or the architecture is fully
			 * coherent. In such cases, existing GTT mmaps
			 * ignore the cache bit in the PTE and we can
			 * rewrite it without confusing the GPU or having
			 * to force userspace to fault back in its mmaps.
			 */
		}
		}


		list_for_each_entry(vma, &obj->vma_list, vma_link)
		list_for_each_entry(vma, &obj->vma_list, vma_link) {
			if (drm_mm_node_allocated(&vma->node)) {
			if (!drm_mm_node_allocated(&vma->node))
				ret = i915_vma_bind(vma, cache_level,
				continue;
						    PIN_UPDATE);

			ret = i915_vma_bind(vma, cache_level, PIN_UPDATE);
			if (ret)
			if (ret)
				return ret;
				return ret;
		}
		}
@@ -3711,6 +3764,10 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
	obj->cache_level = cache_level;
	obj->cache_level = cache_level;


out:
out:
	/* Flush the dirty CPU caches to the backing storage so that the
	 * object is now coherent at its new cache level (with respect
	 * to the access domain).
	 */
	if (obj->cache_dirty &&
	if (obj->cache_dirty &&
	    obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
	    obj->base.write_domain != I915_GEM_DOMAIN_CPU &&
	    cpu_write_needs_clflush(obj)) {
	    cpu_write_needs_clflush(obj)) {
+34 −12
Original line number Original line Diff line number Diff line
@@ -2501,6 +2501,36 @@ static void i915_ggtt_clear_range(struct i915_address_space *vm,
static int ggtt_bind_vma(struct i915_vma *vma,
static int ggtt_bind_vma(struct i915_vma *vma,
			 enum i915_cache_level cache_level,
			 enum i915_cache_level cache_level,
			 u32 flags)
			 u32 flags)
{
	struct drm_i915_gem_object *obj = vma->obj;
	u32 pte_flags = 0;
	int ret;

	ret = i915_get_ggtt_vma_pages(vma);
	if (ret)
		return ret;

	/* Currently applicable only to VLV */
	if (obj->gt_ro)
		pte_flags |= PTE_READ_ONLY;

	vma->vm->insert_entries(vma->vm, vma->ggtt_view.pages,
				vma->node.start,
				cache_level, pte_flags);

	/*
	 * Without aliasing PPGTT there's no difference between
	 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
	 * upgrade to both bound if we bind either to avoid double-binding.
	 */
	vma->bound |= GLOBAL_BIND | LOCAL_BIND;

	return 0;
}

static int aliasing_gtt_bind_vma(struct i915_vma *vma,
				 enum i915_cache_level cache_level,
				 u32 flags)
{
{
	struct drm_device *dev = vma->vm->dev;
	struct drm_device *dev = vma->vm->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2519,23 +2549,13 @@ static int ggtt_bind_vma(struct i915_vma *vma,
		pte_flags |= PTE_READ_ONLY;
		pte_flags |= PTE_READ_ONLY;




	if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) {
	if (flags & GLOBAL_BIND) {
		vma->vm->insert_entries(vma->vm, pages,
		vma->vm->insert_entries(vma->vm, pages,
					vma->node.start,
					vma->node.start,
					cache_level, pte_flags);
					cache_level, pte_flags);

		/* Note the inconsistency here is due to absence of the
		 * aliasing ppgtt on gen4 and earlier. Though we always
		 * request PIN_USER for execbuffer (translated to LOCAL_BIND),
		 * without the appgtt, we cannot honour that request and so
		 * must substitute it with a global binding. Since we do this
		 * behind the upper layers back, we need to explicitly set
		 * the bound flag ourselves.
		 */
		vma->bound |= GLOBAL_BIND;
	}
	}


	if (dev_priv->mm.aliasing_ppgtt && flags & LOCAL_BIND) {
	if (flags & LOCAL_BIND) {
		struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
		struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt;
		appgtt->base.insert_entries(&appgtt->base, pages,
		appgtt->base.insert_entries(&appgtt->base, pages,
					    vma->node.start,
					    vma->node.start,
@@ -2699,6 +2719,8 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
					true);
					true);


		dev_priv->mm.aliasing_ppgtt = ppgtt;
		dev_priv->mm.aliasing_ppgtt = ppgtt;
		WARN_ON(dev_priv->gtt.base.bind_vma != ggtt_bind_vma);
		dev_priv->gtt.base.bind_vma = aliasing_gtt_bind_vma;
	}
	}


	return 0;
	return 0;
Loading