diff mbox

[2/4] drm/i915: Move pll new_config field into intel_atomic_state

Message ID 1422543311-5107-2-git-send-email-ander.conselvan.de.oliveira@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ander Conselvan de Oliveira Jan. 29, 2015, 2:55 p.m. UTC
In order to implement atomic mode sets, we'll need to hold state shared
by multiple crtcs in the drm_atomic_state struct. This patch moves
towards that goal by introducing struct intel_atomic_state for that
purpose and moving the staged pll configuration into it. Current state
will be moved in a follow up patch.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   3 +-
 drivers/gpu/drm/i915/intel_ddi.c     |  11 ++--
 drivers/gpu/drm/i915/intel_display.c | 104 +++++++++++++++--------------------
 drivers/gpu/drm/i915/intel_drv.h     |   8 ++-
 4 files changed, 59 insertions(+), 67 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b09173f..862edc4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -297,7 +297,6 @@  struct intel_shared_dpll_config {
 
 struct intel_shared_dpll {
 	struct intel_shared_dpll_config config;
-	struct intel_shared_dpll_config *new_config;
 
 	int active; /* count of number of active CRTCs (i.e. DPMS on) */
 	bool on; /* is the PLL actually active? Disabled during modeset */
@@ -504,6 +503,7 @@  struct drm_i915_error_state {
 struct intel_connector;
 struct intel_encoder;
 struct intel_crtc_state;
+struct intel_atomic_state;
 struct intel_initial_plane_config;
 struct intel_crtc;
 struct intel_limit;
@@ -546,6 +546,7 @@  struct drm_i915_display_funcs {
 	void (*get_initial_plane_config)(struct intel_crtc *,
 					 struct intel_initial_plane_config *);
 	int (*crtc_compute_clock)(struct intel_crtc *crtc,
+				  struct intel_atomic_state *state,
 				  struct intel_crtc_state *crtc_state);
 	void (*crtc_enable)(struct drm_crtc *crtc);
 	void (*crtc_disable)(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ad8b73d..1cd541f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -909,6 +909,7 @@  hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 
 static bool
 hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_atomic_state *state,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder,
 		   int clock)
@@ -926,7 +927,7 @@  hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 
 		crtc_state->dpll_hw_state.wrpll = val;
 
-		pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+		pll = intel_get_shared_dpll(intel_crtc, state, crtc_state);
 		if (pll == NULL) {
 			DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 					 pipe_name(intel_crtc->pipe));
@@ -1096,6 +1097,7 @@  found:
 
 static bool
 skl_ddi_pll_select(struct intel_crtc *intel_crtc,
+		   struct intel_atomic_state *state,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder,
 		   int clock)
@@ -1150,7 +1152,7 @@  skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
 	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
-	pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+	pll = intel_get_shared_dpll(intel_crtc, state, crtc_state);
 	if (pll == NULL) {
 		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 				 pipe_name(intel_crtc->pipe));
@@ -1171,6 +1173,7 @@  skl_ddi_pll_select(struct intel_crtc *intel_crtc,
  * function should be folded into compute_config() eventually.
  */
 bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
+			  struct intel_atomic_state *state,
 			  struct intel_crtc_state *crtc_state)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
@@ -1179,10 +1182,10 @@  bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
 	int clock = crtc_state->port_clock;
 
 	if (IS_SKYLAKE(dev))
-		return skl_ddi_pll_select(intel_crtc, crtc_state,
+		return skl_ddi_pll_select(intel_crtc, state, crtc_state,
 					  intel_encoder, clock);
 	else
-		return hsw_ddi_pll_select(intel_crtc, crtc_state,
+		return hsw_ddi_pll_select(intel_crtc, state, crtc_state,
 					  intel_encoder, clock);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3d220a6..159e6c8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3891,6 +3891,7 @@  void intel_put_shared_dpll(struct intel_crtc *crtc)
 }
 
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+						struct intel_atomic_state *state,
 						struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
@@ -3905,7 +3906,7 @@  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
 			      crtc->base.base.id, pll->name);
 
-		WARN_ON(pll->new_config->crtc_mask);
+		WARN_ON(state->shared_dpll[i].crtc_mask);
 
 		goto found;
 	}
@@ -3914,15 +3915,15 @@  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 		pll = &dev_priv->shared_dplls[i];
 
 		/* Only want to check enabled timings first */
-		if (pll->new_config->crtc_mask == 0)
+		if (state->shared_dpll[i].crtc_mask == 0)
 			continue;
 
 		if (memcmp(&crtc_state->dpll_hw_state,
-			   &pll->new_config->hw_state,
-			   sizeof(pll->new_config->hw_state)) == 0) {
+			   &state->shared_dpll[i].hw_state,
+			   sizeof(state->shared_dpll[i].hw_state)) == 0) {
 			DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
 				      crtc->base.base.id, pll->name,
-				      pll->new_config->crtc_mask,
+				      state->shared_dpll[i].crtc_mask,
 				      pll->active);
 			goto found;
 		}
@@ -3931,7 +3932,7 @@  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 	/* Ok no matching timings, maybe there's a free one? */
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		pll = &dev_priv->shared_dplls[i];
-		if (pll->new_config->crtc_mask == 0) {
+		if (state->shared_dpll[i].crtc_mask == 0) {
 			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
 				      crtc->base.base.id, pll->name);
 			goto found;
@@ -3941,14 +3942,14 @@  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 	return NULL;
 
 found:
-	if (pll->new_config->crtc_mask == 0)
-		pll->new_config->hw_state = crtc_state->dpll_hw_state;
+	if (state->shared_dpll[i].crtc_mask == 0)
+		state->shared_dpll[i].hw_state = crtc_state->dpll_hw_state;
 
 	crtc_state->shared_dpll = i;
 	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
 			 pipe_name(crtc->pipe));
 
-	pll->new_config->crtc_mask |= 1 << crtc->pipe;
+	state->shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
 
 	return pll;
 }
