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

Commit 58e10eb9 authored by Chris Wilson's avatar Chris Wilson
Browse files

Merge branch 'drm-intel-fixes' into drm-intel-next

Conflicts:
	drivers/gpu/drm/i915/i915_gem_evict.c
	drivers/gpu/drm/i915/intel_display.c
	drivers/gpu/drm/i915/intel_dp.c
parents 1cdf7fef ab7ad7f6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3379,6 +3379,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
				  (int) reloc->offset,
				  reloc->read_domains,
				  reloc->write_domain);
			drm_gem_object_unreference(target_obj);
			i915_gem_object_unpin(obj);
			return -EINVAL;
		}
		if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+20 −22
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct list_head eviction_list, unwind_list;
	struct drm_i915_gem_object *obj_priv, *tmp_obj_priv;
	struct drm_i915_gem_object *obj_priv;
	struct list_head *render_iter, *bsd_iter;
	int ret = 0;

@@ -175,36 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen
	return -ENOSPC;

found:
	INIT_LIST_HEAD(&eviction_list);
	list_for_each_entry_safe(obj_priv, tmp_obj_priv,
				 &unwind_list, evict_list) {
		if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
	/* drm_mm doesn't allow any other other operations while
	 * scanning, therefore store to be evicted objects on a
	 * temporary list. */
	INIT_LIST_HEAD(&eviction_list);
	while (!list_empty(&unwind_list)) {
		obj_priv = list_first_entry(&unwind_list,
					    struct drm_i915_gem_object,
					    evict_list);
		if (drm_mm_scan_remove_block(obj_priv->gtt_space)) {
			list_move(&obj_priv->evict_list, &eviction_list);
		} else
			continue;
		}
		list_del(&obj_priv->evict_list);
		drm_gem_object_unreference(&obj_priv->base);
	}

	/* Unbinding will emit any required flushes */
	list_for_each_entry_safe(obj_priv, tmp_obj_priv,
				 &eviction_list, evict_list) {
	while (!list_empty(&eviction_list)) {
		obj_priv = list_first_entry(&eviction_list,
					    struct drm_i915_gem_object,
					    evict_list);
		if (ret == 0)
			ret = i915_gem_object_unbind(&obj_priv->base);
		if (ret)
			return ret;

		list_del(&obj_priv->evict_list);
		drm_gem_object_unreference(&obj_priv->base);
	}

	/* The just created free hole should be on the top of the free stack
	 * maintained by drm_mm, so this BUG_ON actually executes in O(1).
	 * Furthermore all accessed data has just recently been used, so it
	 * should be really fast, too. */
	BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size,
				   alignment, 0));

	return 0;
	return ret;
}

int
+3 −2
Original line number Diff line number Diff line
@@ -2169,6 +2169,7 @@
#define   PIPE_12BPC				(3 << 5)

#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF)
#define PIPEDSL(pipe)  _PIPE(pipe, PIPEADSL, PIPEBDSL)

#define DSPARB			0x70030
#define   DSPARB_CSTART_MASK	(0x7f << 7)
+35 −22
Original line number Diff line number Diff line
@@ -1017,8 +1017,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
		DRM_DEBUG_KMS("vblank wait timed out\n");
}

/**
 * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
/*
 * intel_wait_for_pipe_off - wait for pipe to turn off
 * @dev: drm device
 * @pipe: pipe to wait for
 *
@@ -1026,26 +1026,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe)
 * spinning on the vblank interrupt status bit, since we won't actually
 * see an interrupt when the pipe is disabled.
 *
 * So this function waits for the display line value to settle (it
 * usually ends up stopping at the start of the next frame).
 * On Gen4 and above:
 *   wait for the pipe register state bit to turn off
 *
 * Otherwise:
 *   wait for the display line value to settle (it usually
 *   ends up stopping at the start of the next frame).
 *
 */
