[Intel-gfx] [PATCH 02/31] drm/i915: Move IPS related stuff to intel_ips.c

Rodrigo Vivi rodrigo.vivi at intel.com
Thu Nov 5 10:49:54 PST 2015


We need to organize ips a bit in order to fix it initialization
So let's start by following other features by moving all relted
functions to its own file.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
---
 drivers/gpu/drm/i915/Makefile        |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c  |   4 +-
 drivers/gpu/drm/i915/intel_display.c | 127 ++---------------------------
 drivers/gpu/drm/i915/intel_dp.c      |   6 +-
 drivers/gpu/drm/i915/intel_drv.h     |   8 +-
 drivers/gpu/drm/i915/intel_ips.c     | 151 +++++++++++++++++++++++++++++++++++
 6 files changed, 170 insertions(+), 127 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_ips.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..7c1a86e 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -60,6 +60,7 @@ i915-y += intel_audio.o \
 	  intel_fifo_underrun.o \
 	  intel_frontbuffer.o \
 	  intel_hotplug.o \
+	  intel_ips.o \
 	  intel_modes.o \
 	  intel_overlay.o \
 	  intel_psr.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5659d4c..391861d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4034,7 +4034,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 		 * user space can't make reliable use of the CRCs, so let's just
 		 * completely disable it.
 		 */
-		hsw_disable_ips(crtc);
+		intel_ips_disable(crtc);
 
 		spin_lock_irq(&pipe_crc->lock);
 		kfree(pipe_crc->entries);
@@ -4079,7 +4079,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 		else if (IS_HASWELL(dev) && pipe == PIPE_A)
 			hsw_trans_edp_pipe_A_crc_wa(dev, false);
 
-		hsw_enable_ips(crtc);
+		intel_ips_disable(crtc);
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 01da1c9..197c608 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1366,22 +1366,6 @@ void assert_pipe(struct drm_i915_private *dev_priv,
 	     pipe_name(pipe), state_string(state), state_string(cur_state));
 }
 
-static void assert_plane(struct drm_i915_private *dev_priv,
-			 enum plane plane, bool state)
-{
-	u32 val;
-	bool cur_state;
-
-	val = I915_READ(DSPCNTR(plane));
-	cur_state = !!(val & DISPLAY_PLANE_ENABLE);
-	I915_STATE_WARN(cur_state != state,
-	     "plane %c assertion failure (expected %s, current %s)\n",
-	     plane_name(plane), state_string(state), state_string(cur_state));
-}
-
-#define assert_plane_enabled(d, p) assert_plane(d, p, true)
-#define assert_plane_disabled(d, p) assert_plane(d, p, false)
-
 static void assert_planes_disabled(struct drm_i915_private *dev_priv,
 				   enum pipe pipe)
 {
@@ -4529,64 +4513,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
 	}
 }
 
-void hsw_enable_ips(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (!crtc->config->ips_ready)
-		return;
-
-	/* We can only enable IPS after we enable a plane and wait for a vblank */
-	intel_wait_for_vblank(dev, crtc->pipe);
-
-	assert_plane_enabled(dev_priv, crtc->plane);
-	if (IS_BROADWELL(dev)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
-		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000));
-		mutex_unlock(&dev_priv->rps.hw_lock);
-		/* Quoting Art Runyan: "its not safe to expect any particular
-		 * value in IPS_CTL bit 31 after enabling IPS through the
-		 * mailbox." Moreover, the mailbox may return a bogus state,
-		 * so we need to just enable it and continue on.
-		 */
-	} else {
-		I915_WRITE(IPS_CTL, IPS_ENABLE);
-		/* The bit only becomes 1 in the next vblank, so this wait here
-		 * is essentially intel_wait_for_vblank. If we don't have this
-		 * and don't wait for vblanks until the end of crtc_enable, then
-		 * the HW state readout code will complain that the expected
-		 * IPS_CTL value is not the one we read. */
-		if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50))
-			DRM_ERROR("Timed out waiting for IPS enable\n");
-	}
-}
-
-void hsw_disable_ips(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (!crtc->config->ips_ready)
-		return;
-
-	assert_plane_enabled(dev_priv, crtc->plane);
-	if (IS_BROADWELL(dev)) {
-		mutex_lock(&dev_priv->rps.hw_lock);
-		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
-		mutex_unlock(&dev_priv->rps.hw_lock);
-		/* wait for pcode to finish disabling IPS, which may take up to 42ms */
-		if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42))
-			DRM_ERROR("Timed out waiting for IPS disable\n");
-	} else {
-		I915_WRITE(IPS_CTL, 0);
-		POSTING_READ(IPS_CTL);
-	}
-
-	/* We need to wait for a vblank before we can disable the plane. */
-	intel_wait_for_vblank(dev, crtc->pipe);
-}
-
 /** Loads the palette/gamma unit for the CRTC with the prepared values */
 static void intel_crtc_load_lut(struct drm_crtc *crtc)
 {
@@ -4615,7 +4541,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
 	if (IS_HASWELL(dev) && intel_crtc->config->ips_ready &&
 	    ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
 	     GAMMA_MODE_MODE_SPLIT)) {
-		hsw_disable_ips(intel_crtc);
+		intel_ips_disable(intel_crtc);
 		reenable_ips = true;
 	}
 
