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

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

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: tune down the noise of the RP irq limit fail
  drm/i915: Remove the error message for unbinding pinned buffers
  drm/i915: Limit page allocations to lowmem (dma32) for i965
  drm/i915: always use RPNSWREQ for turbo change requests
  drm/i915: reject doubleclocked cea modes on dp
  drm/i915: Adding TV Out Missing modes.
  drm/i915: wait for a vblank to pass after tv detect
  drm/i915: no lvds quirk for HP t5740e Thin Client
  drm/i915: enable vdd when switching off the eDP panel
  drm/i915: Fix PCH PLL assertions to not assume CRTC:PLL relationship
  drm/i915: Always update RPS interrupts thresholds along with frequency
  drm/i915: properly handle interlaced bit for sdvo dtd conversion
  drm/i915: fix module unload since error_state rework
  drm/i915: be more careful when returning -ENXIO in gmbus transfer
parents 1ebf169a ef12dab7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2032,6 +2032,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops,
				 1, minor);
	drm_debugfs_remove_files((struct drm_info_list *) &i915_error_state_fops,
				 1, minor);
}

#endif /* CONFIG_DEBUG_FS */
+11 −5
Original line number Diff line number Diff line
@@ -2063,10 +2063,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
	if (obj->gtt_space == NULL)
		return 0;

	if (obj->pin_count != 0) {
		DRM_ERROR("Attempting to unbind pinned buffer\n");
		return -EINVAL;
	}
	if (obj->pin_count)
		return -EBUSY;

	ret = i915_gem_object_finish_gpu(obj);
	if (ret)
@@ -3293,6 +3291,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_gem_object *obj;
	struct address_space *mapping;
	u32 mask;

	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
	if (obj == NULL)
@@ -3303,8 +3302,15 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
		return NULL;
	}

	mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
	if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) {
		/* 965gm cannot relocate objects above 4GiB. */
		mask &= ~__GFP_HIGHMEM;
		mask |= __GFP_DMA32;
	}

	mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
	mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
	mapping_set_gfp_mask(mapping, mask);

	i915_gem_info_add_obj(dev_priv, size);

+7 −30
Original line number Diff line number Diff line
@@ -350,8 +350,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
{
	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
						    rps_work);
	u8 new_delay = dev_priv->cur_delay;
	u32 pm_iir, pm_imr;
	u8 new_delay;

	spin_lock_irq(&dev_priv->rps_lock);
	pm_iir = dev_priv->pm_iir;
@@ -360,41 +360,18 @@ static void gen6_pm_rps_work(struct work_struct *work)
	I915_WRITE(GEN6_PMIMR, 0);
	spin_unlock_irq(&dev_priv->rps_lock);

	if (!pm_iir)
	if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0)
		return;

	mutex_lock(&dev_priv->dev->struct_mutex);
	if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
		if (dev_priv->cur_delay != dev_priv->max_delay)

	if (pm_iir & GEN6_PM_RP_UP_THRESHOLD)
		new_delay = dev_priv->cur_delay + 1;
		if (new_delay > dev_priv->max_delay)
			new_delay = dev_priv->max_delay;
	} else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) {
		gen6_gt_force_wake_get(dev_priv);
		if (dev_priv->cur_delay != dev_priv->min_delay)
	else
		new_delay = dev_priv->cur_delay - 1;
		if (new_delay < dev_priv->min_delay) {
			new_delay = dev_priv->min_delay;
			I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
				   I915_READ(GEN6_RP_INTERRUPT_LIMITS) |
				   ((new_delay << 16) & 0x3f0000));
		} else {
			/* Make sure we continue to get down interrupts
			 * until we hit the minimum frequency */
			I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
				   I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000);
		}
		gen6_gt_force_wake_put(dev_priv);
	}

	gen6_set_rps(dev_priv->dev, new_delay);
	dev_priv->cur_delay = new_delay;

	/*
	 * rps_lock not held here because clearing is non-destructive. There is
	 * an *extremely* unlikely race with gen6_rps_enable() that is prevented
	 * by holding struct_mutex for the duration of the write.
	 */
	mutex_unlock(&dev_priv->dev->struct_mutex);
}

