Commit 1a1c6976 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.c
	drivers/gpu/drm/i915/intel_dp.c
parents 0be73284 1b39d6f3
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -3356,9 +3356,24 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
		 * use this buffer rather sooner than later, so issuing the required
		 * flush earlier is beneficial.
		 */
		if (obj->base.write_domain & I915_GEM_GPU_DOMAINS)
		if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) {
			i915_gem_flush_ring(dev, obj->ring,
					    0, obj->base.write_domain);
		} else if (obj->ring->outstanding_lazy_request ==
			   obj->last_rendering_seqno) {
			struct drm_i915_gem_request *request;

			/* This ring is not being cleared by active usage,
			 * so emit a request to do so.
			 */
			request = kzalloc(sizeof(*request), GFP_KERNEL);
			if (request)
				ret = i915_add_request(dev,
						       NULL, request,
						       obj->ring);
			else
				ret = -ENOMEM;
		}

		/* Update the active list for the hardware's current position.
		 * Otherwise this only updates on a delayed timer or when irqs
+5 −2
Original line number Diff line number Diff line
@@ -1376,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
	struct drm_i915_private *dev_priv = dev->dev_private;
	uint32_t DP = intel_dp->DP;

	if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0)
		return;

	DRM_DEBUG_KMS("\n");

	if (is_edp(intel_dp)) {
@@ -1399,9 +1402,9 @@ intel_dp_link_down(struct intel_dp *intel_dp)
	if (is_edp(intel_dp))
		DP |= DP_LINK_TRAIN_OFF;

	if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) {
	if (!HAS_PCH_CPT(dev) &&
	    I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) {
		struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);

		/* Hardware workaround: leaving our transcoder select
		 * set to transcoder B while it's off will prevent the
		 * corresponding HDMI output on transcoder A.
+54 −44
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
/**
 * Sets the power state for the panel.
 */
static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
static void intel_lvds_enable(struct intel_lvds *intel_lvds)
{
	struct drm_device *dev = intel_lvds->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on)
		lvds_reg = LVDS;
	}

	if (on) {
	I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN);

	if (intel_lvds->pfit_dirty) {
		/*
		 * Enable automatic panel scaling so that non-native modes
		 * fill the screen.  The panel fitter should only be
		 * adjusted whilst the pipe is disabled, according to
		 * register description and PRM.
		 */
		DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
			      intel_lvds->pfit_control,
			      intel_lvds->pfit_pgm_ratios);
		if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) {
			DRM_ERROR("timed out waiting for panel to power off\n");
		} else {
			I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
			I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
			intel_lvds->pfit_dirty = false;
		}
	}

	I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
	POSTING_READ(lvds_reg);

	intel_panel_set_backlight(dev, dev_priv->backlight_level);
}

static void intel_lvds_disable(struct intel_lvds *intel_lvds)
{
	struct drm_device *dev = intel_lvds->base.base.dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 ctl_reg, lvds_reg;

	if (HAS_PCH_SPLIT(dev)) {
		ctl_reg = PCH_PP_CONTROL;
		lvds_reg = PCH_LVDS;
	} else {
		dev_priv->backlight_level = intel_panel_get_backlight(dev);
		ctl_reg = PP_CONTROL;
		lvds_reg = LVDS;
	}

	dev_priv->backlight_level = intel_panel_get_backlight(dev);
	intel_panel_set_backlight(dev, 0);

	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);

	if (intel_lvds->pfit_control) {
		if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
			DRM_ERROR("timed out waiting for panel to power off\n");

		I915_WRITE(PFIT_CONTROL, 0);
			intel_lvds->pfit_control = 0;
			intel_lvds->pfit_dirty = false;
		intel_lvds->pfit_dirty = true;
	}

	I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN);
	}
	POSTING_READ(lvds_reg);
}

@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
	struct intel_lvds *intel_lvds = to_intel_lvds(encoder);

	if (mode == DRM_MODE_DPMS_ON)
		intel_lvds_set_power(intel_lvds, true);
		intel_lvds_enable(intel_lvds);
	else
		intel_lvds_set_power(intel_lvds, false);
		intel_lvds_disable(intel_lvds);

	/* XXX: We never power down the LVDS pairs. */
}
@@ -414,43 +449,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder)
	/* Always do a full power on as we do not know what state
	 * we were left in.
	 */
	intel_lvds_set_power(intel_lvds, true);
	intel_lvds_enable(intel_lvds);
}

static void intel_lvds_mode_set(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_lvds *intel_lvds = to_intel_lvds(encoder);

	/*
	 * The LVDS pin pair will already have been turned on in the
	 * intel_crtc_mode_set since it has a large impact on the DPLL
	 * settings.
	 */

	if (HAS_PCH_SPLIT(dev))
		return;

	if (!intel_lvds->pfit_dirty)
		return;

	/*
	 * Enable automatic panel scaling so that non-native modes fill the
	 * screen.  Should be enabled before the pipe is enabled, according to
	 * register description and PRM.
	 */
	DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
		      intel_lvds->pfit_control,
		      intel_lvds->pfit_pgm_ratios);
	if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000))
		DRM_ERROR("timed out waiting for panel to power off\n");

	I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios);
	I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control);
	intel_lvds->pfit_dirty = false;
}

/**
+16 −14
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)

	/* G45 ring initialization fails to reset head to zero */
	if (head != 0) {
		DRM_ERROR("%s head not reset to zero "
		DRM_DEBUG_KMS("%s head not reset to zero "
			      "ctl %08x head %08x tail %08x start %08x\n",
			      ring->name,
			      I915_READ_CTL(ring),
@@ -167,7 +167,8 @@ static int init_ring_common(struct intel_ring_buffer *ring)

		I915_WRITE_HEAD(ring, 0);

		DRM_ERROR("%s head forced to zero "
		if (I915_READ_HEAD(ring) & HEAD_ADDR) {
			DRM_ERROR("failed to set %s head to zero "
				  "ctl %08x head %08x tail %08x start %08x\n",
				  ring->name,
				  I915_READ_CTL(ring),
@@ -175,6 +176,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
				  I915_READ_TAIL(ring),
				  I915_READ_START(ring));
		}
	}

	I915_WRITE_CTL(ring,
			((ring->size - PAGE_SIZE) & RING_NR_PAGES)