@@ -4634,7 +4560,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
 	}
 
 	if (reenable_ips)
-		hsw_enable_ips(intel_crtc);
+		intel_ips_enable(intel_crtc);
 }
 
 static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
@@ -4687,7 +4613,7 @@ intel_post_enable_primary(struct drm_crtc *crtc)
 	 * when going from primary only to sprite only and vice
 	 * versa.
 	 */
-	hsw_enable_ips(intel_crtc);
+	intel_ips_enable(intel_crtc);
 
 	/*
 	 * Gen2 reports pipe underruns whenever all planes are disabled.
@@ -4752,7 +4678,7 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 	 * when going from primary only to sprite only and vice
 	 * versa.
 	 */
-	hsw_disable_ips(intel_crtc);
+	intel_ips_disable(intel_crtc);
 }
 
 static void intel_post_plane_update(struct intel_crtc *crtc)
@@ -4791,7 +4717,7 @@ static void intel_pre_plane_update(struct intel_crtc *crtc)
 		intel_fbc_disable_crtc(crtc);
 
 	if (crtc->atomic.disable_ips)
-		hsw_disable_ips(crtc);
+		intel_ips_disable(crtc);
 
 	if (atomic->pre_disable_primary)
 		intel_pre_disable_primary(&crtc->base);
@@ -4891,12 +4817,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 		cpt_verify_modeset(dev, intel_crtc->pipe);
 }
 
-/* IPS only exists on ULT machines and is tied to pipe A. */
-static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
-{
-	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
-}
-
 static void haswell_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -6532,38 +6452,6 @@ retry:
 	return ret;
 }
 
-static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
-				     struct intel_crtc_state *pipe_config)
-{
-	if (pipe_config->pipe_bpp > 24)
-		return false;
-
-	/* HSW can handle pixel rate up to cdclk? */
-	if (IS_HASWELL(dev_priv->dev))
-		return true;
-
-	/*
-	 * We compare against max which means we must take
-	 * the increased cdclk requirement into account when
-	 * calculating the new cdclk.
-	 *
-	 * Should measure whether using a lower cdclk w/o IPS
-	 */
-	return ilk_pipe_pixel_rate(pipe_config) <=
-		dev_priv->max_cdclk_freq * 95 / 100;
-}
-
-static void hsw_compute_ips_config(struct intel_crtc *crtc,
-				   struct intel_crtc_state *pipe_config)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	pipe_config->ips_ready = i915.enable_ips &&
-		hsw_crtc_supports_ips(crtc) &&
-		pipe_config_supports_ips(dev_priv, pipe_config);
-}
-
 static int intel_crtc_compute_config(struct intel_crtc *crtc,
 				     struct intel_crtc_state *pipe_config)
 {
@@ -6609,8 +6497,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 		adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
 		return -EINVAL;
 
-	if (HAS_IPS(dev))
-		hsw_compute_ips_config(crtc, pipe_config);
+	pipe_config->ips_ready = intel_ips_ready(crtc, pipe_config);
 
 	if (pipe_config->has_pch_encoder)
 		return ironlake_fdi_compute_config(crtc, pipe_config);
@@ -9831,7 +9718,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 			ironlake_get_pfit_config(crtc, pipe_config);
 	}
 
-	pipe_config->ips_ready = hsw_crtc_supports_ips(crtc);
+	pipe_config->ips_ready = intel_ips_ready(crtc, pipe_config);
 
 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
 		pipe_config->pixel_multiplier =
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5264887..273e1ad 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3823,7 +3823,7 @@ static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
 
 	intel_dp->sink_crc.started = false;
  out:
-	hsw_enable_ips(intel_crtc);
+	intel_ips_enable(intel_crtc);
 	return ret;
 }
 
@@ -3851,11 +3851,11 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp)
 	if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0)
 		return -EIO;
 
-	hsw_disable_ips(intel_crtc);
+	intel_ips_disable(intel_crtc);
 
 	if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK,
 			       buf | DP_TEST_SINK_START) < 0) {
-		hsw_enable_ips(intel_crtc);
+		intel_ips_enable(intel_crtc);
 		return -EIO;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2aae219..41a88f7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1188,8 +1188,6 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
 int chv_calc_dpll_params(int refclk, intel_clock_t *pll_clock);
 
 bool intel_crtc_active(struct drm_crtc *crtc);
-void hsw_enable_ips(struct intel_crtc *crtc);
-void hsw_disable_ips(struct intel_crtc *crtc);
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder);
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
@@ -1207,6 +1205,12 @@ u32 skl_plane_ctl_format(uint32_t pixel_format);
 u32 skl_plane_ctl_tiling(uint64_t fb_modifier);
 u32 skl_plane_ctl_rotation(unsigned int rotation);
 
