Example #1
0
/*
 * intel_wait_for_pipe_off - wait for pipe to turn off
 * @dev: drm device
 * @pipe: pipe to wait for
 *
 * After disabling a pipe, we can't wait for vblank in the usual way,
 * spinning on the vblank interrupt status bit, since we won't actually
 * see an interrupt when the pipe is disabled.
 *
 * 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_pipe_off(struct drm_device *dev, int pipe)
{
	struct drm_i915_private *dev_priv = dev->dev_private;

	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))
			fprintf(stderr, "pipe_off wait timed out\n");
	} else {
		u32 last_line;
		int reg = PIPEDSL(pipe);
		unsigned long timeout = msecs() + 100;

		/* Wait for the display line to settle */
		do {
			last_line = I915_READ(reg) & DSL_LINEMASK;
			mdelay(5);
		} while (((I915_READ(reg) & DSL_LINEMASK) != last_line) &&
			 (timeout> msecs()));
		if ((msecs()> timeout))
			fprintf(stderr, "pipe_off wait timed out\n");
	}
}
int intel_drrs_configure_dsi_pll(struct intel_dsi *intel_dsi,
					struct intel_dsi_mnp *intel_dsi_mnp)
{
	struct drm_i915_private *dev_priv =
			intel_dsi->base.base.dev->dev_private;
	struct intel_crtc *intel_crtc =
				to_intel_crtc(intel_dsi->base.base.crtc);
	struct intel_mipi_drrs_work *work =
				dev_priv->drrs.mipi_drrs_work;
	u32 dsi_pll_ctrl, vactive;
	u32 dsl_offset = PIPEDSL(intel_crtc->pipe), dsl;
	unsigned long timeout;

	intel_configure_dsi_pll_reg(dev_priv, intel_dsi_mnp, intel_dsi, true);

	dsi_pll_ctrl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
	dsi_pll_ctrl &= (~DSI_PLL_VCO_EN);

	vactive = (I915_READ(VTOTAL(intel_crtc->pipe)) &
				VERTICAL_ACTIVE_DISPLAY_MASK) + 1;

	timeout = jiffies + msecs_to_jiffies(50);

	do {
		if (atomic_read(&work->abort_wait_loop) == 1) {
			DRM_DEBUG_KMS("Aborting the pll update\n");
			return -EPERM;
		}

		dsl = (I915_READ(dsl_offset) & DSL_LINEMASK_GEN3);

		if (jiffies >= timeout) {
			DRM_ERROR("Timeout at waiting for Vblank\n");
			return -ETIMEDOUT;
		}
	} while (dsl <= vactive);

	mutex_lock(&dev_priv->dpio_lock);
	/* Toggle the VCO_EN to bring in the new dividers values */
	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl);

	dsi_pll_ctrl |= DSI_PLL_VCO_EN;
	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_pll_ctrl);
	mutex_unlock(&dev_priv->dpio_lock);

	DRM_DEBUG_KMS("PLL Changed between DSL: %d, %d\n",
			dsl, I915_READ(dsl_offset) & DSL_LINEMASK_GEN3);

	if (wait_for(I915_READ(PIPECONF(PIPE_A)) & PIPECONF_DSI_PLL_LOCKED,
									20)) {
		DRM_ERROR("DSI PLL lock failed\n");
		return -EACCES;
	}

	return 0;
}