@@ -3962,6 +3963,7 @@  found:
  * releasing the references of pipes specified in clear_pipes.
  */
 static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
+					  struct intel_atomic_state *state,
 					  unsigned clear_pipes)
 {
 	struct intel_shared_dpll *pll;
@@ -3970,54 +3972,23 @@  static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		pll = &dev_priv->shared_dplls[i];
 
-		pll->new_config = kmemdup(&pll->config, sizeof pll->config,
-					  GFP_KERNEL);
-		if (!pll->new_config)
-			goto cleanup;
-
-		pll->new_config->crtc_mask &= ~clear_pipes;
+		memcpy(&state->shared_dpll[i], &pll->config,
+		       sizeof pll->config);
+		state->shared_dpll[i].crtc_mask &= ~clear_pipes;
 	}
 
 	return 0;
-
-cleanup:
-	while (--i >= 0) {
-		pll = &dev_priv->shared_dplls[i];
-		kfree(pll->new_config);
-		pll->new_config = NULL;
-	}
-
-	return -ENOMEM;
 }
 
-static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv)
+static void intel_shared_dpll_commit(struct drm_i915_private *dev_priv,
+				     struct intel_atomic_state *state)
 {
 	struct intel_shared_dpll *pll;
 	enum intel_dpll_id i;
 
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		pll = &dev_priv->shared_dplls[i];
-
-		WARN_ON(pll->new_config == &pll->config);
-
-		pll->config = *pll->new_config;
-		kfree(pll->new_config);
-		pll->new_config = NULL;
-	}
-}
-
-static void intel_shared_dpll_abort_config(struct drm_i915_private *dev_priv)
-{
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		pll = &dev_priv->shared_dplls[i];
-
-		WARN_ON(pll->new_config == &pll->config);
-
-		kfree(pll->new_config);
-		pll->new_config = NULL;
+		pll->config = state->shared_dpll[i];
 	}
 }
 
@@ -6426,6 +6397,7 @@  static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 }
 
 static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
+				   struct intel_atomic_state *state,
 				   struct intel_crtc_state *crtc_state)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -7452,6 +7424,7 @@  static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 }
 
 static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
+				       struct intel_atomic_state *state,
 				       struct intel_crtc_state *crtc_state)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -7498,7 +7471,7 @@  static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
 		else
 			crtc_state->dpll_hw_state.fp1 = fp;
 
-		pll = intel_get_shared_dpll(crtc, crtc_state);
+		pll = intel_get_shared_dpll(crtc, state, crtc_state);
 		if (pll == NULL) {
 			DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 					 pipe_name(crtc->pipe));