+/* intel_ips.c */
+bool intel_ips_ready(struct intel_crtc *crtc,
+		     struct intel_crtc_state *crtc_state);
+void intel_ips_enable(struct intel_crtc *crtc);
+void intel_ips_disable(struct intel_crtc *crtc);
+
 /* intel_csr.c */
 void intel_csr_ucode_init(struct drm_device *dev);
 enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_ips.c b/drivers/gpu/drm/i915/intel_ips.c
new file mode 100644
index 0000000..5c659a3
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_ips.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/* IPS only exists on ULT machines and is tied to pipe A. */
+
+#include "intel_drv.h"
+#include "i915_drv.h"
+
+
+static void assert_plane(struct drm_i915_private *dev_priv,
+			 enum plane plane, bool state)
+{
+	u32 val;
+	bool cur_state;
+
+	val = I915_READ(DSPCNTR(plane));
+	cur_state = !!(val & DISPLAY_PLANE_ENABLE);
+	I915_STATE_WARN(cur_state != state,
+			"plane %c assertion failure (expected %s, current %s)\n",
+			plane_name(plane), state ? "on" : "off",
+			cur_state ? "on" : "off");
+}
+
+#define assert_plane_enabled(d, p) assert_plane(d, p, true)
+#define assert_plane_disabled(d, p) assert_plane(d, p, false)
+
+static bool intel_ips_supported(struct intel_crtc *crtc)
+{
+	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
+}
+
+static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
+				     struct intel_crtc_state *pipe_config)
+{
+	if (pipe_config->pipe_bpp > 24)
+		return false;
+
+	/* HSW can handle pixel rate up to cdclk? */
+	if (IS_HASWELL(dev_priv->dev))
+		return true;
+
+	/*
+	 * We compare against max which means we must take
+	 * the increased cdclk requirement into account when
+	 * calculating the new cdclk.
+	 *
+	 * Should measure whether using a lower cdclk w/o IPS
+	 */
+	return ilk_pipe_pixel_rate(pipe_config) <=
+	       dev_priv->max_cdclk_freq * 95 / 100;
+}
+
+bool intel_ips_ready(struct intel_crtc *crtc,
+		     struct intel_crtc_state *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	return HAS_IPS(dev) && i915.enable_ips &&
+	       intel_ips_supported(crtc) &&
+	       pipe_config_supports_ips(dev_priv, pipe_config);
+}
+
+void intel_ips_enable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config->ips_ready)
+		return;
+
+	/*
+	 * We can only enable IPS after we enable a plane
+	 * and wait for a vblank.
+	 */
+	intel_wait_for_vblank(dev, crtc->pipe);
+
+	assert_plane_enabled(dev_priv, crtc->plane);
+	if (IS_BROADWELL(dev)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
+						0xc0000000));
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		/*
+		 * Quoting Art Runyan: "its not safe to expect any particular
+		 * value in IPS_CTL bit 31 after enabling IPS through the
+		 * mailbox." Moreover, the mailbox may return a bogus state,
+		 * so we need to just enable it and continue on.
+		 */
+	} else {
+		I915_WRITE(IPS_CTL, IPS_ENABLE);
+		/*
+		 * The bit only becomes 1 in the next vblank, so this wait here
+		 * is essentially intel_wait_for_vblank. If we don't have this
+		 * and don't wait for vblanks until the end of crtc_enable, then
+		 * the HW state readout code will complain that the expected
+		 * IPS_CTL value is not the one we read.
+		 */
+		if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50))
+			DRM_ERROR("Timed out waiting for IPS enable\n");
+	}
+}
+
+void intel_ips_disable(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!crtc->config->ips_ready)
+		return;
+
+	assert_plane_enabled(dev_priv, crtc->plane);
+	if (IS_BROADWELL(dev)) {
+		mutex_lock(&dev_priv->rps.hw_lock);
+		WARN_ON(sandybridge_pcode_write(dev_priv,
+						DISPLAY_IPS_CONTROL, 0));
+		mutex_unlock(&dev_priv->rps.hw_lock);
+		/*
+		 * Wait for pcode to finish disabling IPS,
+		 * which may take up to 42ms.
+		 */
+		if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42))
+			DRM_ERROR("Timed out waiting for IPS disable\n");
+	} else {
+		I915_WRITE(IPS_CTL, 0);
+		POSTING_READ(IPS_CTL);
+	}
+
+	/* We need to wait for a vblank before we can disable the plane. */
+	intel_wait_for_vblank(dev, crtc->pipe);
+}
-- 
2.4.3



More information about the Intel-gfx mailing list