+33 −23
Original line number Diff line number Diff line
@@ -910,9 +910,10 @@ static void assert_pll(struct drm_i915_private *dev_priv,

/* For ILK+ */
static void assert_pch_pll(struct drm_i915_private *dev_priv,
			   struct intel_crtc *intel_crtc, bool state)
			   struct intel_pch_pll *pll,
			   struct intel_crtc *crtc,
			   bool state)
{
	int reg;
	u32 val;
	bool cur_state;

@@ -921,30 +922,37 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv,
		return;
	}

	if (!intel_crtc->pch_pll) {
		WARN(1, "asserting PCH PLL enabled with no PLL\n");
	if (WARN (!pll,
		  "asserting PCH PLL %s with no PLL\n", state_string(state)))
		return;
	}

	if (HAS_PCH_CPT(dev_priv->dev)) {
	val = I915_READ(pll->pll_reg);
	cur_state = !!(val & DPLL_VCO_ENABLE);
	WARN(cur_state != state,
	     "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
	     pll->pll_reg, state_string(state), state_string(cur_state), val);

	/* Make sure the selected PLL is correctly attached to the transcoder */
	if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
		u32 pch_dpll;

		pch_dpll = I915_READ(PCH_DPLL_SEL);

		/* Make sure the selected PLL is enabled to the transcoder */
		WARN(!((pch_dpll >> (4 * intel_crtc->pipe)) & 8),
		     "transcoder %d PLL not enabled\n", intel_crtc->pipe);
	}

	reg = intel_crtc->pch_pll->pll_reg;
	val = I915_READ(reg);
	cur_state = !!(val & DPLL_VCO_ENABLE);
		cur_state = pll->pll_reg == _PCH_DPLL_B;
		if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
			  "PLL[%d] not attached to this transcoder %d: %08x\n",
			  cur_state, crtc->pipe, pch_dpll)) {
			cur_state = !!(val >> (4*crtc->pipe + 3));
			WARN(cur_state != state,
	     "PCH PLL state assertion failure (expected %s, current %s)\n",
	     state_string(state), state_string(cur_state));
			     "PLL[%d] not %s on this transcoder %d: %08x\n",
			     pll->pll_reg == _PCH_DPLL_B,
			     state_string(state),
			     crtc->pipe,
			     val);
		}
	}
}
#define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true)
#define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false)
#define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
#define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false)

static void assert_fdi_tx(struct drm_i915_private *dev_priv,
			  enum pipe pipe, bool state)
@@ -1424,7 +1432,7 @@ static void intel_enable_pch_pll(struct intel_crtc *intel_crtc)
	assert_pch_refclk_enabled(dev_priv);

	if (pll->active++ && pll->on) {
		assert_pch_pll_enabled(dev_priv, intel_crtc);
		assert_pch_pll_enabled(dev_priv, pll, NULL);
		return;
	}

@@ -1460,12 +1468,12 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
		      intel_crtc->base.base.id);

	if (WARN_ON(pll->active == 0)) {
		assert_pch_pll_disabled(dev_priv, intel_crtc);
		assert_pch_pll_disabled(dev_priv, pll, NULL);
		return;
	}

	if (--pll->active) {
		assert_pch_pll_enabled(dev_priv, intel_crtc);
		assert_pch_pll_enabled(dev_priv, pll, NULL);
		return;
	}

@@ -1495,7 +1503,9 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
	BUG_ON(dev_priv->info->gen < 5);

	/* Make sure PCH DPLL is enabled */
	assert_pch_pll_enabled(dev_priv, to_intel_crtc(crtc));
	assert_pch_pll_enabled(dev_priv,
			       to_intel_crtc(crtc)->pch_pll,
			       to_intel_crtc(crtc));

	/* FDI must be feeding us bits for PCH ports */
	assert_fdi_tx_enabled(dev_priv, pipe);
+14 −10
Original line number Diff line number Diff line
@@ -266,6 +266,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
	if (mode->clock < 10000)
		return MODE_CLOCK_LOW;

	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		return MODE_H_ILLEGAL;

	return MODE_OK;
}

@@ -702,6 +705,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
		mode->clock = intel_dp->panel_fixed_mode->clock;
	}

	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		return false;

	DRM_DEBUG_KMS("DP link computation with max lane count %i "
		      "max bw %02x pixel clock %iKHz\n",
		      max_lane_count, bws[max_clock], mode->clock);
@@ -1154,11 +1160,10 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)

	DRM_DEBUG_KMS("Turn eDP power off\n");

	WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
	ironlake_panel_vdd_off_sync(intel_dp); /* finish any pending work */
	WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");

	pp = ironlake_get_pp_control(dev_priv);
	pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
	pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
	I915_WRITE(PCH_PP_CONTROL, pp);
	POSTING_READ(PCH_PP_CONTROL);

@@ -1266,18 +1271,16 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
{
	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);


	/* Make sure the panel is off before trying to change the mode. But also
	 * ensure that we have vdd while we switch off the panel. */
	ironlake_edp_panel_vdd_on(intel_dp);
	ironlake_edp_backlight_off(intel_dp);
	ironlake_edp_panel_off(intel_dp);

	/* Wake up the sink first */
	ironlake_edp_panel_vdd_on(intel_dp);
	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
	intel_dp_link_down(intel_dp);
	ironlake_edp_panel_vdd_off(intel_dp, false);

	/* Make sure the panel is off before trying to
	 * change the mode
	 */
}

static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1309,10 +1312,11 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
	uint32_t dp_reg = I915_READ(intel_dp->output_reg);

	if (mode != DRM_MODE_DPMS_ON) {
		/* Switching the panel off requires vdd. */
		ironlake_edp_panel_vdd_on(intel_dp);
		ironlake_edp_backlight_off(intel_dp);
		ironlake_edp_panel_off(intel_dp);

		ironlake_edp_panel_vdd_on(intel_dp);
		intel_dp_sink_dpms(intel_dp, mode);
		intel_dp_link_down(intel_dp);
		ironlake_edp_panel_vdd_off(intel_dp, false);
Loading