void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);

	if (INTEL_INFO(dev)->gen >= 4) {
		int reg = PIPECONF(pipe);

		/* Wait for the Pipe State to go off */
		if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
			     100))
			DRM_DEBUG_KMS("pipe_off wait timed out\n");
	} else {
		u32 last_line;
		int reg = PIPEDSL(pipe);
		unsigned long timeout = jiffies + msecs_to_jiffies(100);
	u32 last_line, line;

		/* Wait for the display line to settle */
	line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
		do {
		last_line = line;
		MSLEEP(5);
		line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
	} while (line != last_line && time_after(timeout, jiffies));

	if (line != last_line)
		DRM_DEBUG_KMS("vblank wait timed out\n");
			last_line = I915_READ(reg) & DSL_LINEMASK;
			mdelay(5);
		} while (((I915_READ(reg) & DSL_LINEMASK) != last_line) &&
			 time_after(timeout, jiffies));
		if (time_after(jiffies, timeout))
			DRM_DEBUG_KMS("pipe_off wait timed out\n");
	}
}

static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -2406,7 +2419,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)

		/* Wait for vblank for the disable to take effect */
		if (IS_GEN2(dev))
			intel_wait_for_vblank_off(dev, pipe);
			intel_wait_for_vblank(dev, pipe);
	}

	/* Don't disable pipe A or pipe A PLLs if needed */
@@ -2419,9 +2432,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
	if (temp & PIPECONF_ENABLE) {
		I915_WRITE(reg, temp & ~PIPECONF_ENABLE);

		/* Wait for vblank for the disable to take effect. */
		/* Wait for the pipe to turn off */
		POSTING_READ(reg);
		intel_wait_for_vblank_off(dev, pipe);
		intel_wait_for_pipe_off(dev, pipe);
	}

	reg = DPLL(pipe);
+12 −11
Original line number Diff line number Diff line
@@ -1186,25 +1186,22 @@ intel_channel_eq_ok(struct intel_dp *intel_dp)
static bool
intel_dp_set_link_train(struct intel_dp *intel_dp,
			uint32_t dp_reg_value,
			uint8_t dp_train_pat,
			bool first)
			uint8_t dp_train_pat)
{
	struct drm_device *dev = intel_dp->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
	int ret;

	I915_WRITE(intel_dp->output_reg, dp_reg_value);
	POSTING_READ(intel_dp->output_reg);
	if (first)
		intel_wait_for_vblank(dev, intel_crtc->pipe);

	intel_dp_aux_native_write_1(intel_dp,
				    DP_TRAINING_PATTERN_SET,
				    dp_train_pat);

	ret = intel_dp_aux_native_write(intel_dp,
					DP_TRAINING_LANE0_SET, intel_dp->train_set, 4);
					DP_TRAINING_LANE0_SET,
					intel_dp->train_set, 4);
	if (ret != 4)
		return false;

@@ -1216,14 +1213,20 @@ static void
intel_dp_start_link_train(struct intel_dp *intel_dp)
{
	struct drm_device *dev = intel_dp->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
	int i;
	uint8_t voltage;
	bool clock_recovery = false;
	bool first = true;
	int tries;
	u32 reg;
	uint32_t DP = intel_dp->DP;

	/* Enable output, wait for it to become active */
	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
	POSTING_READ(intel_dp->output_reg);
	intel_wait_for_vblank(dev, intel_crtc->pipe);

	/* Write the link configuration data */
	intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
				  intel_dp->link_configuration,
@@ -1255,9 +1258,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
			reg = DP | DP_LINK_TRAIN_PAT_1;

		if (!intel_dp_set_link_train(intel_dp, reg,
					     DP_TRAINING_PATTERN_1, first))
					     DP_TRAINING_PATTERN_1))
			break;
		first = false;
		/* Set training pattern 1 */

		udelay(100);
@@ -1324,8 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)

		/* channel eq pattern */
		if (!intel_dp_set_link_train(intel_dp, reg,
					     DP_TRAINING_PATTERN_2,
					     false))
					     DP_TRAINING_PATTERN_2))
			break;

		udelay(400);
Loading