@@ -8070,9 +8043,10 @@  void hsw_disable_pc8(struct drm_i915_private *dev_priv)
 }
 
 static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
+				      struct intel_atomic_state *state,
 				      struct intel_crtc_state *crtc_state)
 {
-	if (!intel_ddi_pll_select(crtc, crtc_state))
+	if (!intel_ddi_pll_select(crtc, state, crtc_state))
 		return -EINVAL;
 
 	crtc->lowfreq_avail = false;
@@ -10417,14 +10391,15 @@  static bool intel_crtc_in_use(struct drm_crtc *crtc)
 }
 
 static void
-intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
+intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes,
+			   struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *intel_encoder;
 	struct intel_crtc *intel_crtc;
 	struct drm_connector *connector;
 
-	intel_shared_dpll_commit(dev_priv);
+	intel_shared_dpll_commit(dev_priv, state);
 
 	for_each_intel_encoder(dev, intel_encoder) {
 		if (!intel_encoder->base.crtc)
@@ -11022,6 +10997,7 @@  out:
 }
 
 static int __intel_set_mode_setup_plls(struct drm_device *dev,
+				       struct intel_atomic_state *state,
 				       unsigned modeset_pipes,
 				       unsigned disable_pipes)
 {
@@ -11033,21 +11009,18 @@  static int __intel_set_mode_setup_plls(struct drm_device *dev,
 	if (!dev_priv->display.crtc_compute_clock)
 		return 0;
 
-	ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
+	ret = intel_shared_dpll_start_config(dev_priv, state, clear_pipes);
 	if (ret)
-		goto done;
+		return ret;
 
 	for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
-		struct intel_crtc_state *state = intel_crtc->new_config;
+		struct intel_crtc_state *crtc_state = intel_crtc->new_config;
 		ret = dev_priv->display.crtc_compute_clock(intel_crtc,
-							   state);
-		if (ret) {
-			intel_shared_dpll_abort_config(dev_priv);
-			goto done;
-		}
+							   state, crtc_state);
+		if (ret)
+			break;
 	}
 
-done:
 	return ret;
 }
 
@@ -11063,6 +11036,7 @@  static int __intel_set_mode(struct drm_crtc *crtc,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *saved_mode;
 	struct intel_crtc *intel_crtc;
+	struct intel_atomic_state *state = NULL;
 	int ret = 0;
 
 	saved_mode = kmalloc(sizeof(*saved_mode), GFP_KERNEL);
@@ -11088,7 +11062,14 @@  static int __intel_set_mode(struct drm_crtc *crtc,
 		prepare_pipes &= ~disable_pipes;
 	}
 
-	ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes);
+	state = kzalloc(sizeof *state, GFP_KERNEL);
+	if (!state) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = __intel_set_mode_setup_plls(dev, state,
+					  modeset_pipes, disable_pipes);
 	if (ret)
 		goto done;
 
@@ -11124,7 +11105,7 @@  static int __intel_set_mode(struct drm_crtc *crtc,
 
 	/* Only after disabling all output pipelines that will be changed can we
 	 * update the the output configuration. */
-	intel_modeset_update_state(dev, prepare_pipes);
+	intel_modeset_update_state(dev, prepare_pipes, state);
 
 	modeset_update_crtc_power_domains(dev);
 
@@ -11155,6 +11136,7 @@  done:
 	if (ret && crtc->enabled)
 		crtc->mode = *saved_mode;
 
+	kfree(state);
 	kfree(saved_mode);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eef79cc..f2f4210 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -243,6 +243,10 @@  typedef struct dpll {
 	int	p;
 } intel_clock_t;
 
+struct intel_atomic_state {
+	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+};
+
 struct intel_plane_state {
 	struct drm_plane_state base;
 	struct drm_rect src;
@@ -837,6 +841,7 @@  void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
 void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
 bool intel_ddi_pll_select(struct intel_crtc *crtc,
+			  struct intel_atomic_state *state,
 			  struct intel_crtc_state *crtc_state);
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
 void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
@@ -962,7 +967,8 @@  void assert_shared_dpll(struct drm_i915_private *dev_priv,
 #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
 #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-						struct intel_crtc_state *state);
+						struct intel_atomic_state *state,
+						struct intel_crtc_state *crtc_state);
 void intel_put_shared_dpll(struct intel_crtc *crtc);
 
 void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,