All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/42] drm/i915: Convert to atomic, part 2.
@ 2015-05-11 14:24 Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state Maarten Lankhorst
                   ` (42 more replies)
  0 siblings, 43 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This patch makes this happen by consolidating all modeset paths
and getting rid of most transitional state.

This happens first by unifying all paths so all code that
disables a crtc goes through either intel_crtc_toggle or
__intel_set_mode. After that's done crtc_state->active is
updated in intel_crtc_toggle, and used to check whether
the crtc is active or not.

At this point crtc->state is equal to intel_crtc->config and
crtc->state->active is equal to crtc->config.

This gives us enough information to convert all planes to atomic,
this had to be done in a single commit because the transitional
helpers don't call crtc_check and some things have to be moved
there.

This makes the planes fully atomic, next step is getting rid
of the transitional intel_crtc->active and intel_crtc->config,
and replacing it with crtc->state or old_crtc_state.

The last part allows setting multiple crtc's in intel_set_mode,
and restore the sw state after suspend by calculating the hw
state in a drm_atomic_state, then swapping it with sw state
and finally call intel_set_mode with the sw state.

Ander Conselvan de Oliveira (6):
  drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
  drm/i915: Make __intel_set_mode() take only atomic state as argument
  drm/i915: Use global atomic state for staged pll config
  drm/i915: Support modeset across multiple pipes
  drm/i915: Move cdclk and pll setup to intel_modeset_compute_config()
  drm/i915: Read hw state into an atomic state struct

Maarten Lankhorst (36):
  drm/atomic: Allow drivers to subclass drm_atomic_state
  drm/i915: get rid of intel_crtc_disable and related code, v2
  drm/i915: Only update required power domains.
  drm/i915: use intel_crtc_control everywhere
  drm/i915: Get rid of new_encoder.
  drm/i915: get rid of new_crtc
  drm/i915: Get rid of crtc->new_enabled, v2.
  drm/i915: Implement intel_crtc_toggle using atomic state
  drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
  drm/i915: make plane helpers fully atomic
  drm/i915: Update less state during modeset.
  drm/i915: move swap_state to the right place
  drm/i915: Use hwmode for vblanks.
  drm/i915: Remove usage of crtc->config from i915_debugfs.c
  drm/i915: Remove use of crtc->config from intel_pm.c
  drm/i915: Remove use of crtc->config from intel_audio.c
  drm/i915: remove use of crtc->config from intel_fbc.c
  drm/i915: remove use of crtc->config from intel_atomic.c and
    intel_sprite.c
  drm/i915: Remove use of crtc->config from intel_overlay.c
  drm/i915: Pass old state to crtc_disable and use it.
  drm/i915: Pass old state to encoder->(post_)disable.
  drm/i915: Remove use of crtc->config from intel_fbdev.c
  drm/i915: Remove use of crtc->config from intel_psr.c
  drm/i915: Remove use of crtc->config from intel_ddi.c
  drm/i915: Remove use of crtc->config from intel_dp.c
  drm/i915: Remove use of crtc->config from intel_dp_mst.c
  drm/i915: Remove use of crtc->config from intel_dsi.c
  drm/i915: Remove use of crtc->config in intel_hdmi.c
  drm/i915: Remove use of crtc->config in intel_sdvo.c
  drm/i915: Calculate haswell plane workaround.
  drm/i915: remove crtc->active tracking completely
  drm/i915: get rid of crtc->config in intel_display.c, part 1
  drm/i915: get rid of crtc->config in intel_display.c, part 2
  drm/i915: get rid of crtc->config
  drm/i915: swap state correctly in intel_atomic_commit
  drm/i915: return early in __intel_set_mode_setup_plls without modeset

 drivers/gpu/drm/drm_atomic.c              |   91 +-
 drivers/gpu/drm/i915/i915_debugfs.c       |   50 +-
 drivers/gpu/drm/i915/i915_drv.h           |    5 +-
 drivers/gpu/drm/i915/i915_irq.c           |   13 +-
 drivers/gpu/drm/i915/intel_atomic.c       |   93 +-
 drivers/gpu/drm/i915/intel_atomic_plane.c |   59 +-
 drivers/gpu/drm/i915/intel_audio.c        |    2 +-
 drivers/gpu/drm/i915/intel_crt.c          |   21 +-
 drivers/gpu/drm/i915/intel_ddi.c          |   93 +-
 drivers/gpu/drm/i915/intel_display.c      | 2639 +++++++++++++++--------------
 drivers/gpu/drm/i915/intel_dp.c           |   86 +-
 drivers/gpu/drm/i915/intel_dp_mst.c       |   16 +-
 drivers/gpu/drm/i915/intel_drv.h          |   72 +-
 drivers/gpu/drm/i915/intel_dsi.c          |   25 +-
 drivers/gpu/drm/i915/intel_dvo.c          |   15 +-
 drivers/gpu/drm/i915/intel_fbc.c          |    8 +-
 drivers/gpu/drm/i915/intel_fbdev.c        |   19 +-
 drivers/gpu/drm/i915/intel_hdmi.c         |   78 +-
 drivers/gpu/drm/i915/intel_lvds.c         |   13 +-
 drivers/gpu/drm/i915/intel_overlay.c      |    8 +-
 drivers/gpu/drm/i915/intel_panel.c        |    3 +-
 drivers/gpu/drm/i915/intel_pm.c           |   96 +-
 drivers/gpu/drm/i915/intel_psr.c          |   25 +-
 drivers/gpu/drm/i915/intel_sdvo.c         |   22 +-
 drivers/gpu/drm/i915/intel_sprite.c       |   84 +-
 drivers/gpu/drm/i915/intel_tv.c           |    5 +-
 include/drm/drm_atomic.h                  |    4 +
 include/drm/drm_crtc.h                    |    4 +
 28 files changed, 1908 insertions(+), 1741 deletions(-)

-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-13  5:52   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2 Maarten Lankhorst
                   ` (41 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira, dri-devel

Drivers may need to store the state of shared resources, such as PLLs
or FIFO space, into the atomic state. Allow this by making it possible
to subclass drm_atomic_state.

Cc: dri-devel@lists.freedesktop.org
Acked-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/drm_atomic.c | 91 ++++++++++++++++++++++++++++++++------------
 include/drm/drm_atomic.h     |  4 ++
 include/drm/drm_crtc.h       |  4 ++
 3 files changed, 74 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 6e3b78ee7d16..f0f914591f1d 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -38,24 +38,19 @@ static void kfree_state(struct drm_atomic_state *state)
 	kfree(state->crtc_states);
 	kfree(state->planes);
 	kfree(state->plane_states);
-	kfree(state);
 }
 
 /**
- * drm_atomic_state_alloc - allocate atomic state
+ * __drm_atomic_new_state - init new atomic state
  * @dev: DRM device
+ * @state: atomic state
  *
- * This allocates an empty atomic state to track updates.
+ * Default implementation for filling in a new atomic state.
+ * This is useful for drivers that subclass the atomic state.
  */
-struct drm_atomic_state *
-drm_atomic_state_alloc(struct drm_device *dev)
+int __drm_atomic_new_state(struct drm_device *dev,
+			   struct drm_atomic_state *state)
 {
-	struct drm_atomic_state *state;
-
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return NULL;
-
 	/* TODO legacy paths should maybe do a better job about
 	 * setting this appropriately?
 	 */
@@ -92,31 +87,50 @@ drm_atomic_state_alloc(struct drm_device *dev)
 
 	state->dev = dev;
 
-	DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state);
+	DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
 
-	return state;
+	return 0;
 fail:
 	kfree_state(state);
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(__drm_atomic_new_state);
 
-	return NULL;
+/**
+ * drm_atomic_state_alloc - allocate atomic state
+ * @dev: DRM device
+ *
+ * This allocates an empty atomic state to track updates.
+ */
+struct drm_atomic_state *
+drm_atomic_state_alloc(struct drm_device *dev)
+{
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state;
+
+	if (!config->funcs->atomic_new_state) {
+		state = kzalloc(sizeof(*state), GFP_KERNEL);
+		if (!state)
+			return NULL;
+		if (__drm_atomic_new_state(dev, state) < 0) {
+			kfree(state);
+			return NULL;
+		}
+		return state;
+	}
+
+	return config->funcs->atomic_new_state(dev);
 }
 EXPORT_SYMBOL(drm_atomic_state_alloc);
 
 /**
- * drm_atomic_state_clear - clear state object
+ * __drm_atomic_clear_state - clear atomic state
  * @state: atomic state
  *
- * When the w/w mutex algorithm detects a deadlock we need to back off and drop
- * all locks. So someone else could sneak in and change the current modeset
- * configuration. Which means that all the state assembled in @state is no
- * longer an atomic update to the current state, but to some arbitrary earlier
- * state. Which could break assumptions the driver's ->atomic_check likely
- * relies on.
- *
- * Hence we must clear all cached state and completely start over, using this
- * function.
+ * Default implementation for clearing atomic state.
+ * This is useful for drivers that subclass the atomic state.
  */
-void drm_atomic_state_clear(struct drm_atomic_state *state)
+void __drm_atomic_clear_state(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct drm_mode_config *config = &dev->mode_config;
@@ -162,6 +176,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
 		state->plane_states[i] = NULL;
 	}
 }
+EXPORT_SYMBOL(__drm_atomic_clear_state);
+
+/**
+ * drm_atomic_state_clear - clear state object
+ * @state: atomic state
+ *
+ * When the w/w mutex algorithm detects a deadlock we need to back off and drop
+ * all locks. So someone else could sneak in and change the current modeset
+ * configuration. Which means that all the state assembled in @state is no
+ * longer an atomic update to the current state, but to some arbitrary earlier
+ * state. Which could break assumptions the driver's ->atomic_check likely
+ * relies on.
+ *
+ * Hence we must clear all cached state and completely start over, using this
+ * function.
+ */
+void drm_atomic_state_clear(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config *config = &dev->mode_config;
+
+	if (config->funcs->atomic_clear_state)
+		config->funcs->atomic_clear_state(state);
+	else
+		__drm_atomic_clear_state(state);
+}
 EXPORT_SYMBOL(drm_atomic_state_clear);
 
 /**
@@ -181,6 +221,7 @@ void drm_atomic_state_free(struct drm_atomic_state *state)
 	DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
 
 	kfree_state(state);
+	kfree(state);
 }
 EXPORT_SYMBOL(drm_atomic_state_free);
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index c157103492b0..6125eec6ad79 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -35,6 +35,10 @@ drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
 void drm_atomic_state_free(struct drm_atomic_state *state);
 
+int  __must_check
+__drm_atomic_new_state(struct drm_device *dev, struct drm_atomic_state *state);
+void __drm_atomic_clear_state(struct drm_atomic_state *state);
+
 struct drm_crtc_state * __must_check
 drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 			  struct drm_crtc *crtc);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 0a4a040d6bb7..e5bea3a45484 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -983,6 +983,8 @@ struct drm_mode_set {
  * @atomic_check: check whether a given atomic state update is possible
  * @atomic_commit: commit an atomic state update previously verified with
  * 	atomic_check()
+ * @atomic_clear_state: allocate a new atomic state
+ * @atomic_clear_state: clear the atomic state
  *
  * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that
  * involve drivers.
@@ -998,6 +1000,8 @@ struct drm_mode_config_funcs {
 	int (*atomic_commit)(struct drm_device *dev,
 			     struct drm_atomic_state *a,
 			     bool async);
+	struct drm_atomic_state *(*atomic_new_state)(struct drm_device *dev);
+	void (*atomic_clear_state)(struct drm_atomic_state *state);
 };
 
 /**
-- 
2.1.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:08   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 03/42] drm/i915: Only update required power domains Maarten Lankhorst
                   ` (40 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Now that the dpll updates are (mostly) atomic, the .off() code is no longer used,
and there are no more callers for intel_put_shared_dpll. Move all the updates
done in intel_crtc_disable to intel_modeset_update_state, one less special case
to worry about.

Changes since v1:
- Move drm_atomic_helper_swap_state up.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   1 -
 drivers/gpu/drm/i915/intel_display.c | 106 +++++++----------------------------
 drivers/gpu/drm/i915/intel_drv.h     |   1 -
 3 files changed, 19 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6b3142a99171..a6d3ab94ec15 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -574,7 +574,6 @@ struct drm_i915_display_funcs {
 				  struct intel_crtc_state *crtc_state);
 	void (*crtc_enable)(struct drm_crtc *crtc);
 	void (*crtc_disable)(struct drm_crtc *crtc);
-	void (*off)(struct drm_crtc *crtc);
 	void (*audio_codec_enable)(struct drm_connector *connector,
 				   struct intel_encoder *encoder,
 				   struct drm_display_mode *mode);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c5543f0bcda9..af96d686aae2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4228,27 +4228,6 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
 	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
 
-void intel_put_shared_dpll(struct intel_crtc *crtc)
-{
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-
-	if (pll == NULL)
-		return;
-
-	if (!(pll->config.crtc_mask & (1 << crtc->pipe))) {
-		WARN(1, "bad %s crtc mask\n", pll->name);
-		return;
-	}
-
-	pll->config.crtc_mask &= ~(1 << crtc->pipe);
-	if (pll->config.crtc_mask == 0) {
-		WARN_ON(pll->on);
-		WARN_ON(pll->active);
-	}
-
-	crtc->config->shared_dpll = DPLL_ID_PRIVATE;
-}
-
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 						struct intel_crtc_state *crtc_state)
 {
@@ -5224,13 +5203,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 		intel_disable_shared_dpll(intel_crtc);
 }
 
-static void ironlake_crtc_off(struct drm_crtc *crtc)
-{
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	intel_put_shared_dpll(intel_crtc);
-}
-
-
 static void i9xx_pfit_enable(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -6062,10 +6034,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	mutex_unlock(&dev->struct_mutex);
 }
 
-static void i9xx_crtc_off(struct drm_crtc *crtc)
-{
-}
-
 /* Master function to enable/disable CRTC and corresponding power wells */
 void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 {
@@ -6115,34 +6083,6 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc)
 	crtc->state->active = enable;
 }
 
-static void intel_crtc_disable(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_connector *connector;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	/* crtc should still be enabled when we disable it. */
-	WARN_ON(!crtc->state->enable);
-
-	intel_crtc_disable_planes(crtc);
-	dev_priv->display.crtc_disable(crtc);
-	dev_priv->display.off(crtc);
-
-	drm_plane_helper_disable(crtc->primary);
-
-	/* Update computed state. */
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (!connector->encoder || !connector->encoder->crtc)
-			continue;
-
-		if (connector->encoder->crtc != crtc)
-			continue;
-
-		connector->dpms = DRM_MODE_DPMS_OFF;
-		to_intel_encoder(connector->encoder)->connectors_active = false;
-	}
-}
-
 void intel_encoder_destroy(struct drm_encoder *encoder)
 {
 	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
@@ -11614,26 +11554,22 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
-	int i;
 
 	intel_shared_dpll_commit(dev_priv);
+	drm_atomic_helper_swap_state(state->dev, state);
 
 	for_each_intel_encoder(dev, intel_encoder) {
 		if (!intel_encoder->base.crtc)
 			continue;
 
-		for_each_crtc_in_state(state, crtc, crtc_state, i)
-			if (crtc == intel_encoder->base.crtc)
-				break;
-
-		if (crtc != intel_encoder->base.crtc)
+		crtc = intel_encoder->base.crtc;
+		crtc_state = state->crtc_states[drm_crtc_index(crtc)];
+		if (!crtc_state || !needs_modeset(crtc->state))
 			continue;
 
-		if (crtc_state->enable && needs_modeset(crtc_state))
-			intel_encoder->connectors_active = false;
+		intel_encoder->connectors_active = false;
 	}
 
-	drm_atomic_helper_swap_state(state->dev, state);
 	intel_modeset_fixup_state(state);
 
 	/* Double check state. */
@@ -11645,14 +11581,12 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 		if (!connector->encoder || !connector->encoder->crtc)
 			continue;
 
-		for_each_crtc_in_state(state, crtc, crtc_state, i)
-			if (crtc == connector->encoder->crtc)
-				break;
-
-		if (crtc != connector->encoder->crtc)
+		crtc = connector->encoder->crtc;
+		crtc_state = state->crtc_states[drm_crtc_index(crtc)];
+		if (!crtc_state || !needs_modeset(crtc->state))
 			continue;
 
-		if (crtc->state->enable && needs_modeset(crtc->state)) {
+		if (crtc->state->enable) {
 			struct drm_property *dpms_property =
 				dev->mode_config.dpms_property;
 
@@ -11663,7 +11597,8 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 
 			intel_encoder = to_intel_encoder(connector->encoder);
 			intel_encoder->connectors_active = true;
-		}
+		} else
+			connector->dpms = DRM_MODE_DPMS_OFF;
 	}
 
 }
@@ -12214,6 +12149,10 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	if (IS_ERR(pipe_config))
 		return pipe_config;
 
+	if (!pipe_config->base.enable &&
+	    WARN_ON(pipe_config->base.active))
+		pipe_config->base.active = false;
+
 	if (!pipe_config->base.enable)
 		return pipe_config;
 
@@ -12341,12 +12280,10 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 		if (!needs_modeset(crtc_state))
 			continue;
 
-		if (!crtc_state->enable) {
-			intel_crtc_disable(crtc);
-		} else if (crtc->state->enable) {
-			intel_crtc_disable_planes(crtc);
-			dev_priv->display.crtc_disable(crtc);
-		}
+		intel_crtc_disable_planes(crtc);
+		dev_priv->display.crtc_disable(crtc);
+		if (!crtc_state->enable)
+			drm_plane_helper_disable(crtc->primary);
 	}
 
 	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
@@ -14064,7 +14001,6 @@ static void intel_init_display(struct drm_device *dev)
 			haswell_crtc_compute_clock;
 		dev_priv->display.crtc_enable = haswell_crtc_enable;
 		dev_priv->display.crtc_disable = haswell_crtc_disable;
-		dev_priv->display.off = ironlake_crtc_off;
 		dev_priv->display.update_primary_plane =
 			skylake_update_primary_plane;
 	} else if (HAS_DDI(dev)) {
@@ -14075,7 +14011,6 @@ static void intel_init_display(struct drm_device *dev)
 			haswell_crtc_compute_clock;
 		dev_priv->display.crtc_enable = haswell_crtc_enable;
 		dev_priv->display.crtc_disable = haswell_crtc_disable;
-		dev_priv->display.off = ironlake_crtc_off;
 		dev_priv->display.update_primary_plane =
 			ironlake_update_primary_plane;
 	} else if (HAS_PCH_SPLIT(dev)) {
@@ -14086,7 +14021,6 @@ static void intel_init_display(struct drm_device *dev)
 			ironlake_crtc_compute_clock;
 		dev_priv->display.crtc_enable = ironlake_crtc_enable;
 		dev_priv->display.crtc_disable = ironlake_crtc_disable;
-		dev_priv->display.off = ironlake_crtc_off;
 		dev_priv->display.update_primary_plane =
 			ironlake_update_primary_plane;
 	} else if (IS_VALLEYVIEW(dev)) {
@@ -14096,7 +14030,6 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
 		dev_priv->display.crtc_enable = valleyview_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
-		dev_priv->display.off = i9xx_crtc_off;
 		dev_priv->display.update_primary_plane =
 			i9xx_update_primary_plane;
 	} else {
@@ -14106,7 +14039,6 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
 		dev_priv->display.crtc_enable = i9xx_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
-		dev_priv->display.off = i9xx_crtc_off;
 		dev_priv->display.update_primary_plane =
 			i9xx_update_primary_plane;
 	}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 29262228f264..4c690403942c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1082,7 +1082,6 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 #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);
-void intel_put_shared_dpll(struct intel_crtc *crtc);
 
 void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
 		      const struct dpll *dpll);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 03/42] drm/i915: Only update required power domains.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2 Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:00   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 04/42] drm/i915: use intel_crtc_control everywhere Maarten Lankhorst
                   ` (39 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This prevents unnecessarily updating power domains, while still
enabling all power domains on initial setup.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 52 ++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index af96d686aae2..42d0cc329b37 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5298,36 +5298,72 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 	return mask;
 }
 
+static bool
+needs_modeset(struct drm_crtc_state *state)
+{
+	return state->mode_changed || state->active_changed;
+}
+
 static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
 	struct intel_crtc *crtc;
+	bool init_power = dev_priv->power_domains.init_power_on;
+	bool any_power = init_power, any_modeset = false;
+	unsigned long domains;
 
 	/*
 	 * First get all needed power domains, then put all unneeded, to avoid
 	 * any unnecessary toggling of the power wells.
 	 */
 	for_each_intel_crtc(dev, crtc) {
+		int idx = drm_crtc_index(&crtc->base);
+		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
 		enum intel_display_power_domain domain;
 
-		if (!crtc->base.state->enable)
+		if (!init_power && !crtc_state)
+			continue;
+
+		if (needs_modeset(crtc->base.state))
+			any_modeset = true;
+
+		if (crtc->base.state->enable)
+			pipe_domains[crtc->pipe] =
+				get_crtc_power_domains(&crtc->base);
+
+		if (pipe_domains[crtc->pipe] == crtc->enabled_power_domains)
 			continue;
 
-		pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
+		WARN_ON(!init_power && !needs_modeset(crtc->base.state));
+
+		any_power = true;
+		domains = pipe_domains[crtc->pipe] &
+			  ~crtc->enabled_power_domains;
 
-		for_each_power_domain(domain, pipe_domains[crtc->pipe])
+		for_each_power_domain(domain, domains)
 			intel_display_power_get(dev_priv, domain);
 	}
 
-	if (dev_priv->display.modeset_global_resources)
+	if (any_modeset && dev_priv->display.modeset_global_resources)
 		dev_priv->display.modeset_global_resources(state);
 
+	if (!any_power)
+		return;
+
 	for_each_intel_crtc(dev, crtc) {
+		int idx = drm_crtc_index(&crtc->base);
+		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
 		enum intel_display_power_domain domain;
 
-		for_each_power_domain(domain, crtc->enabled_power_domains)
+		if (!init_power && !crtc_state)
+			continue;
+
+		domains = crtc->enabled_power_domains &
+			  ~pipe_domains[crtc->pipe];
+
+		for_each_power_domain(domain, domains)
 			intel_display_power_put(dev_priv, domain);
 
 		crtc->enabled_power_domains = pipe_domains[crtc->pipe];
@@ -11539,12 +11575,6 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc)
 	return false;
 }
 
-static bool
-needs_modeset(struct drm_crtc_state *state)
-{
-	return state->mode_changed || state->active_changed;
-}
-
 static void
 intel_modeset_update_state(struct drm_atomic_state *state)
 {
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 04/42] drm/i915: use intel_crtc_control everywhere
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 03/42] drm/i915: Only update required power domains Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:11   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 05/42] drm/i915: Get rid of new_encoder Maarten Lankhorst
                   ` (38 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  | 18 ++++++++--
 drivers/gpu/drm/i915/intel_display.c | 68 +++++++++++++-----------------------
 drivers/gpu/drm/i915/intel_drv.h     |  1 -
 3 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index adbbddab42c6..acd4d2c7613a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -3606,12 +3606,18 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
 	 */
 	if (crtc->config->cpu_transcoder == TRANSCODER_EDP &&
 	    !crtc->config->pch_pfit.enabled) {
+		bool active = crtc->active;
+
+		if (active)
+			intel_crtc_control(&crtc->base, false);
+
 		crtc->config->pch_pfit.force_thru = true;
 
 		intel_display_power_get(dev_priv,
 					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
 
-		intel_crtc_reset(crtc);
+		if (active)
+			intel_crtc_control(&crtc->base, true);
 	}
 	drm_modeset_unlock_all(dev);
 }
@@ -3630,12 +3636,18 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
 	 * routing.
 	 */
 	if (crtc->config->pch_pfit.force_thru) {
-		crtc->config->pch_pfit.force_thru = false;
+		bool active = crtc->active;
 
-		intel_crtc_reset(crtc);
+		if (active)
+			intel_crtc_control(&crtc->base, false);
+
+		crtc->config->pch_pfit.force_thru = false;
 
 		intel_display_power_put(dev_priv,
 					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
+
+		if (active)
+			intel_crtc_control(&crtc->base, true);
 	}
 	drm_modeset_unlock_all(dev);
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 42d0cc329b37..70269da6a6b8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3206,22 +3206,8 @@ static void intel_update_primary_planes(struct drm_device *dev)
 	}
 }
 
-void intel_crtc_reset(struct intel_crtc *crtc)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
-	if (!crtc->active)
-		return;
-
-	intel_crtc_disable_planes(&crtc->base);
-	dev_priv->display.crtc_disable(&crtc->base);
-	dev_priv->display.crtc_enable(&crtc->base);
-	intel_crtc_enable_planes(&crtc->base);
-}
-
 void intel_prepare_reset(struct drm_device *dev)
 {
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *crtc;
 
 	/* no reset support for gen2 */
@@ -3233,18 +3219,12 @@ void intel_prepare_reset(struct drm_device *dev)
 		return;
 
 	drm_modeset_lock_all(dev);
-
 	/*
 	 * Disabling the crtcs gracefully seems nicer. Also the
 	 * g33 docs say we should at least disable all the planes.
 	 */
-	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
-			continue;
-
-		intel_crtc_disable_planes(&crtc->base);
-		dev_priv->display.crtc_disable(&crtc->base);
-	}
+	for_each_intel_crtc(dev, crtc)
+		intel_crtc_control(&crtc->base, false);
 }
 
 void intel_finish_reset(struct drm_device *dev)
@@ -6079,26 +6059,29 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 	enum intel_display_power_domain domain;
 	unsigned long domains;
 
+	if (enable == intel_crtc->active)
+		return;
+
+	if (enable && !crtc->state->enable)
+		return;
+
+	crtc->state->active = enable;
 	if (enable) {
-		if (!intel_crtc->active) {
-			domains = get_crtc_power_domains(crtc);
-			for_each_power_domain(domain, domains)
-				intel_display_power_get(dev_priv, domain);
-			intel_crtc->enabled_power_domains = domains;
-
-			dev_priv->display.crtc_enable(crtc);
-			intel_crtc_enable_planes(crtc);
-		}
+		domains = get_crtc_power_domains(crtc);
+		for_each_power_domain(domain, domains)
+			intel_display_power_get(dev_priv, domain);
+		intel_crtc->enabled_power_domains = domains;
+
+		dev_priv->display.crtc_enable(crtc);
+		intel_crtc_enable_planes(crtc);
 	} else {
-		if (intel_crtc->active) {
-			intel_crtc_disable_planes(crtc);
-			dev_priv->display.crtc_disable(crtc);
-
-			domains = intel_crtc->enabled_power_domains;
-			for_each_power_domain(domain, domains)
-				intel_display_power_put(dev_priv, domain);
-			intel_crtc->enabled_power_domains = 0;
-		}
+		intel_crtc_disable_planes(crtc);
+		dev_priv->display.crtc_disable(crtc);
+
+		domains = intel_crtc->enabled_power_domains;
+		for_each_power_domain(domain, domains)
+			intel_display_power_put(dev_priv, domain);
+		intel_crtc->enabled_power_domains = 0;
 	}
 }
 
@@ -6115,8 +6098,6 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc)
 		enable |= intel_encoder->connectors_active;
 
 	intel_crtc_control(crtc, enable);
-
-	crtc->state->active = enable;
 }
 
 void intel_encoder_destroy(struct drm_encoder *encoder)
@@ -14543,8 +14524,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 		plane = crtc->plane;
 		to_intel_plane_state(crtc->base.primary->state)->visible = true;
 		crtc->plane = !plane;
-		intel_crtc_disable_planes(&crtc->base);
-		dev_priv->display.crtc_disable(&crtc->base);
+		intel_crtc_control(&crtc->base, false);
 		crtc->plane = plane;
 
 		/* ... and break all links. */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4c690403942c..7390fe9ba97d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -993,7 +993,6 @@ void intel_mark_busy(struct drm_device *dev);
 void intel_mark_idle(struct drm_device *dev);
 void intel_crtc_restore_mode(struct drm_crtc *crtc);
 void intel_crtc_control(struct drm_crtc *crtc, bool enable);
-void intel_crtc_reset(struct intel_crtc *crtc);
 void intel_crtc_update_dpms(struct drm_crtc *crtc);
 void intel_encoder_destroy(struct drm_encoder *encoder);
 int intel_connector_init(struct intel_connector *);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 05/42] drm/i915: Get rid of new_encoder.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 04/42] drm/i915: use intel_crtc_control everywhere Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:17   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 06/42] drm/i915: get rid of new_crtc Maarten Lankhorst
                   ` (37 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 16 +++++-----------
 drivers/gpu/drm/i915/intel_drv.h     |  6 ------
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 70269da6a6b8..00b1552a1f91 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9796,7 +9796,6 @@ retry:
 	if (ret)
 		goto fail_unlock;
 	intel_encoder->new_crtc = to_intel_crtc(crtc);
-	to_intel_connector(connector)->new_encoder = intel_encoder;
 
 	intel_crtc = to_intel_crtc(crtc);
 	intel_crtc->new_enabled = true;
@@ -9915,7 +9914,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 		if (IS_ERR(crtc_state))
 			goto fail;
 
-		to_intel_connector(connector)->new_encoder = NULL;
 		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 
@@ -11066,12 +11064,6 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
 {
 	struct intel_crtc *crtc;
 	struct intel_encoder *encoder;
-	struct intel_connector *connector;
-
-	for_each_intel_connector(dev, connector) {
-		connector->new_encoder =
-			to_intel_encoder(connector->base.encoder);
-	}
 
 	for_each_intel_encoder(dev, encoder) {
 		encoder->new_crtc =
@@ -11886,11 +11878,14 @@ check_connector_state(struct drm_device *dev)
 	struct intel_connector *connector;
 
 	for_each_intel_connector(dev, connector) {
+		struct drm_encoder *encoder = connector->base.encoder;
+		struct drm_connector_state *state = connector->base.state;
+
 		/* This also checks the encoder/connector hw state with the
 		 * ->get_hw_state callbacks. */
 		intel_connector_check_state(connector);
 
-		I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
+		I915_STATE_WARN(state->best_encoder != encoder,
 		     "connector's staged encoder doesn't match current encoder\n");
 	}
 }
@@ -12410,7 +12405,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 			continue;
 
 		for_each_intel_connector(dev, connector) {
-			if (connector->new_encoder != encoder)
+			if (connector->base.state->best_encoder != &encoder->base)
 				continue;
 
 			connector_state = drm_atomic_get_connector_state(state, &connector->base);
@@ -12423,7 +12418,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 			}
 
 			connector_state->crtc = crtc;
-			connector_state->best_encoder = &encoder->base;
 		}
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7390fe9ba97d..44d1de9ee2db 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -195,12 +195,6 @@ struct intel_connector {
 	 */
 	struct intel_encoder *encoder;
 
-	/*
-	 * The new encoder this connector will be driven. Only differs from
-	 * encoder while a modeset is in progress.
-	 */
-	struct intel_encoder *new_encoder;
-
 	/* Reads out the current hw, returning true if the connector is enabled
 	 * and active (i.e. dpms ON state). */
 	bool (*get_hw_state)(struct intel_connector *);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 06/42] drm/i915: get rid of new_crtc
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (4 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 05/42] drm/i915: Get rid of new_encoder Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:28   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2 Maarten Lankhorst
                   ` (36 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 15 ++++-----------
 drivers/gpu/drm/i915/intel_drv.h     |  5 -----
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00b1552a1f91..a9ce827601d8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9795,7 +9795,6 @@ retry:
 	ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
 	if (ret)
 		goto fail_unlock;
-	intel_encoder->new_crtc = to_intel_crtc(crtc);
 
 	intel_crtc = to_intel_crtc(crtc);
 	intel_crtc->new_enabled = true;
@@ -9914,7 +9913,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 		if (IS_ERR(crtc_state))
 			goto fail;
 
-		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 
 		connector_state->best_encoder = NULL;
@@ -11063,12 +11061,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 static void intel_modeset_update_staged_output_state(struct drm_device *dev)
 {
 	struct intel_crtc *crtc;
-	struct intel_encoder *encoder;
-
-	for_each_intel_encoder(dev, encoder) {
-		encoder->new_crtc =
-			to_intel_crtc(encoder->base.crtc);
-	}
 
 	for_each_intel_crtc(dev, crtc) {
 		crtc->new_enabled = crtc->base.state->enable;
@@ -11905,8 +11897,6 @@ check_encoder_state(struct drm_device *dev)
 			      encoder->base.base.id,
 			      encoder->base.name);
 
-		I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
-		     "encoder's stage crtc doesn't match current crtc\n");
 		I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
 		     "encoder's active_connectors set, but no crtc\n");
 
@@ -11916,6 +11906,9 @@ check_encoder_state(struct drm_device *dev)
 			enabled = true;
 			if (connector->base.dpms != DRM_MODE_DPMS_OFF)
 				active = true;
+
+			I915_STATE_WARN(connector->base.state->crtc != encoder->base.crtc,
+			     "encoder's stage crtc doesn't match current crtc\n");
 		}
 		/*
 		 * for MST connectors if we unplug the connector is gone
@@ -12401,7 +12394,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 	 * need to copy the staged config to the atomic state, otherwise the
 	 * mode set will just reapply the state the HW is already in. */
 	for_each_intel_encoder(dev, encoder) {
-		if (&encoder->new_crtc->base != crtc)
+		if (encoder->base.crtc != crtc)
 			continue;
 
 		for_each_intel_connector(dev, connector) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 44d1de9ee2db..f85761494dd1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -130,11 +130,6 @@ struct intel_fbdev {
 
 struct intel_encoder {
 	struct drm_encoder base;
-	/*
-	 * The new crtc this encoder will be driven from. Only differs from
-	 * base->crtc while a modeset is in progress.
-	 */
-	struct intel_crtc *new_crtc;
 
 	enum intel_output_type type;
 	unsigned int cloneable;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (5 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 06/42] drm/i915: get rid of new_crtc Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 17:33   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state Maarten Lankhorst
                   ` (35 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

No longer any different from state->enable.

v2: Keep track of enabled crtc's for calling intel_crtc_restore_mode.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 63 +++++++++++-------------------------
 drivers/gpu/drm/i915/intel_drv.h     |  1 -
 2 files changed, 18 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a9ce827601d8..8c2fb951029b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9733,7 +9733,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 retry:
 	ret = drm_modeset_lock(&config->connection_mutex, ctx);
 	if (ret)
-		goto fail_unlock;
+		goto fail;
 
 	/*
 	 * Algorithm gets a little messy:
@@ -9751,10 +9751,10 @@ retry:
 
 		ret = drm_modeset_lock(&crtc->mutex, ctx);
 		if (ret)
-			goto fail_unlock;
+			goto fail;
 		ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
 		if (ret)
-			goto fail_unlock;
+			goto fail;
 
 		old->dpms_mode = connector->dpms;
 		old->load_detect_temp = false;
@@ -9773,9 +9773,6 @@ retry:
 			continue;
 		if (possible_crtc->state->enable)
 			continue;
-		/* This can occur when applying the pipe A quirk on resume. */
-		if (to_intel_crtc(possible_crtc)->new_enabled)
-			continue;
 
 		crtc = possible_crtc;
 		break;
@@ -9786,18 +9783,17 @@ retry:
 	 */
 	if (!crtc) {
 		DRM_DEBUG_KMS("no pipe available for load-detect\n");
-		goto fail_unlock;
+		goto fail;
 	}
 
 	ret = drm_modeset_lock(&crtc->mutex, ctx);
 	if (ret)
-		goto fail_unlock;
+		goto fail;
 	ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
 	if (ret)
-		goto fail_unlock;
+		goto fail;
 
 	intel_crtc = to_intel_crtc(crtc);
-	intel_crtc->new_enabled = true;
 	old->dpms_mode = connector->dpms;
 	old->load_detect_temp = true;
 	old->release_fb = NULL;
@@ -9865,9 +9861,7 @@ retry:
 	intel_wait_for_vblank(dev, intel_crtc->pipe);
 	return true;
 
- fail:
-	intel_crtc->new_enabled = crtc->state->enable;
-fail_unlock:
+fail:
 	drm_atomic_state_free(state);
 	state = NULL;
 
@@ -9913,8 +9907,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 		if (IS_ERR(crtc_state))
 			goto fail;
 
-		intel_crtc->new_enabled = false;
-
 		connector_state->best_encoder = NULL;
 		connector_state->crtc = NULL;
 
@@ -11052,21 +11044,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.atomic_flush = intel_finish_crtc_commit,
 };
 
-/**
- * intel_modeset_update_staged_output_state
- *
- * Updates the staged output configuration state, e.g. after we've read out the
- * current hw state.
- */
-static void intel_modeset_update_staged_output_state(struct drm_device *dev)
-{
-	struct intel_crtc *crtc;
-
-	for_each_intel_crtc(dev, crtc) {
-		crtc->new_enabled = crtc->base.state->enable;
-	}
-}
-
 /* Transitional helper to copy current connector/encoder state to
  * connector->state. This is needed so that code that is partially
  * converted to atomic does the right thing.
@@ -11119,10 +11096,6 @@ static void intel_modeset_fixup_state(struct drm_atomic_state *state)
 		crtc->base.enabled = crtc->base.state->enable;
 		crtc->config = to_intel_crtc_state(crtc->base.state);
 	}
-
-	/* Copy the new configuration to the staged state, to keep the few
-	 * pieces of code that haven't been converted yet happy */
-	intel_modeset_update_staged_output_state(state->dev);
 }
 
 static void
@@ -12415,9 +12388,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 	}
 
 	for_each_intel_crtc(dev, intel_crtc) {
-		if (intel_crtc->new_enabled == intel_crtc->base.enabled)
-			continue;
-
 		crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
 		if (IS_ERR(crtc_state)) {
 			DRM_DEBUG_KMS("Failed to add [CRTC:%d] to state: %ld\n",
@@ -12426,9 +12396,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 			continue;
 		}
 
-		crtc_state->base.active = crtc_state->base.enable =
-			intel_crtc->new_enabled;
-
 		if (&intel_crtc->base == crtc)
 			drm_mode_copy(&crtc_state->base.mode, &crtc->mode);
 	}
@@ -14679,7 +14646,8 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
 	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
-static void intel_modeset_readout_hw_state(struct drm_device *dev)
+static void intel_modeset_readout_hw_state(struct drm_device *dev,
+					   unsigned *crtc_mask)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe;
@@ -14688,6 +14656,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 	struct intel_connector *connector;
 	int i;
 
+	*crtc_mask = 0;
 	for_each_intel_crtc(dev, crtc) {
 		struct drm_plane *primary = crtc->base.primary;
 		struct intel_plane_state *plane_state;
@@ -14696,6 +14665,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 
 		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
 
+		if (crtc->active)
+			*crtc_mask |= drm_crtc_index(&crtc->base);
+
 		crtc->active = dev_priv->display.get_pipe_config(crtc,
 								 crtc->config);
 
@@ -14778,7 +14750,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 	struct intel_encoder *encoder;
 	int i;
 
-	intel_modeset_readout_hw_state(dev);
+	unsigned crtc_mask;
+
+	intel_modeset_readout_hw_state(dev, &crtc_mask);
 
 	/*
 	 * Now that we have the config, copy it to each CRTC struct
@@ -14837,10 +14811,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 			struct drm_crtc *crtc =
 				dev_priv->pipe_to_crtc_mapping[pipe];
 
-			intel_crtc_restore_mode(crtc);
+			if (crtc_mask & (1 << drm_crtc_index(crtc)))
+				intel_crtc_restore_mode(crtc);
 		}
-	} else {
-		intel_modeset_update_staged_output_state(dev);
 	}
 
 	intel_modeset_check_state(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f85761494dd1..1e892098eea2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -515,7 +515,6 @@ struct intel_crtc {
 
 	struct intel_initial_plane_config plane_config;
 	struct intel_crtc_state *config;
-	bool new_enabled;
 
 	/* reset counter value when the last flip was submitted */
 	unsigned int reset_counter;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (6 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2 Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 18:12   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper Maarten Lankhorst
                   ` (34 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Assume the function is locked with drm_modeset_lock_all for now.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c      |  2 +-
 drivers/gpu/drm/i915/intel_display.c | 79 ++++++++++++++++++++++--------------
 2 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9da955e4f355..a6816503a080 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
 		return -EINVAL;
 	}
 
-	if (!crtc->state->enable) {
+	if (!crtc->state->active) {
 		DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
 		return -EBUSY;
 	}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8c2fb951029b..a21b2e51c054 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4656,7 +4656,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
 	bool reenable_ips = false;
 
 	/* The clocks have to be on to load the palette. */
-	if (!crtc->state->enable || !intel_crtc->active)
+	if (!crtc->state->active || !intel_crtc->active)
 		return;
 
 	if (HAS_GMCH_DISPLAY(dev_priv->dev)) {
@@ -5767,7 +5767,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)
 
 	/* add all active pipes to the state */
 	for_each_crtc(state->dev, crtc) {
-		if (!crtc->state->enable)
+		if (!crtc->state->active)
 			continue;
 
 		crtc_state = drm_atomic_get_crtc_state(state, crtc);
@@ -5865,7 +5865,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	bool is_dsi;
 
-	WARN_ON(!crtc->state->enable);
+	WARN_ON(!crtc->state->active);
 
 	if (intel_crtc->active)
 		return;
@@ -5943,7 +5943,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 
-	WARN_ON(!crtc->state->enable);
+	WARN_ON(!crtc->state->active);
 
 	if (intel_crtc->active)
 		return;
@@ -6054,10 +6054,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum intel_display_power_domain domain;
-	unsigned long domains;
+	struct intel_crtc_state *pipe_config;
+	struct drm_plane_state *plane_state;
+	struct drm_atomic_state *state;
+	int ret;
 
 	if (enable == intel_crtc->active)
 		return;
@@ -6065,24 +6068,40 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 	if (enable && !crtc->state->enable)
 		return;
 
-	crtc->state->active = enable;
-	if (enable) {
-		domains = get_crtc_power_domains(crtc);
-		for_each_power_domain(domain, domains)
-			intel_display_power_get(dev_priv, domain);
-		intel_crtc->enabled_power_domains = domains;
+	/* this function should be called with drm_modeset_lock_all for now */
+	if (WARN_ON(!ctx))
+		return;
+	lockdep_assert_held(&ctx->ww_ctx);
 
-		dev_priv->display.crtc_enable(crtc);
-		intel_crtc_enable_planes(crtc);
-	} else {
-		intel_crtc_disable_planes(crtc);
-		dev_priv->display.crtc_disable(crtc);
+	state = drm_atomic_state_alloc(dev);
+	if (WARN_ON(!state))
+		return;
 
-		domains = intel_crtc->enabled_power_domains;
-		for_each_power_domain(domain, domains)
-			intel_display_power_put(dev_priv, domain);
-		intel_crtc->enabled_power_domains = 0;
+	state->acquire_ctx = ctx;
+	state->allow_modeset = true;
+
+	pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
+	if (IS_ERR(pipe_config)) {
+		ret = PTR_ERR(pipe_config);
+		goto err;
 	}
+	pipe_config->base.active = enable;
+
+	plane_state = drm_atomic_get_plane_state(state, crtc->primary);
+	if (IS_ERR(plane_state)) {
+		ret = PTR_ERR(plane_state);
+		goto err;
+	}
+
+	ret = intel_set_mode(crtc, state);
+	if (!ret)
+		return;
+
+	DRM_ERROR("Failed to toggle crtc!\n");
+
+err:
+	DRM_ERROR("Updating crtc active failed with %i\n", ret);
+	drm_atomic_state_free(state);
 }
 
 /**
@@ -6158,7 +6177,7 @@ static void intel_connector_check_state(struct intel_connector *connector)
 
 			crtc = encoder->base.crtc;
 
-			I915_STATE_WARN(!crtc->state->enable,
+			I915_STATE_WARN(!crtc->state->active,
 					"crtc not enabled\n");
 			I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
 			I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
@@ -11554,7 +11573,7 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 		if (!crtc_state || !needs_modeset(crtc->state))
 			continue;
 
-		if (crtc->state->enable) {
+		if (crtc->state->active) {
 			struct drm_property *dpms_property =
 				dev->mode_config.dpms_property;
 
@@ -12018,7 +12037,7 @@ check_shared_dpll_state(struct drm_device *dev)
 		     pll->on, active);
 
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
+			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
 				enabled_crtcs++;
 			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
 				active_crtcs++;
@@ -12185,7 +12204,7 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 		goto done;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!needs_modeset(crtc_state) || !crtc_state->enable)
+		if (!needs_modeset(crtc_state) || !crtc_state->active)
 			continue;
 
 		intel_crtc = to_intel_crtc(crtc);
@@ -12265,7 +12284,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	 * pipes; here we assume a single modeset_pipe and only track the
 	 * single crtc and mode.
 	 */
-	if (pipe_config->base.enable && needs_modeset(&pipe_config->base)) {
+	if (pipe_config->base.active && needs_modeset(&pipe_config->base)) {
 		modeset_crtc->mode = pipe_config->base.mode;
 
 		/*
@@ -12290,7 +12309,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 
 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!needs_modeset(crtc->state) || !crtc->state->enable)
+		if (!crtc->state->active)
 			continue;
 
 		update_scanline_offset(to_intel_crtc(crtc));
@@ -14516,7 +14535,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 	 * have active connectors/encoders. */
 	intel_crtc_update_dpms(&crtc->base);
 
-	if (crtc->active != crtc->base.state->enable) {
+	if (crtc->active != crtc->base.state->active) {
 		struct intel_encoder *encoder;
 
 		/* This can happen either due to bugs in the get_hw_state
@@ -14665,7 +14684,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 
 		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
 
-		if (crtc->active)
+		if (crtc->base.state->active)
 			*crtc_mask |= drm_crtc_index(&crtc->base);
 
 		crtc->active = dev_priv->display.get_pipe_config(crtc,
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (7 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  6:59   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 10/42] drm/i915: make plane helpers fully atomic Maarten Lankhorst
                   ` (33 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This should be safe.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 82 ++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a21b2e51c054..956c9964275d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11084,36 +11084,48 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
 	}
 }
 
-/* Fixup legacy state after an atomic state swap.
+/*
+ * Fixup legacy state in a similar way to
+ * drm_atomic_helper.c:set_routing_links.
  */
 static void intel_modeset_fixup_state(struct drm_atomic_state *state)
 {
-	struct intel_crtc *crtc;
-	struct intel_encoder *encoder;
-	struct intel_connector *connector;
+	struct drm_connector *connector;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc *crtc;
+	int i;
 
-	for_each_intel_connector(state->dev, connector) {
-		connector->base.encoder = connector->base.state->best_encoder;
-		if (connector->base.encoder)
-			connector->base.encoder->crtc =
-				connector->base.state->crtc;
+	/*
+	 * swap crtc and connector and update legacy state,
+	 * plane state already gets swapped
+	 * by the plane helpers. Once .crtc_disable is fixed
+	 * all state should be swapped before disabling crtc's.
+	 */
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		crtc->enabled = crtc->state->enable;
+		crtc->mode = crtc->state->mode;
 	}
 
-	/* Update crtc of disabled encoders */
-	for_each_intel_encoder(state->dev, encoder) {
-		int num_connectors = 0;
-
-		for_each_intel_connector(state->dev, connector)
-			if (connector->base.encoder == &encoder->base)
-				num_connectors++;
+	/* clear out existing links */
+	for_each_connector_in_state(state, connector, conn_state, i) {
+		if (!connector->encoder)
+			continue;
 
-		if (num_connectors == 0)
-			encoder->base.crtc = NULL;
+		WARN_ON(!connector->encoder->crtc);
+		connector->encoder->crtc = NULL;
+		connector->encoder = NULL;
 	}
 
-	for_each_intel_crtc(state->dev, crtc) {
-		crtc->base.enabled = crtc->base.state->enable;
-		crtc->config = to_intel_crtc_state(crtc->base.state);
+	for_each_connector_in_state(state, connector, conn_state, i) {
+		if (!connector->state->crtc)
+			continue;
+
+		if (WARN_ON(!connector->state->best_encoder))
+			continue;
+
+		connector->encoder = connector->state->best_encoder;
+		connector->encoder->crtc = connector->state->crtc;
 	}
 }
 
@@ -11559,9 +11571,16 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 
 	intel_modeset_fixup_state(state);
 
-	/* Double check state. */
 	for_each_crtc(dev, crtc) {
+		/* Double check state. */
 		WARN_ON(crtc->state->enable != intel_crtc_in_use(crtc));
+
+		if (!state->crtcs[drm_crtc_index(crtc)])
+			continue;
+
+		to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
+		if (crtc->state->active && needs_modeset(crtc->state))
+			drm_calc_timestamping_constants(crtc, &crtc->state->adjusted_mode);
 	}
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -12277,25 +12296,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 			drm_plane_helper_disable(crtc->primary);
 	}
 
-	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
-	 * to set it here already despite that we pass it down the callchain.
-	 *
-	 * Note we'll need to fix this up when we start tracking multiple
-	 * pipes; here we assume a single modeset_pipe and only track the
-	 * single crtc and mode.
-	 */
-	if (pipe_config->base.active && needs_modeset(&pipe_config->base)) {
-		modeset_crtc->mode = pipe_config->base.mode;
-
-		/*
-		 * Calculate and store various constants which
-		 * are later needed by vblank and swap-completion
-		 * timestamping. They are derived from true hwmode.
-		 */
-		drm_calc_timestamping_constants(modeset_crtc,
-						&pipe_config->base.adjusted_mode);
-	}
-
 	/* Only after disabling all output pipelines that will be changed can we
 	 * update the the output configuration. */
 	intel_modeset_update_state(state);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (8 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  8:18   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 11/42] drm/i915: Update less state during modeset Maarten Lankhorst
                   ` (32 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This kills off most of the transitional helpers and uses atomic plane updates
in the modeset path to update everything.

Getting rid of the transitional plane helpers meant that planes had to be added
in the crtc check function. On modeset a connector can be moved to a different
crtc, and this is not handled correctly otherwise.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic_plane.c |  59 ++-
 drivers/gpu/drm/i915/intel_display.c      | 655 ++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h          |   2 +-
 drivers/gpu/drm/i915/intel_sprite.c       |  80 +---
 4 files changed, 441 insertions(+), 355 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 86ba4b2c3a65..85b87e4d4b6e 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -110,32 +110,40 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
 	struct drm_crtc *crtc = state->crtc;
-	struct intel_crtc *intel_crtc;
-	struct intel_crtc_state *crtc_state;
+	struct drm_crtc_state *crtc_state;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct intel_plane_state *intel_state = to_intel_plane_state(state);
 
-	crtc = crtc ? crtc : plane->crtc;
-	intel_crtc = to_intel_crtc(crtc);
-
+	intel_state->visible = false;
 	/*
 	 * Both crtc and plane->crtc could be NULL if we're updating a
 	 * property while the plane is disabled.  We don't actually have
 	 * anything driver-specific we need to test in that case, so
 	 * just return success.
 	 */
-	if (!crtc)
+	if (!crtc) {
+		DRM_DEBUG_ATOMIC("Invisible: no crtc\n");
 		return 0;
+	}
+
+	crtc_state = state->state->crtc_states[drm_crtc_index(crtc)];
+	if (WARN_ON(!crtc_state))
+		return 0;
+
+	if (!crtc_state->enable) {
+		DRM_DEBUG_ATOMIC("Invisible: crtc off\n");
 
-	/* FIXME: temporary hack necessary while we still use the plane update
-	 * helper. */
-	if (state->state) {
-		crtc_state =
-			intel_atomic_get_crtc_state(state->state, intel_crtc);
-		if (IS_ERR(crtc_state))
-			return PTR_ERR(crtc_state);
-	} else {
-		crtc_state = intel_crtc->config;
+		/*
+		 * Probably allowed after converting to atomic. Right
+		 * now it probably means we have the state confused.
+		 */
+		I915_STATE_WARN_ON(plane->type == DRM_PLANE_TYPE_PRIMARY);
+		return 0;
+	}
+
+	if (!crtc_state->active) {
+		DRM_DEBUG_ATOMIC("Invisible: dpms off\n");
+		return 0;
 	}
 
 	/*
@@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
 	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
 	intel_state->clip.x1 = 0;
 	intel_state->clip.y1 = 0;
-	intel_state->clip.x2 =
-		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
-	intel_state->clip.y2 =
-		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
-
-	/*
-	 * Disabling a plane is always okay; we just need to update
-	 * fb tracking in a special way since cleanup_fb() won't
-	 * get called by the plane helpers.
-	 */
-	if (state->fb == NULL && plane->state->fb != NULL) {
-		/*
-		 * 'prepare' is never called when plane is being disabled, so
-		 * we need to handle frontbuffer tracking as a special case
-		 */
-		intel_crtc->atomic.disabled_planes |=
-			(1 << drm_plane_index(plane));
-	}
+	drm_crtc_get_hv_timing(&crtc_state->mode,
+			       &intel_state->clip.x2,
+			       &intel_state->clip.y2);
 
 	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
 		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 956c9964275d..9610f76a2489 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -100,14 +100,16 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
 static void chv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
+static int intel_atomic_check_crtc(struct drm_crtc *crtc,
+				   struct drm_crtc_state *crtc_state);
 static void intel_begin_crtc_commit(struct drm_crtc *crtc);
 static void intel_finish_crtc_commit(struct drm_crtc *crtc);
 static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
 	struct intel_crtc_state *crtc_state);
 static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
 			   int num_connectors);
-static void intel_crtc_enable_planes(struct drm_crtc *crtc);
-static void intel_crtc_disable_planes(struct drm_crtc *crtc);
+static void intel_pre_disable_primary(struct drm_crtc *crtc);
+static void intel_post_enable_primary(struct drm_crtc *crtc);
 
 static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
 {
@@ -2220,28 +2222,6 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
 	POSTING_READ(reg);
 }
 
-/**
- * intel_enable_primary_hw_plane - enable the primary plane on a given pipe
- * @plane:  plane to be enabled
- * @crtc: crtc for the plane
- *
- * Enable @plane on @crtc, making sure that the pipe is running first.
- */
-static void intel_enable_primary_hw_plane(struct drm_plane *plane,
-					  struct drm_crtc *crtc)
-{
-	struct drm_device *dev = plane->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	/* If the pipe isn't enabled, we can't pump pixels and may hang */
-	assert_pipe_enabled(dev_priv, intel_crtc->pipe);
-	to_intel_plane_state(plane->state)->visible = true;
-
-	dev_priv->display.update_primary_plane(crtc, plane->fb,
-					       crtc->x, crtc->y);
-}
-
 static bool need_vtd_wa(struct drm_device *dev)
 {
 #ifdef CONFIG_INTEL_IOMMU
@@ -3161,11 +3141,20 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane_state *plane_state =
+		to_intel_plane_state(crtc->primary->state);
+	bool was_visible = plane_state->visible;
 
-	if (dev_priv->display.disable_fbc)
+	/* Not supported right now by the helper, but lets be thorough. */
+	if (was_visible && !fb)
+		intel_pre_disable_primary(crtc);
+	else if (was_visible && dev_priv->display.disable_fbc)
 		dev_priv->display.disable_fbc(dev);
 
+	plane_state->visible = !!fb;
 	dev_priv->display.update_primary_plane(crtc, fb, x, y);
+	if (!was_visible && fb)
+		intel_post_enable_primary(crtc);
 
 	return 0;
 }
@@ -3192,16 +3181,17 @@ static void intel_update_primary_planes(struct drm_device *dev)
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 		drm_modeset_lock(&crtc->mutex, NULL);
-		/*
-		 * FIXME: Once we have proper support for primary planes (and
-		 * disabling them without disabling the entire crtc) allow again
-		 * a NULL crtc->primary->fb.
-		 */
-		if (intel_crtc->active && crtc->primary->fb)
+
+		if (intel_crtc->active) {
+			const struct intel_plane_state *state =
+				to_intel_plane_state(crtc->primary->state);
+
 			dev_priv->display.update_primary_plane(crtc,
-							       crtc->primary->fb,
-							       crtc->x,
-							       crtc->y);
+							state->base.fb,
+							state->src.x1 >> 16,
+							state->src.y1 >> 16);
+		}
+
 		drm_modeset_unlock(&crtc->mutex);
 	}
 }
@@ -4572,20 +4562,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
 	}
 }
 
-static void intel_enable_sprite_planes(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	enum pipe pipe = to_intel_crtc(crtc)->pipe;
-	struct drm_plane *plane;
-	struct intel_plane *intel_plane;
-
-	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
-		intel_plane = to_intel_plane(plane);
-		if (intel_plane->pipe == pipe)
-			intel_plane_restore(&intel_plane->base);
-	}
-}
-
 void hsw_enable_ips(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
@@ -4815,44 +4791,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 	hsw_disable_ips(intel_crtc);
 }
 
-static void intel_crtc_enable_planes(struct drm_crtc *crtc)
-{
-	intel_enable_primary_hw_plane(crtc->primary, crtc);
-	intel_enable_sprite_planes(crtc);
-	intel_crtc_update_cursor(crtc, true);
-
-	intel_post_enable_primary(crtc);
-}
-
-static void intel_crtc_disable_planes(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_plane *intel_plane;
-	int pipe = intel_crtc->pipe;
-
-	intel_crtc_wait_for_pending_flips(crtc);
-
-	intel_pre_disable_primary(crtc);
-
-	intel_crtc_dpms_overlay_disable(intel_crtc);
-	for_each_intel_plane(dev, intel_plane) {
-		if (intel_plane->pipe == pipe) {
-			struct drm_crtc *from = intel_plane->base.crtc;
-
-			intel_plane->disable_plane(&intel_plane->base,
-						   from ?: crtc, true);
-		}
-	}
-
-	/*
-	 * FIXME: Once we grow proper nuclear flip support out of this we need
-	 * to compute the mask of flip planes precisely. For the time being
-	 * consider this a flip to a NULL plane.
-	 */
-	intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
-}
-
 static void ironlake_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -11061,6 +10999,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.load_lut = intel_crtc_load_lut,
 	.atomic_begin = intel_begin_crtc_commit,
 	.atomic_flush = intel_finish_crtc_commit,
+	.atomic_check = intel_atomic_check_crtc,
 };
 
 /* Transitional helper to copy current connector/encoder state to
@@ -11426,16 +11365,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 	int i;
 	bool retry = true;
 
-	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
-		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
-		return -EINVAL;
-	}
-
-	if (!check_digital_port_conflicts(state)) {
-		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
-		return -EINVAL;
-	}
-
 	clear_intel_crtc_state(pipe_config);
 
 	pipe_config->cpu_transcoder =
@@ -11553,9 +11482,27 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int i;
 
 	intel_shared_dpll_commit(dev_priv);
-	drm_atomic_helper_swap_state(state->dev, state);
+
+	/*
+	 * swap crtc and connector state, plane state is already swapped in
+	 * __intel_set_mode_update_planes. Once .crtc_disable is fixed
+	 * all state should be swapped before disabling crtc's.
+	 */
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		crtc->state->state = state;
+		swap(state->crtc_states[i], crtc->state);
+		crtc->state->state = NULL;
+	}
+
+	for_each_connector_in_state(state, connector, connector_state, i) {
+		connector->state->state = state;
+		swap(state->connector_states[i], connector->state);
+		connector->state->state = NULL;
+	}
 
 	for_each_intel_encoder(dev, intel_encoder) {
 		if (!intel_encoder->base.crtc)
@@ -12163,8 +12110,8 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	    WARN_ON(pipe_config->base.active))
 		pipe_config->base.active = false;
 
-	if (!pipe_config->base.enable)
-		return pipe_config;
+	if (!pipe_config->base.active)
+		goto done;
 
 	ret = intel_modeset_pipe_config(crtc, state, pipe_config);
 	if (ret)
@@ -12182,8 +12129,8 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	 * required changes and forcing a mode set.
 	 */
 
-	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,"[modeset]");
-
+	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]");
+done:
 	ret = drm_atomic_helper_check_planes(state->dev, state);
 	if (ret)
 		return ERR_PTR(ret);
@@ -12247,6 +12194,11 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
 	struct drm_device *dev = state->dev;
 	int ret;
 
+	if (!check_digital_port_conflicts(state)) {
+		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * See if the config requires any additional preparation, e.g.
 	 * to adjust global state with pipes off.  We need to do this
@@ -12267,6 +12219,112 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
 	return 0;
 }
 
+static void __intel_set_mode_update_planes(struct drm_device *dev,
+					   struct drm_atomic_state *state)
+{
+	int i;
+	struct drm_plane_state *old_plane_state;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+
+	/*
+	 * For now only swap plane state, will be replaced with a
+	 * call to drm_atomic_helper_swap_state
+	 */
+	for_each_plane_in_state(state, plane, old_plane_state, i) {
+		struct drm_plane *plane = state->planes[i];
+
+		if (!plane)
+			continue;
+
+		plane->state->state = state;
+		swap(state->plane_states[i], plane->state);
+		plane->state->state = NULL;
+	}
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		const struct drm_crtc_helper_funcs *funcs;
+
+		funcs = crtc->helper_private;
+
+		if (!funcs || !funcs->atomic_begin)
+			continue;
+
+		/* XXX: Hack because crtc state is not swapped */
+		crtc->state->mode_changed = crtc_state->mode_changed;
+		crtc->state->active_changed = crtc_state->active_changed;
+
+		DRM_DEBUG_ATOMIC("Calling atomic_begin on crtc %i\n", i);
+		funcs->atomic_begin(crtc);
+	}
+
+	for_each_plane_in_state(state, plane, old_plane_state, i) {
+		bool visible = to_intel_plane_state(plane->state)->visible;
+		struct intel_plane *intel_plane = to_intel_plane(plane);
+		const struct drm_plane_helper_funcs *funcs =
+			plane->helper_private;
+
+		crtc = plane->state->crtc;
+
+		/* no point in disabling if already disabled */
+		if (!to_intel_plane_state(old_plane_state)->visible &&
+		    !to_intel_plane_state(old_plane_state)->hw_enabled)
+			continue;
+
+		to_intel_plane_state(plane->state)->hw_enabled = false;
+		DRM_DEBUG_ATOMIC("Plane %i is visible: %i\n", i, visible);
+
+		if (!visible)
+			funcs->atomic_update(plane, old_plane_state);
+		else if (needs_modeset(crtc->state))
+			intel_plane->disable_plane(plane, crtc, true);
+	}
+}
+
+static void __intel_set_mode_cleanup_planes(struct drm_device *dev,
+					    struct drm_atomic_state *old_state)
+{
+	int nplanes = dev->mode_config.num_total_plane;
+	int ncrtcs = dev->mode_config.num_crtc;
+	int i;
+
+	for (i = 0; i < nplanes; i++) {
+		const struct drm_plane_helper_funcs *funcs;
+		struct drm_plane *plane = old_state->planes[i];
+		struct drm_plane_state *old_plane_state;
+
+		if (!plane)
+			continue;
+
+		funcs = plane->helper_private;
+		old_plane_state = old_state->plane_states[i];
+
+		if (to_intel_plane_state(plane->state)->visible) {
+			DRM_DEBUG_ATOMIC("Plane %i is updated\n", i);
+			funcs->atomic_update(plane, old_plane_state);
+		} else
+			DRM_DEBUG_ATOMIC("Plane %i is left alone\n", i);
+	}
+
+	for (i = 0; i < ncrtcs; i++) {
+		const struct drm_crtc_helper_funcs *funcs;
+		struct drm_crtc *crtc = old_state->crtcs[i];
+
+		if (!crtc)
+			continue;
+
+		funcs = crtc->helper_private;
+
+		if (!funcs || !funcs->atomic_flush)
+			continue;
+
+		DRM_DEBUG_ATOMIC("Calling atomic_flush on crtc %i\n", i);
+		funcs->atomic_flush(crtc);
+	}
+	drm_atomic_helper_cleanup_planes(dev, old_state);
+}
+
 static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 			    struct intel_crtc_state *pipe_config)
 {
@@ -12275,7 +12333,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	struct drm_atomic_state *state = pipe_config->base.state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
-	int ret = 0;
+	int ret;
 	int i;
 
 	ret = __intel_set_mode_checks(state);
@@ -12286,14 +12344,14 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	if (ret)
 		return ret;
 
+	__intel_set_mode_update_planes(dev, state);
+
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (!needs_modeset(crtc_state))
 			continue;
 
-		intel_crtc_disable_planes(crtc);
+		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
 		dev_priv->display.crtc_disable(crtc);
-		if (!crtc_state->enable)
-			drm_plane_helper_disable(crtc->primary);
 	}
 
 	/* Only after disabling all output pipelines that will be changed can we
@@ -12305,8 +12363,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 
 	modeset_update_crtc_power_domains(state);
 
-	drm_atomic_helper_commit_planes(dev, state);
-
 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (!crtc->state->active)
@@ -12314,13 +12370,13 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 
 		update_scanline_offset(to_intel_crtc(crtc));
 
-		dev_priv->display.crtc_enable(crtc);
-		intel_crtc_enable_planes(crtc);
+		if (needs_modeset(crtc->state))
+			dev_priv->display.crtc_enable(crtc);
 	}
 
-	/* FIXME: add subpixel order */
+	__intel_set_mode_cleanup_planes(dev, state);
 
-	drm_atomic_helper_cleanup_planes(dev, state);
+	/* FIXME: add subpixel order */
 
 	drm_atomic_state_free(state);
 
@@ -12568,20 +12624,11 @@ intel_modeset_stage_output_state(struct drm_device *dev,
 	return 0;
 }
 
-static bool primary_plane_visible(struct drm_crtc *crtc)
-{
-	struct intel_plane_state *plane_state =
-		to_intel_plane_state(crtc->primary->state);
-
-	return plane_state->visible;
-}
-
 static int intel_crtc_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
 	struct drm_atomic_state *state = NULL;
 	struct intel_crtc_state *pipe_config;
-	bool primary_plane_was_visible;
 	int ret;
 
 	BUG_ON(!set);
@@ -12620,38 +12667,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 
 	intel_update_pipe_size(to_intel_crtc(set->crtc));
 
-	primary_plane_was_visible = primary_plane_visible(set->crtc);
-
 	ret = intel_set_mode_with_config(set->crtc, pipe_config);
-
-	if (ret == 0 &&
-	    pipe_config->base.enable &&
-	    pipe_config->base.planes_changed &&
-	    !needs_modeset(&pipe_config->base)) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
-
-		/*
-		 * We need to make sure the primary plane is re-enabled if it
-		 * has previously been turned off.
-		 */
-		if (ret == 0 && !primary_plane_was_visible &&
-		    primary_plane_visible(set->crtc)) {
-			WARN_ON(!intel_crtc->active);
-			intel_post_enable_primary(set->crtc);
-		}
-
-		/*
-		 * In the fastboot case this may be our only check of the
-		 * state after boot.  It would be better to only do it on
-		 * the first update, but we don't have a nice way of doing that
-		 * (and really, set_config isn't used much for high freq page
-		 * flipping, so increasing its cost here shouldn't be a big
-		 * deal).
-		 */
-		if (i915.fastboot && ret == 0)
-			intel_modeset_check_state(set->crtc->dev);
-	}
-
 	if (ret) {
 		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
 			      set->crtc->base.id, ret);
@@ -12791,6 +12807,9 @@ bool intel_wm_need_update(struct drm_plane *plane,
 	    plane->state->rotation != state->rotation)
 		return true;
 
+	if (plane->state->crtc_w != state->crtc_w)
+		return true;
+
 	return false;
 }
 
@@ -12819,6 +12838,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 	unsigned frontbuffer_bits = 0;
 	int ret = 0;
 
+	if (!to_intel_plane_state(plane->state)->visible)
+		old_obj = NULL;
+
 	if (!obj)
 		return 0;
 
@@ -12915,10 +12937,8 @@ intel_check_primary_plane(struct drm_plane *plane,
 			  struct intel_plane_state *state)
 {
 	struct drm_device *dev = plane->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = state->base.crtc;
 	struct intel_crtc *intel_crtc;
-	struct intel_crtc_state *crtc_state;
 	struct drm_framebuffer *fb = state->base.fb;
 	struct drm_rect *dest = &state->dst;
 	struct drm_rect *src = &state->src;
@@ -12926,90 +12946,46 @@ intel_check_primary_plane(struct drm_plane *plane,
 	bool can_position = false;
 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
-	int ret;
 
-	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
-	crtc_state = state->base.state ?
-		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
 	if (INTEL_INFO(dev)->gen >= 9) {
+		struct intel_crtc_state *crtc_state =
+			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
+
 		min_scale = 1;
 		max_scale = skl_max_scale(intel_crtc, crtc_state);
 		can_position = true;
 	}
 
-	ret = drm_plane_helper_check_update(plane, crtc, fb,
-					    src, dest, clip,
-					    min_scale,
-					    max_scale,
-					    can_position, true,
-					    &state->visible);
-	if (ret)
-		return ret;
-
-	if (intel_crtc->active) {
-		struct intel_plane_state *old_state =
-			to_intel_plane_state(plane->state);
-
-		intel_crtc->atomic.wait_for_flips = true;
-
-		/*
-		 * FBC does not work on some platforms for rotated
-		 * planes, so disable it when rotation is not 0 and
-		 * update it when rotation is set back to 0.
-		 *
-		 * FIXME: This is redundant with the fbc update done in
-		 * the primary plane enable function except that that
-		 * one is done too late. We eventually need to unify
-		 * this.
-		 */
-		if (state->visible &&
-		    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
-		    dev_priv->fbc.crtc == intel_crtc &&
-		    state->base.rotation != BIT(DRM_ROTATE_0)) {
-			intel_crtc->atomic.disable_fbc = true;
-		}
-
-		if (state->visible && !old_state->visible) {
-			/*
-			 * BDW signals flip done immediately if the plane
-			 * is disabled, even if the plane enable is already
-			 * armed to occur at the next vblank :(
-			 */
-			if (IS_BROADWELL(dev))
-				intel_crtc->atomic.wait_vblank = true;
-		}
-
-		intel_crtc->atomic.fb_bits |=
-			INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
-
-		intel_crtc->atomic.update_fbc = true;
-
-		if (intel_wm_need_update(plane, &state->base))
-			intel_crtc->atomic.update_wm = true;
-	}
+	return drm_plane_helper_check_update(plane, crtc, fb,
+					     src, dest, clip,
+					     min_scale, max_scale,
+					     can_position, true,
+					     &state->visible);
+}
 
-	if (INTEL_INFO(dev)->gen >= 9) {
-		ret = skl_update_scaler_users(intel_crtc, crtc_state,
-			to_intel_plane(plane), state, 0);
-		if (ret)
-			return ret;
-	}
+static void
+intel_disable_primary_plane(struct drm_plane *plane,
+			    struct drm_crtc *crtc,
+			    bool force)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	return 0;
+	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
 }
 
 static void
 intel_commit_primary_plane(struct drm_plane *plane,
-			   struct intel_plane_state *state)
+			   struct intel_plane_state *new_state)
 {
-	struct drm_crtc *crtc = state->base.crtc;
-	struct drm_framebuffer *fb = state->base.fb;
+	struct drm_crtc *crtc = new_state->base.crtc;
+	struct drm_framebuffer *fb = new_state->base.fb;
 	struct drm_device *dev = plane->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc;
-	struct drm_rect *src = &state->src;
+	struct drm_rect *src = &new_state->src;
 
 	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
@@ -13018,25 +12994,178 @@ intel_commit_primary_plane(struct drm_plane *plane,
 	crtc->x = src->x1 >> 16;
 	crtc->y = src->y1 >> 16;
 
-	if (intel_crtc->active) {
-		if (state->visible)
-			/* FIXME: kill this fastboot hack */
-			intel_update_pipe_size(intel_crtc);
+	if (!new_state->visible ||
+	    WARN_ON(new_state->visible && !crtc->state->active)) {
+		intel_disable_primary_plane(plane, crtc, false);
+	} else {
+		/* FIXME: kill this fastboot hack */
+		intel_update_pipe_size(intel_crtc);
 
-		dev_priv->display.update_primary_plane(crtc, plane->fb,
-						       crtc->x, crtc->y);
+		dev_priv->display.update_primary_plane(crtc, fb,
+						       src->x1 >> 16,
+						       src->y1 >> 16);
 	}
 }
 
-static void
-intel_disable_primary_plane(struct drm_plane *plane,
-			    struct drm_crtc *crtc,
-			    bool force)
+/* Transitional checking here, mostly for plane updates */
+static int intel_atomic_check_crtc(struct drm_crtc *crtc,
+				   struct drm_crtc_state *crtc_state)
 {
-	struct drm_device *dev = plane->dev;
+	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_atomic_state *state = crtc_state->state;
+	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_plane *plane;
+	unsigned plane_mask;
+	int idx, ret;
+	bool mode_changed = needs_modeset(crtc_state);
+	bool is_crtc_enabled = crtc_state->active;
+	bool was_crtc_enabled = crtc->state->active;
 
-	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
+	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
+		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
+		return -EINVAL;
+	}
+
+	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
+	intel_crtc->atomic.update_wm = mode_changed;
+
+	idx = crtc->base.id;
+	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
+		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
+		idx, crtc->state->active, intel_crtc->active);
+
+	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
+			 idx, was_crtc_enabled, is_crtc_enabled);
+
+	plane_mask = crtc_state->plane_mask | crtc->state->plane_mask;
+	drm_for_each_plane_mask(plane, dev, plane_mask) {
+		int i = drm_plane_index(plane);
+		struct drm_plane_state *plane_state = state->plane_states[i];
+		struct intel_plane_state *old_plane_state;
+		bool turn_off, turn_on, visible, was_visible;
+		struct drm_framebuffer *fb;
+
+		if (!plane_state) {
+			const struct drm_plane_helper_funcs *funcs;
+			int ret;
+
+			if (!mode_changed || !plane->state->fb)
+				continue;
+
+			plane_state = drm_atomic_get_plane_state(state, plane);
+			if (IS_ERR(plane_state))
+				return PTR_ERR(plane_state);
+
+			funcs = plane->helper_private;
+			ret = funcs->atomic_check(plane, plane_state);
+			if (ret)
+				return ret;
+		}
+		old_plane_state = to_intel_plane_state(plane->state);
+
+		was_visible = was_crtc_enabled && (old_plane_state->visible ||
+			      old_plane_state->hw_enabled);
+		visible = to_intel_plane_state(plane_state)->visible &&
+			      is_crtc_enabled;
+
+		if (plane->state->crtc != crtc)
+			was_visible = false;
+		if (plane_state->crtc != crtc)
+			visible = false;
+
+		if (!was_visible && !visible)
+			continue;
+
+		turn_off = was_visible && (!visible || mode_changed);
+		turn_on = visible && (!was_visible || mode_changed);
+		fb = plane_state->fb;
+
+		DRM_DEBUG_ATOMIC("Crtc %i has plane %i with fb %i\n", idx,
+			plane->base.id, fb ? fb->base.id : -1);
+		DRM_DEBUG_ATOMIC("\tvisible %i -> %i, off %i, on %i, ms %i\n",
+			was_visible, visible, turn_off, turn_on, mode_changed);
+
+		/* plane being turned off as part of modeset or changes? */
+		if (intel_wm_need_update(plane, plane_state))
+			intel_crtc->atomic.update_wm = true;
+
+		if (INTEL_INFO(dev)->gen >= 9 &&
+		    plane->base.type != DRM_PLANE_TYPE_CURSOR) {
+			ret = skl_update_scaler_users(intel_crtc, pipe_config,
+					to_intel_plane(plane),
+					to_intel_plane_state(plane_state), 0);
+			if (ret)
+				return ret;
+		}
+
+		/*
+		 * 'prepare' is never called when plane is being disabled, so
+		 * we need to handle frontbuffer tracking as a special case
+		 */
+		if (old_plane_state->base.fb && !visible)
+			intel_crtc->atomic.disabled_planes |= 1 << i;
+
+		switch (plane->base.type) {
+		case DRM_PLANE_TYPE_PRIMARY:
+			if (visible)
+				intel_crtc->atomic.fb_bits |=
+				    INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
+
+			intel_crtc->atomic.wait_for_flips = true;
+			intel_crtc->atomic.pre_disable_primary = turn_off;
+			intel_crtc->atomic.post_enable_primary = turn_on;
+
+			if (turn_off)
+				intel_crtc->atomic.disable_fbc = true;
+
+			/*
+			 * FBC does not work on some platforms for rotated
+			 * planes, so disable it when rotation is not 0 and
+			 * update it when rotation is set back to 0.
+			 *
+			 * FIXME: This is redundant with the fbc update done in
+			 * the primary plane enable function except that that
+			 * one is done too late. We eventually need to unify
+			 * this.
+			 */
+
+			if (visible &&
+			    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+			    dev_priv->fbc.crtc == intel_crtc &&
+			    plane_state->rotation != BIT(DRM_ROTATE_0))
+				intel_crtc->atomic.disable_fbc = true;
+
+			/*
+			 * BDW signals flip done immediately if the plane
+			 * is disabled, even if the plane enable is already
+			 * armed to occur at the next vblank :(
+			 */
+			if (turn_on && IS_BROADWELL(dev))
+				intel_crtc->atomic.wait_vblank = true;
+
+			intel_crtc->atomic.update_fbc = true;
+			break;
+		case DRM_PLANE_TYPE_CURSOR:
+			if (visible)
+				intel_crtc->atomic.fb_bits |=
+				    INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe);
+			break;
+		case DRM_PLANE_TYPE_OVERLAY:
+			if (visible)
+				intel_crtc->atomic.fb_bits |=
+				    INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
+
+			if (turn_off) {
+				intel_crtc->atomic.wait_vblank = true;
+				intel_crtc->atomic.update_sprite_watermarks |=
+					1 << i;
+			}
+			break;
+		}
+	}
+	return 0;
 }
 
 static void intel_begin_crtc_commit(struct drm_crtc *crtc)
@@ -13087,10 +13216,13 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 	intel_runtime_pm_get(dev_priv);
 
 	/* Perform vblank evasion around commit operation */
-	if (intel_crtc->active)
+	if (intel_crtc->active && !needs_modeset(crtc->state) &&
+	    !dev_priv->power_domains.init_power_on)
 		intel_crtc->atomic.evade =
 			intel_pipe_update_start(intel_crtc,
 						&intel_crtc->atomic.start_vbl_count);
+	else
+		intel_crtc->atomic.evade = false;
 }
 
 static void intel_finish_crtc_commit(struct drm_crtc *crtc)
@@ -13099,6 +13231,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_plane *p;
+	unsigned plane_mask;
 
 	if (intel_crtc->atomic.evade)
 		intel_pipe_update_end(intel_crtc,
@@ -13120,12 +13253,13 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
 	if (intel_crtc->atomic.post_enable_primary)
 		intel_post_enable_primary(crtc);
 
-	drm_for_each_legacy_plane(p, &dev->mode_config.plane_list)
-		if (intel_crtc->atomic.update_sprite_watermarks & drm_plane_index(p))
-			intel_update_sprite_watermarks(p, crtc, 0, 0, 0,
-						       false, false);
+	plane_mask = intel_crtc->atomic.update_sprite_watermarks;
+	drm_for_each_plane_mask(p, dev, plane_mask)
+		intel_update_sprite_watermarks(p, crtc, 0, 0, 0, false, false);
 
 	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
+	crtc->state->mode_changed = false;
+	crtc->state->active_changed = false;
 }
 
 /**
@@ -13238,13 +13372,9 @@ intel_check_cursor_plane(struct drm_plane *plane,
 	struct drm_rect *src = &state->src;
 	const struct drm_rect *clip = &state->clip;
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-	struct intel_crtc *intel_crtc;
 	unsigned stride;
 	int ret;
 
-	crtc = crtc ? crtc : plane->crtc;
-	intel_crtc = to_intel_crtc(crtc);
-
 	ret = drm_plane_helper_check_update(plane, crtc, fb,
 					    src, dest, clip,
 					    DRM_PLANE_HELPER_NO_SCALING,
@@ -13256,7 +13386,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
 
 	/* if we want to turn off the cursor ignore width and height */
 	if (!obj)
-		goto finish;
+		return 0;
 
 	/* Check for which cursor types we support */
 	if (!cursor_size_ok(dev, state->base.crtc_w, state->base.crtc_h)) {
@@ -13273,19 +13403,10 @@ intel_check_cursor_plane(struct drm_plane *plane,
 
 	if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
 		DRM_DEBUG_KMS("cursor cannot be tiled\n");
-		ret = -EINVAL;
-	}
-
-finish:
-	if (intel_crtc->active) {
-		if (plane->state->crtc_w != state->base.crtc_w)
-			intel_crtc->atomic.update_wm = true;
-
-		intel_crtc->atomic.fb_bits |=
-			INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe);
+		return -EINVAL;
 	}
 
-	return ret;
+	return 0;
 }
 
 static void
@@ -13306,20 +13427,26 @@ intel_disable_cursor_plane(struct drm_plane *plane,
 
 static void
 intel_commit_cursor_plane(struct drm_plane *plane,
-			  struct intel_plane_state *state)
+			  struct intel_plane_state *new_state)
 {
-	struct drm_crtc *crtc = state->base.crtc;
+	struct drm_crtc *crtc = new_state->base.crtc;
 	struct drm_device *dev = plane->dev;
 	struct intel_crtc *intel_crtc;
-	struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+	struct drm_i915_gem_object *obj = intel_fb_obj(new_state->base.fb);
 	uint32_t addr;
 
 	crtc = crtc ? crtc : plane->crtc;
 	intel_crtc = to_intel_crtc(crtc);
 
-	plane->fb = state->base.fb;
-	crtc->cursor_x = state->base.crtc_x;
-	crtc->cursor_y = state->base.crtc_y;
+	plane->fb = new_state->base.fb;
+	crtc->cursor_x = new_state->base.crtc_x;
+	crtc->cursor_y = new_state->base.crtc_y;
+
+	if (!new_state->visible ||
+	    WARN_ON(new_state->visible && !crtc->state->active)) {
+		intel_disable_cursor_plane(plane, crtc, false);
+		return;
+	}
 
 	if (intel_crtc->cursor_bo == obj)
 		goto update;
@@ -13333,10 +13460,9 @@ intel_commit_cursor_plane(struct drm_plane *plane,
 
 	intel_crtc->cursor_addr = addr;
 	intel_crtc->cursor_bo = obj;
-update:
 
-	if (intel_crtc->active)
-		intel_crtc_update_cursor(crtc, state->visible);
+update:
+	intel_crtc_update_cursor(crtc, new_state->visible);
 }
 
 static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
@@ -14695,7 +14821,14 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 		crtc->base.enabled = crtc->active;
 
 		plane_state = to_intel_plane_state(primary->state);
-		plane_state->visible = primary_get_hw_state(crtc);
+		plane_state->hw_enabled = plane_state->visible =
+			primary_get_hw_state(crtc);
+		if (plane_state->visible)
+			crtc->base.state->plane_mask |=
+				1 << drm_plane_index(primary);
+		else
+			crtc->base.state->plane_mask &=
+				~(1 << drm_plane_index(primary));
 
 		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
 			      crtc->base.base.id,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1e892098eea2..9ef89c91aa5c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -235,7 +235,7 @@ struct intel_plane_state {
 	struct drm_rect src;
 	struct drm_rect dst;
 	struct drm_rect clip;
-	bool visible;
+	bool visible, hw_enabled;
 
 	/*
 	 * scaler_id
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 497e7953ad4d..28291ab0993f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -759,7 +759,6 @@ intel_check_sprite_plane(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
-	struct intel_crtc_state *crtc_state;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_framebuffer *fb = state->base.fb;
 	int crtc_x, crtc_y;
@@ -771,16 +770,9 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	int hscale, vscale;
 	int max_scale, min_scale;
 	int pixel_size;
-	int ret;
-
-	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
-	crtc_state = state->base.state ?
-		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
 
-	if (!fb) {
-		state->visible = false;
-		goto finish;
-	}
+	if (!fb)
+		return 0;
 
 	/* Don't modify another pipe's plane */
 	if (intel_plane->pipe != intel_crtc->pipe) {
@@ -803,6 +795,9 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
 	if (INTEL_INFO(dev)->gen >= 9) {
+		struct intel_crtc_state *crtc_state =
+			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
+
 		min_scale = 1;
 		max_scale = skl_max_scale(intel_crtc, crtc_state);
 	}
@@ -816,7 +811,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
 	BUG_ON(vscale < 0);
 
-	state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
+	state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
 
 	crtc_x = dst->x1;
 	crtc_y = dst->y1;
@@ -921,36 +916,6 @@ intel_check_sprite_plane(struct drm_plane *plane,
 	dst->y1 = crtc_y;
 	dst->y2 = crtc_y + crtc_h;
 
-finish:
-	/*
-	 * If the sprite is completely covering the primary plane,
-	 * we can disable the primary and save power.
-	 */
-	if (intel_crtc->active) {
-		intel_crtc->atomic.fb_bits |=
-			INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
-
-		if (intel_wm_need_update(plane, &state->base))
-			intel_crtc->atomic.update_wm = true;
-
-		if (!state->visible) {
-			/*
-			 * Avoid underruns when disabling the sprite.
-			 * FIXME remove once watermark updates are done properly.
-			 */
-			intel_crtc->atomic.wait_vblank = true;
-			intel_crtc->atomic.update_sprite_watermarks |=
-				(1 << drm_plane_index(plane));
-		}
-	}
-
-	if (INTEL_INFO(dev)->gen >= 9) {
-		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
-			state, 0);
-		if (ret)
-			return ret;
-	}
-
 	return 0;
 }
 
@@ -959,7 +924,6 @@ intel_commit_sprite_plane(struct drm_plane *plane,
 			  struct intel_plane_state *state)
 {
 	struct drm_crtc *crtc = state->base.crtc;
-	struct intel_crtc *intel_crtc;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	struct drm_framebuffer *fb = state->base.fb;
 	int crtc_x, crtc_y;
@@ -967,26 +931,22 @@ intel_commit_sprite_plane(struct drm_plane *plane,
 	uint32_t src_x, src_y, src_w, src_h;
 
 	crtc = crtc ? crtc : plane->crtc;
-	intel_crtc = to_intel_crtc(crtc);
-
 	plane->fb = fb;
 
-	if (intel_crtc->active) {
-		if (state->visible) {
-			crtc_x = state->dst.x1;
-			crtc_y = state->dst.y1;
-			crtc_w = drm_rect_width(&state->dst);
-			crtc_h = drm_rect_height(&state->dst);
-			src_x = state->src.x1 >> 16;
-			src_y = state->src.y1 >> 16;
-			src_w = drm_rect_width(&state->src) >> 16;
-			src_h = drm_rect_height(&state->src) >> 16;
-			intel_plane->update_plane(plane, crtc, fb,
-						  crtc_x, crtc_y, crtc_w, crtc_h,
-						  src_x, src_y, src_w, src_h);
-		} else {
-			intel_plane->disable_plane(plane, crtc, false);
-		}
+	if (state->visible && crtc->state->active) {
+		crtc_x = state->dst.x1;
+		crtc_y = state->dst.y1;
+		crtc_w = drm_rect_width(&state->dst);
+		crtc_h = drm_rect_height(&state->dst);
+		src_x = state->src.x1 >> 16;
+		src_y = state->src.y1 >> 16;
+		src_w = drm_rect_width(&state->src) >> 16;
+		src_h = drm_rect_height(&state->src) >> 16;
+		intel_plane->update_plane(plane, crtc, fb,
+					  crtc_x, crtc_y, crtc_w, crtc_h,
+					  src_x, src_y, src_w, src_h);
+	} else {
+		intel_plane->disable_plane(plane, crtc, false);
 	}
 }
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 11/42] drm/i915: Update less state during modeset.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (9 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 10/42] drm/i915: make plane helpers fully atomic Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  8:22   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 12/42] drm/i915: move swap_state to the right place Maarten Lankhorst
                   ` (31 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

No need to repeatedly call update_watermarks, or update_fbc.
For update_watermarks once should be enough after disabling crtc's
and swapping the state.

Down to a single call to update_watermarks in .crtc_enable

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 79 +++++++++++++-----------------------
 1 file changed, 28 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9610f76a2489..a90ebc8eff6f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4719,10 +4719,6 @@ intel_post_enable_primary(struct drm_crtc *crtc)
 	 */
 	hsw_enable_ips(intel_crtc);
 
-	mutex_lock(&dev->struct_mutex);
-	intel_fbc_update(dev);
-	mutex_unlock(&dev->struct_mutex);
-
 	/*
 	 * Gen2 reports pipe underruns whenever all planes are disabled.
 	 * So don't enable underrun reporting before at least some planes
@@ -4777,11 +4773,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 	if (HAS_GMCH_DISPLAY(dev))
 		intel_set_memory_cxsr(dev_priv, false);
 
-	mutex_lock(&dev->struct_mutex);
-	if (dev_priv->fbc.crtc == intel_crtc)
-		intel_fbc_disable(dev);
-	mutex_unlock(&dev->struct_mutex);
-
 	/*
 	 * FIXME IPS should be fine as long as one plane is
 	 * enabled, but in practice it seems to have problems
@@ -5009,9 +5000,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp;
 
-	if (!intel_crtc->active)
-		return;
-
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->disable(encoder);
 
@@ -5049,18 +5037,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 			I915_WRITE(PCH_DPLL_SEL, temp);
 		}
 
-		/* disable PCH DPLL */
-		intel_disable_shared_dpll(intel_crtc);
-
 		ironlake_fdi_pll_disable(intel_crtc);
 	}
-
-	intel_crtc->active = false;
-	intel_update_watermarks(crtc);
-
-	mutex_lock(&dev->struct_mutex);
-	intel_fbc_update(dev);
-	mutex_unlock(&dev->struct_mutex);
 }
 
 static void haswell_crtc_disable(struct drm_crtc *crtc)
@@ -5071,9 +5049,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
 
-	if (!intel_crtc->active)
-		return;
-
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		intel_opregion_notify_encoder(encoder, false);
 		encoder->disable(encoder);
@@ -5109,16 +5084,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
 			encoder->post_disable(encoder);
-
-	intel_crtc->active = false;
-	intel_update_watermarks(crtc);
-
-	mutex_lock(&dev->struct_mutex);
-	intel_fbc_update(dev);
-	mutex_unlock(&dev->struct_mutex);
-
-	if (intel_crtc_to_shared_dpll(intel_crtc))
-		intel_disable_shared_dpll(intel_crtc);
 }
 
 static void i9xx_pfit_enable(struct intel_crtc *crtc)
@@ -5943,9 +5908,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 
-	if (!intel_crtc->active)
-		return;
-
 	/*
 	 * On gen2 planes are double buffered but the pipe isn't, so we must
 	 * wait for planes to fully turn off before disabling the pipe.
@@ -5979,13 +5941,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 
 	if (!IS_GEN2(dev))
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-
-	intel_crtc->active = false;
-	intel_update_watermarks(crtc);
-
-	mutex_lock(&dev->struct_mutex);
-	intel_fbc_update(dev);
-	mutex_unlock(&dev->struct_mutex);
 }
 
 /* Master function to enable/disable CRTC and corresponding power wells */
@@ -12347,11 +12302,21 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	__intel_set_mode_update_planes(dev, state);
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
 		if (!needs_modeset(crtc_state))
 			continue;
 
+		if (!crtc->state->active)
+			continue;
+
 		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
 		dev_priv->display.crtc_disable(crtc);
+
+		intel_crtc->active = false;
+
+		if (intel_crtc_to_shared_dpll(intel_crtc))
+			intel_disable_shared_dpll(intel_crtc);
 	}
 
 	/* Only after disabling all output pipelines that will be changed can we
@@ -12365,8 +12330,11 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 
 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!crtc->state->active)
+		if (!crtc->state->active) {
+			if (needs_modeset(crtc->state))
+				intel_update_watermarks(crtc);
 			continue;
+		}
 
 		update_scanline_offset(to_intel_crtc(crtc));
 
@@ -13030,6 +12998,7 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
 
 	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
 	intel_crtc->atomic.update_wm = mode_changed;
+	intel_crtc->atomic.disable_fbc = mode_changed;
 
 	idx = crtc->base.id;
 	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
@@ -13165,6 +13134,9 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
 			break;
 		}
 	}
+
+	if (mode_changed)
+		intel_crtc->atomic.update_wm = false;
 	return 0;
 }
 
@@ -13204,8 +13176,13 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 	if (intel_crtc->atomic.wait_for_flips)
 		intel_crtc_wait_for_pending_flips(crtc);
 
-	if (intel_crtc->atomic.disable_fbc)
-		intel_fbc_disable(dev);
+	if (intel_crtc->atomic.disable_fbc &&
+	    dev_priv->fbc.crtc == intel_crtc) {
+		mutex_lock(&dev->struct_mutex);
+		if (dev_priv->fbc.crtc == intel_crtc)
+			intel_fbc_disable(dev);
+		mutex_unlock(&dev->struct_mutex);
+	}
 
 	if (intel_crtc->atomic.pre_disable_primary)
 		intel_pre_disable_primary(crtc);
@@ -13244,15 +13221,15 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
 
 	intel_frontbuffer_flip(dev, intel_crtc->atomic.fb_bits);
 
+	if (intel_crtc->atomic.post_enable_primary)
+		intel_post_enable_primary(crtc);
+
 	if (intel_crtc->atomic.update_fbc) {
 		mutex_lock(&dev->struct_mutex);
 		intel_fbc_update(dev);
 		mutex_unlock(&dev->struct_mutex);
 	}
 
-	if (intel_crtc->atomic.post_enable_primary)
-		intel_post_enable_primary(crtc);
-
 	plane_mask = intel_crtc->atomic.update_sprite_watermarks;
 	drm_for_each_plane_mask(p, dev, plane_mask)
 		intel_update_sprite_watermarks(p, crtc, 0, 0, 0, false, false);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 12/42] drm/i915: move swap_state to the right place
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (10 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 11/42] drm/i915: Update less state during modeset Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  8:25   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 13/42] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config() Maarten Lankhorst
                   ` (30 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Done as a separate commit to allow better bisecting.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 50 +++++-------------------------------
 1 file changed, 7 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a90ebc8eff6f..253d9cd4154a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11437,28 +11437,9 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
-	struct drm_connector_state *connector_state;
-	int i;
 
 	intel_shared_dpll_commit(dev_priv);
 
-	/*
-	 * swap crtc and connector state, plane state is already swapped in
-	 * __intel_set_mode_update_planes. Once .crtc_disable is fixed
-	 * all state should be swapped before disabling crtc's.
-	 */
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		crtc->state->state = state;
-		swap(state->crtc_states[i], crtc->state);
-		crtc->state->state = NULL;
-	}
-
-	for_each_connector_in_state(state, connector, connector_state, i) {
-		connector->state->state = state;
-		swap(state->connector_states[i], connector->state);
-		connector->state->state = NULL;
-	}
-
 	for_each_intel_encoder(dev, intel_encoder) {
 		if (!intel_encoder->base.crtc)
 			continue;
@@ -12183,21 +12164,6 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 
-	/*
-	 * For now only swap plane state, will be replaced with a
-	 * call to drm_atomic_helper_swap_state
-	 */
-	for_each_plane_in_state(state, plane, old_plane_state, i) {
-		struct drm_plane *plane = state->planes[i];
-
-		if (!plane)
-			continue;
-
-		plane->state->state = state;
-		swap(state->plane_states[i], plane->state);
-		plane->state->state = NULL;
-	}
-
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		const struct drm_crtc_helper_funcs *funcs;
 
@@ -12206,10 +12172,6 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
 		if (!funcs || !funcs->atomic_begin)
 			continue;
 
-		/* XXX: Hack because crtc state is not swapped */
-		crtc->state->mode_changed = crtc_state->mode_changed;
-		crtc->state->active_changed = crtc_state->active_changed;
-
 		DRM_DEBUG_ATOMIC("Calling atomic_begin on crtc %i\n", i);
 		funcs->atomic_begin(crtc);
 	}
@@ -12287,7 +12249,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_atomic_state *state = pipe_config->base.state;
 	struct drm_crtc *crtc;
-	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_state *old_crtc_state;
 	int ret;
 	int i;
 
@@ -12299,15 +12261,17 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	if (ret)
 		return ret;
 
+	drm_atomic_helper_swap_state(dev, state);
+
 	__intel_set_mode_update_planes(dev, state);
 
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-		if (!needs_modeset(crtc_state))
+		if (!needs_modeset(crtc->state))
 			continue;
 
-		if (!crtc->state->active)
+		if (!old_crtc_state->active)
 			continue;
 
 		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
@@ -12329,7 +12293,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
 	modeset_update_crtc_power_domains(state);
 
 	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
 		if (!crtc->state->active) {
 			if (needs_modeset(crtc->state))
 				intel_update_watermarks(crtc);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 13/42] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (11 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 12/42] drm/i915: move swap_state to the right place Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 14/42] drm/i915: Make __intel_set_mode() take only atomic state as argument Maarten Lankhorst
                   ` (29 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

A follow up patch will make intel_modeset_compute_config() deal with
multiple crtcs, so move crtc specific stuff into the lower level crtc
specific function.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 37 ++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 253d9cd4154a..045910b36bbf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11320,6 +11320,15 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 	int i;
 	bool retry = true;
 
+	/*
+	 * XXX: Add all connectors to make the crtc state match the encoders.
+	 */
+	if (!needs_modeset(&pipe_config->base)) {
+		ret = drm_atomic_add_affected_connectors(state, crtc);
+		if (ret)
+			return ret;
+	}
+
 	clear_intel_crtc_state(pipe_config);
 
 	pipe_config->cpu_transcoder =
@@ -11411,6 +11420,18 @@ encoder_retry:
 	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
 		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
+	/* Check if we need to force a modeset */
+	if (pipe_config->has_audio !=
+	    to_intel_crtc_state(crtc->state)->has_audio)
+		pipe_config->base.mode_changed = true;
+
+	/*
+	 * Note we have an issue here with infoframes: current code
+	 * only updates them on the full mode set path per hw
+	 * requirements.  So here we should be checking for any
+	 * required changes and forcing a mode set.
+	 */
+
 	return 0;
 fail:
 	return ret;
@@ -12024,10 +12045,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	struct intel_crtc_state *pipe_config;
 	int ret = 0;
 
-	ret = drm_atomic_add_affected_connectors(state, crtc);
-	if (ret)
-		return ERR_PTR(ret);
-
 	ret = drm_atomic_helper_check_modeset(state->dev, state);
 	if (ret)
 		return ERR_PTR(ret);
@@ -12053,18 +12070,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	if (ret)
 		return ERR_PTR(ret);
 
-	/* Check things that can only be changed through modeset */
-	if (pipe_config->has_audio !=
-	    to_intel_crtc(crtc)->config->has_audio)
-		pipe_config->base.mode_changed = true;
-
-	/*
-	 * Note we have an issue here with infoframes: current code
-	 * only updates them on the full mode set path per hw
-	 * requirements.  So here we should be checking for any
-	 * required changes and forcing a mode set.
-	 */
-
 	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]");
 done:
 	ret = drm_atomic_helper_check_planes(state->dev, state);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 14/42] drm/i915: Make __intel_set_mode() take only atomic state as argument
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (12 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 13/42] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config() Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 15/42] drm/i915: Use hwmode for vblanks Maarten Lankhorst
                   ` (28 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

The last remaining portion that required the modeset_crtc argument is
converted to deal with all crtcs in the state that need_modeset(). By
doing that, __intel_set_mode() is generic enough, behaving like a commit
function for the atomic state.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 045910b36bbf..72262e73013d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11510,7 +11510,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 		} else
 			connector->dpms = DRM_MODE_DPMS_OFF;
 	}
-
 }
 
 static bool intel_fuzzy_clock_check(int clock1, int clock2)
@@ -12247,12 +12246,10 @@ static void __intel_set_mode_cleanup_planes(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, old_state);
 }
 
-static int __intel_set_mode(struct drm_crtc *modeset_crtc,
-			    struct intel_crtc_state *pipe_config)
+static int __intel_set_mode(struct drm_atomic_state *state)
 {
-	struct drm_device *dev = modeset_crtc->dev;
+	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_atomic_state *state = pipe_config->base.state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
 	int ret;
@@ -12325,7 +12322,7 @@ static int intel_set_mode_with_config(struct drm_crtc *crtc,
 {
 	int ret;
 
-	ret = __intel_set_mode(crtc, pipe_config);
+	ret = __intel_set_mode(pipe_config->base.state);
 
 	if (ret == 0)
 		intel_modeset_check_state(crtc->dev);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 15/42] drm/i915: Use hwmode for vblanks.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (13 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 14/42] drm/i915: Make __intel_set_mode() take only atomic state as argument Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c Maarten Lankhorst
                   ` (27 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Must start somewhere to get rid of crtc->config.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c      | 13 ++++++-------
 drivers/gpu/drm/i915/intel_display.c |  6 ++++++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index a6816503a080..ace6373be831 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -564,8 +564,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 	u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
 	struct intel_crtc *intel_crtc =
 		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-	const struct drm_display_mode *mode =
-		&intel_crtc->config->base.adjusted_mode;
+	const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
 
 	htotal = mode->crtc_htotal;
 	hsync_start = mode->crtc_hsync_start;
@@ -620,7 +619,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
+	const struct drm_display_mode *mode = &crtc->base.hwmode;
 	enum pipe pipe = crtc->pipe;
 	int position, vtotal;
 
@@ -647,14 +646,14 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	const struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
+	const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
 	int position;
 	int vbl_start, vbl_end, hsync_start, htotal, vtotal;
 	bool in_vbl = true;
 	int ret = 0;
 	unsigned long irqflags;
 
-	if (!intel_crtc->active) {
+	if (WARN_ON(!mode->crtc_clock)) {
 		DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
 				 "pipe %c\n", pipe_name(pipe));
 		return 0;
@@ -796,7 +795,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
 		return -EINVAL;
 	}
 
-	if (!crtc->state->active) {
+	if (!crtc->hwmode.crtc_clock) {
 		DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
 		return -EBUSY;
 	}
@@ -805,7 +804,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
 	return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
 						     vblank_time, flags,
 						     crtc,
-						     &to_intel_crtc(crtc)->config->base.adjusted_mode);
+						     &crtc->hwmode);
 }
 
 static bool intel_hpd_irq_event(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 72262e73013d..9bf31371ed49 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11485,6 +11485,12 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 		to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
 		if (crtc->state->active && needs_modeset(crtc->state))
 			drm_calc_timestamping_constants(crtc, &crtc->state->adjusted_mode);
+
+		if (crtc->state->active)
+			drm_mode_copy(&crtc->hwmode,
+				      &crtc->state->adjusted_mode);
+		else
+			crtc->hwmode.crtc_clock = 0;
 	}
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (14 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 15/42] drm/i915: Use hwmode for vblanks Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  8:51   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c Maarten Lankhorst
                   ` (26 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Another abuser gone.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 42 ++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index acd4d2c7613a..5439ff9f7e6b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2755,13 +2755,16 @@ static int i915_display_info(struct seq_file *m, void *unused)
 	seq_printf(m, "---------\n");
 	for_each_intel_crtc(dev, crtc) {
 		bool active;
+		struct intel_crtc_state *pipe_config;
 		int x, y;
 
+		pipe_config = to_intel_crtc_state(crtc->base.state);
+
 		seq_printf(m, "CRTC %d: pipe: %c, active=%s (size=%dx%d)\n",
 			   crtc->base.base.id, pipe_name(crtc->pipe),
-			   yesno(crtc->active), crtc->config->pipe_src_w,
-			   crtc->config->pipe_src_h);
-		if (crtc->active) {
+			   yesno(pipe_config->base.active),
+			   pipe_config->pipe_src_w, pipe_config->pipe_src_h);
+		if (pipe_config->base.active) {
 			intel_crtc_info(m, crtc);
 
 			active = cursor_position(dev, crtc->pipe, &x, &y);
@@ -3002,7 +3005,7 @@ static void drrs_status_per_crtc(struct seq_file *m,
 
 	seq_puts(m, "\n\n");
 
-	if (intel_crtc->config->has_drrs) {
+	if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
 		struct intel_panel *panel;
 
 		mutex_lock(&drrs->mutex);
@@ -3054,7 +3057,7 @@ static int i915_drrs_status(struct seq_file *m, void *unused)
 	for_each_intel_crtc(dev, intel_crtc) {
 		drm_modeset_lock(&intel_crtc->base.mutex, NULL);
 
-		if (intel_crtc->active) {
+		if (intel_crtc->base.state->active) {
 			active_crtc_cnt++;
 			seq_printf(m, "\nCRTC %d:  ", active_crtc_cnt);
 
@@ -3596,22 +3599,27 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc =
 		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+	struct intel_crtc_state *pipe_config;
 
 	drm_modeset_lock_all(dev);
+	pipe_config = to_intel_crtc_state(crtc->base.state);
+
 	/*
 	 * If we use the eDP transcoder we need to make sure that we don't
 	 * bypass the pfit, since otherwise the pipe CRC source won't work. Only
 	 * relevant on hsw with pipe A when using the always-on power well
 	 * routing.
 	 */
-	if (crtc->config->cpu_transcoder == TRANSCODER_EDP &&
-	    !crtc->config->pch_pfit.enabled) {
-		bool active = crtc->active;
+	if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
+	    !pipe_config->pch_pfit.enabled) {
+		bool active = pipe_config->base.active;
 
-		if (active)
+		if (active) {
 			intel_crtc_control(&crtc->base, false);
+			pipe_config = to_intel_crtc_state(crtc->base.state);
+		}
 
-		crtc->config->pch_pfit.force_thru = true;
+		pipe_config->pch_pfit.force_thru = true;
 
 		intel_display_power_get(dev_priv,
 					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
@@ -3627,6 +3635,7 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc =
 		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+	struct intel_crtc_state *pipe_config;
 
 	drm_modeset_lock_all(dev);
 	/*
@@ -3635,13 +3644,16 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
 	 * relevant on hsw with pipe A when using the always-on power well
 	 * routing.
 	 */
-	if (crtc->config->pch_pfit.force_thru) {
-		bool active = crtc->active;
+	pipe_config = to_intel_crtc_state(crtc->base.state);
+	if (pipe_config->pch_pfit.force_thru) {
+		bool active = pipe_config->base.active;
 
-		if (active)
+		if (active) {
 			intel_crtc_control(&crtc->base, false);
+			pipe_config = to_intel_crtc_state(crtc->base.state);
+		}
 
-		crtc->config->pch_pfit.force_thru = false;
+		pipe_config->pch_pfit.force_thru = false;
 
 		intel_display_power_put(dev_priv,
 					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
@@ -3763,7 +3775,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
 				 pipe_name(pipe));
 
 		drm_modeset_lock(&crtc->base.mutex, NULL);
-		if (crtc->active)
+		if (crtc->base.state->active)
 			intel_wait_for_vblank(dev, pipe);
 		drm_modeset_unlock(&crtc->base.mutex);
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (15 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  8:54   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 18/42] drm/i915: Remove use of crtc->config from intel_audio.c Maarten Lankhorst
                   ` (25 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 96 ++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a70b2d1fc844..869b587f463d 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -678,7 +678,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
 		int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
 		int clock;
 
-		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		adjusted_mode = &crtc->state->adjusted_mode;
 		clock = adjusted_mode->crtc_clock;
 
 		/* Display SR */
@@ -747,10 +747,10 @@ static bool g4x_compute_wm0(struct drm_device *dev,
 		return false;
 	}
 
-	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	adjusted_mode = &crtc->state->adjusted_mode;
 	clock = adjusted_mode->crtc_clock;
 	htotal = adjusted_mode->crtc_htotal;
-	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+	hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
 	pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
 
 	/* Use the small buffer method to calculate plane watermark */
@@ -834,10 +834,10 @@ static bool g4x_compute_srwm(struct drm_device *dev,
 	}
 
 	crtc = intel_get_crtc_for_plane(dev, plane);
-	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	adjusted_mode = &crtc->state->adjusted_mode;
 	clock = adjusted_mode->crtc_clock;
 	htotal = adjusted_mode->crtc_htotal;
-	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+	hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
 	pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
 
 	line_time_us = max(htotal * 1000 / clock, 1);
@@ -934,16 +934,11 @@ static uint8_t vlv_compute_drain_latency(struct drm_crtc *crtc,
 					 struct drm_plane *plane)
 {
 	struct drm_device *dev = crtc->dev;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int entries, prec_mult, drain_latency, pixel_size;
-	int clock = intel_crtc->config->base.adjusted_mode.crtc_clock;
+	int clock = crtc->state->adjusted_mode.crtc_clock;
 	const int high_precision = IS_CHERRYVIEW(dev) ? 16 : 64;
 
-	/*
-	 * FIXME the plane might have an fb
-	 * but be invisible (eg. due to clipping)
-	 */
-	if (!intel_crtc->active || !plane->state->fb)
+	if (!crtc->state->active || !to_intel_plane_state(plane->state)->visible)
 		return 0;
 
 	if (WARN(clock == 0, "Pixel clock is zero!\n"))
@@ -981,11 +976,11 @@ static int vlv_compute_wm(struct intel_crtc *crtc,
 	 * FIXME the plane might have an fb
 	 * but be invisible (eg. due to clipping)
 	 */
-	if (!crtc->active || !plane->base.state->fb)
+	if (!crtc->base.state->active || !plane->base.state->fb)
 		return 0;
 
 	pixel_size = drm_format_plane_cpp(plane->base.state->fb->pixel_format, 0);
-	clock = crtc->config->base.adjusted_mode.crtc_clock;
+	clock = crtc->base.state->adjusted_mode.crtc_clock;
 
 	entries = DIV_ROUND_UP(clock, 1000) * pixel_size;
 
@@ -1217,10 +1212,10 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
 		const struct drm_display_mode *adjusted_mode =
-			&to_intel_crtc(crtc)->config->base.adjusted_mode;
+			&crtc->state->adjusted_mode;
 		int clock = adjusted_mode->crtc_clock;
 		int htotal = adjusted_mode->crtc_htotal;
-		int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
+		int hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
 		int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
 		unsigned long line_time_us;
 		int entries;
@@ -1304,7 +1299,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 		if (IS_GEN2(dev))
 			cpp = 4;
 
-		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		adjusted_mode = &crtc->state->adjusted_mode;
 		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
@@ -1326,7 +1321,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 		if (IS_GEN2(dev))
 			cpp = 4;
 
-		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+		adjusted_mode = &crtc->state->adjusted_mode;
 		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
@@ -1365,10 +1360,10 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
 		const struct drm_display_mode *adjusted_mode =
-			&to_intel_crtc(enabled)->config->base.adjusted_mode;
+			&enabled->state->adjusted_mode;
 		int clock = adjusted_mode->crtc_clock;
 		int htotal = adjusted_mode->crtc_htotal;
-		int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w;
+		int hdisplay = to_intel_crtc_state(enabled->state)->pipe_src_w;
 		int pixel_size = enabled->primary->state->fb->bits_per_pixel / 8;
 		unsigned long line_time_us;
 		int entries;
@@ -1421,7 +1416,7 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
 	if (crtc == NULL)
 		return;
 
-	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
+	adjusted_mode = &crtc->state->adjusted_mode;
 	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 				       &i845_wm_info,
 				       dev_priv->display.get_fifo_size(dev, 0),
@@ -1437,20 +1432,20 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
 static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
 				    struct drm_crtc *crtc)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	uint32_t pixel_rate;
-
-	pixel_rate = intel_crtc->config->base.adjusted_mode.crtc_clock;
+	uint32_t pixel_rate =
+		crtc->state->adjusted_mode.crtc_clock;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 
 	/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
 	 * adjust the pixel_rate here. */
 
-	if (intel_crtc->config->pch_pfit.enabled) {
+	if (pipe_config->pch_pfit.enabled) {
 		uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
-		uint32_t pfit_size = intel_crtc->config->pch_pfit.size;
+		uint32_t pfit_size = pipe_config->pch_pfit.size;
 
-		pipe_w = intel_crtc->config->pipe_src_w;
-		pipe_h = intel_crtc->config->pipe_src_h;
+		pipe_w = pipe_config->pipe_src_w;
+		pipe_h = pipe_config->pipe_src_h;
 		pfit_w = (pfit_size >> 16) & 0xFFFF;
 		pfit_h = pfit_size & 0xFFFF;
 		if (pipe_w < pfit_w)
@@ -1802,11 +1797,10 @@ static uint32_t
 hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
+	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
 	u32 linetime, ips_linetime;
 
-	if (!intel_crtc->active)
+	if (!crtc->state->active)
 		return 0;
 
 	/* The WM are computed with base on how long it takes to fill a single
@@ -2061,11 +2055,11 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 	enum pipe pipe = intel_crtc->pipe;
 	struct drm_plane *plane;
 
-	if (!intel_crtc->active)
+	if (!crtc->state->active)
 		return;
 
 	p->active = true;
-	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
+	p->pipe_htotal = crtc->state->adjusted_mode.crtc_htotal;
 	p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
 
 	if (crtc->primary->state->fb) {
@@ -2084,8 +2078,8 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
 		p->cur.enabled = false;
 		p->cur.bytes_per_pixel = 0;
 	}
-	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
-	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
+	p->pri.horiz_pixels = to_intel_crtc_state(crtc->state)->pipe_src_w;
+	p->cur.horiz_pixels = crtc->cursor->state->crtc_w;
 
 	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
 		struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -2589,7 +2583,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
 
 	nth_active_pipe = 0;
 	for_each_crtc(dev, crtc) {
-		if (!to_intel_crtc(crtc)->active)
+		if (!crtc->state->active)
 			continue;
 
 		if (crtc == for_crtc)
@@ -2862,7 +2856,7 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
 	struct drm_plane *plane;
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		config->num_pipes_active += to_intel_crtc(crtc)->active;
+		config->num_pipes_active += crtc->state->active;
 
 	/* FIXME: I don't think we need those two global parameters on SKL */
 	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
@@ -2881,12 +2875,14 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
 	enum pipe pipe = intel_crtc->pipe;
 	struct drm_plane *plane;
 	struct drm_framebuffer *fb;
+	struct intel_crtc_state *pipe_config;
 	int i = 1; /* Index for sprite planes start */
 
-	p->active = intel_crtc->active;
+	pipe_config = to_intel_crtc_state(crtc->state);
+	p->active = crtc->state->active;
 	if (p->active) {
-		p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
-		p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
+		p->pipe_htotal = pipe_config->base.adjusted_mode.crtc_htotal;
+		p->pixel_rate = skl_pipe_pixel_rate(pipe_config);
 
 		fb = crtc->primary->state->fb;
 		/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
@@ -2903,8 +2899,8 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
 			p->plane[0].y_bytes_per_pixel = 0;
 			p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
 		}
-		p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
-		p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
+		p->plane[0].horiz_pixels = pipe_config->pipe_src_w;
+		p->plane[0].vert_pixels = pipe_config->pipe_src_h;
 		p->plane[0].rotation = crtc->primary->state->rotation;
 
 		fb = crtc->cursor->state->fb;
@@ -3042,7 +3038,7 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
 static uint32_t
 skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
 {
-	if (!to_intel_crtc(crtc)->active)
+	if (!crtc->state->active)
 		return 0;
 
 	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
@@ -3266,7 +3262,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	 * re-allocate the freed space without this pipe fetching from it.
 	 */
 	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
+		if (!crtc->base.state->active)
 			continue;
 
 		pipe = crtc->pipe;
@@ -3289,7 +3285,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	 * space is not used anymore.
 	 */
 	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
+		if (!crtc->base.state->active)
 			continue;
 
 		pipe = crtc->pipe;
@@ -3312,7 +3308,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
 	 * will just get more DDB space with the correct WM values.
 	 */
 	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
+		if (!crtc->base.state->active)
 			continue;
 
 		pipe = crtc->pipe;
@@ -3378,7 +3374,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
 		if (this_crtc->pipe == intel_crtc->pipe)
 			continue;
 
-		if (!intel_crtc->active)
+		if (!intel_crtc->base.state->active)
 			continue;
 
 		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
@@ -3603,7 +3599,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
 	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
 
-	if (!intel_crtc->active)
+	if (!crtc->state->active)
 		return;
 
 	hw->dirty[pipe] = true;
@@ -3658,7 +3654,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
 
-	active->pipe_enabled = intel_crtc->active;
+	active->pipe_enabled = crtc->state->active;
 
 	if (active->pipe_enabled) {
 		u32 tmp = hw->wm_pipe[pipe];
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 18/42] drm/i915: Remove use of crtc->config from intel_audio.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (16 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 19/42] drm/i915: remove use of crtc->config from intel_fbc.c Maarten Lankhorst
                   ` (24 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_audio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index c4312177b0ee..dd74fd3157ee 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -395,7 +395,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
-	struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
+	struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
 	struct drm_connector *connector;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 19/42] drm/i915: remove use of crtc->config from intel_fbc.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (17 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 18/42] drm/i915: Remove use of crtc->config from intel_audio.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-11 14:24 ` [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c Maarten Lankhorst
                   ` (23 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_fbc.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 6abb83432d4d..098461ce1fe4 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -503,6 +503,7 @@ void intel_fbc_update(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = NULL;
 	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *pipe_config;
 	struct drm_framebuffer *fb;
 	struct drm_i915_gem_object *obj;
 	const struct drm_display_mode *adjusted_mode;
@@ -543,7 +544,8 @@ void intel_fbc_update(struct drm_device *dev)
 	intel_crtc = to_intel_crtc(crtc);
 	fb = crtc->primary->fb;
 	obj = intel_fb_obj(fb);
-	adjusted_mode = &intel_crtc->config->base.adjusted_mode;
+	pipe_config = to_intel_crtc_state(crtc->state);
+	adjusted_mode = &pipe_config->base.adjusted_mode;
 
 	if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 	    (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
@@ -563,8 +565,8 @@ void intel_fbc_update(struct drm_device *dev)
 		max_width = 2048;
 		max_height = 1536;
 	}
-	if (intel_crtc->config->pipe_src_w > max_width ||
-	    intel_crtc->config->pipe_src_h > max_height) {
+	if (pipe_config->pipe_src_w > max_width ||
+	    pipe_config->pipe_src_h > max_height) {
 		if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE))
 			DRM_DEBUG_KMS("mode too large for compression, disabling\n");
 		goto out_disable;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (18 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 19/42] drm/i915: remove use of crtc->config from intel_fbc.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  9:03   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c Maarten Lankhorst
                   ` (22 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c | 10 +++-------
 drivers/gpu/drm/i915/intel_sprite.c |  4 ++--
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 7ed8033aae60..ace6aeeb1359 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -176,7 +176,7 @@ int intel_atomic_commit(struct drm_device *dev,
 			continue;
 		}
 
-		to_intel_crtc(crtc)->config->scaler_state =
+		to_intel_crtc_state(crtc->state)->scaler_state =
 			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
 
 		if (INTEL_INFO(dev)->gen >= 9)
@@ -241,14 +241,10 @@ intel_connector_atomic_get_property(struct drm_connector *connector,
 struct drm_crtc_state *
 intel_crtc_duplicate_state(struct drm_crtc *crtc)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_crtc_state *crtc_state;
 
-	if (WARN_ON(!intel_crtc->config))
-		crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
-	else
-		crtc_state = kmemdup(intel_crtc->config,
-				     sizeof(*intel_crtc->config), GFP_KERNEL);
+	crtc_state = kmemdup(crtc->state,
+			     sizeof(*crtc_state), GFP_KERNEL);
 
 	if (!crtc_state)
 		return NULL;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 28291ab0993f..dfb6656ef544 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -81,7 +81,7 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
 bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
 {
 	struct drm_device *dev = crtc->base.dev;
-	const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
+	const struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
 	enum pipe pipe = crtc->pipe;
 	long timeout = msecs_to_jiffies_timeout(1);
 	int scanline, min, max, vblank_start;
@@ -187,7 +187,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
 	u32 tile_height, plane_offset, plane_size;
 	unsigned int rotation;
 	int x_offset, y_offset;
-	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
+	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->state);
 	int scaler_id;
 
 	plane_ctl = PLANE_CTL_ENABLE |
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (19 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  9:06   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it Maarten Lankhorst
                   ` (21 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_overlay.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 5fd2d5ac02e2..fa0ff6974dcc 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -857,13 +857,13 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
 }
 
 static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
-					  struct intel_crtc *crtc)
+					  struct drm_crtc *crtc)
 {
-	if (!crtc->active)
+	if (!crtc->state->active)
 		return -EINVAL;
 
 	/* can't use the overlay with double wide pipe */
-	if (crtc->config->double_wide)
+	if (to_intel_crtc_state(crtc->state)->double_wide)
 		return -EINVAL;
 
 	return 0;
@@ -1127,7 +1127,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
 		if (ret != 0)
 			goto out_unlock;
 
-		ret = check_overlay_possible_on_crtc(overlay, crtc);
+		ret = check_overlay_possible_on_crtc(overlay, &crtc->base);
 		if (ret != 0)
 			goto out_unlock;
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (20 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  9:13   ` Daniel Vetter
  2015-05-11 14:24 ` [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable Maarten Lankhorst
                   ` (20 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   3 +-
 drivers/gpu/drm/i915/intel_display.c | 207 ++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_dp.c      |   2 +
 drivers/gpu/drm/i915/intel_drv.h     |  10 +-
 drivers/gpu/drm/i915/intel_panel.c   |   3 +-
 drivers/gpu/drm/i915/intel_tv.c      |   2 +-
 6 files changed, 120 insertions(+), 107 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a6d3ab94ec15..3ba15df4c93a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -573,7 +573,8 @@ struct drm_i915_display_funcs {
 	int (*crtc_compute_clock)(struct intel_crtc *crtc,
 				  struct intel_crtc_state *crtc_state);
 	void (*crtc_enable)(struct drm_crtc *crtc);
-	void (*crtc_disable)(struct drm_crtc *crtc);
+	void (*crtc_disable)(struct drm_crtc *crtc,
+			     struct intel_crtc_state *old_state);
 	void (*audio_codec_enable)(struct drm_connector *connector,
 				   struct intel_encoder *encoder,
 				   struct drm_display_mode *mode);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9bf31371ed49..311a4b44bebe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -982,8 +982,6 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
 
 bool intel_crtc_active(struct drm_crtc *crtc)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
 	/* Be paranoid as we can arrive here with only partial
 	 * state retrieved from the hardware during setup.
 	 *
@@ -997,17 +995,8 @@ bool intel_crtc_active(struct drm_crtc *crtc)
 	 * crtc->state->active once we have proper CRTC states wired up
 	 * for atomic.
 	 */
-	return intel_crtc->active && crtc->primary->state->fb &&
-		intel_crtc->config->base.adjusted_mode.crtc_clock;
-}
-
-enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
-					     enum pipe pipe)
-{
-	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	return intel_crtc->config->cpu_transcoder;
+	return crtc->state->active && crtc->primary->state->fb &&
+		crtc->state->adjusted_mode.crtc_clock;
 }
 
 static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
@@ -1029,9 +1018,10 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
 	return line1 == line2;
 }
 
-/*
+/**
  * intel_wait_for_pipe_off - wait for pipe to turn off
  * @crtc: crtc whose pipe to wait for
+ * @old_state: currently applied config
  *
  * 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
@@ -1045,11 +1035,12 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
  *   ends up stopping at the start of the next frame).
  *
  */
-static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
+static void intel_wait_for_pipe_off(struct intel_crtc *crtc,
+				    struct intel_crtc_state *old_state)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 
 	if (INTEL_INFO(dev)->gen >= 4) {
@@ -1180,13 +1171,12 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 }
 
 static void assert_fdi_tx(struct drm_i915_private *dev_priv,
+			  enum transcoder cpu_transcoder,
 			  enum pipe pipe, bool state)
 {
 	int reg;
 	u32 val;
 	bool cur_state;
-	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-								      pipe);
 
 	if (HAS_DDI(dev_priv->dev)) {
 		/* DDI does not have a specific FDI_TX register */
@@ -1202,8 +1192,8 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
 	     "FDI TX state assertion failure (expected %s, current %s)\n",
 	     state_string(state), state_string(cur_state));
 }
-#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true)
-#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false)
+#define assert_fdi_tx_enabled(d, c, p) assert_fdi_tx(d, c, p, true)
+#define assert_fdi_tx_disabled(d, c, p) assert_fdi_tx(d, c, p, false)
 
 static void assert_fdi_rx(struct drm_i915_private *dev_priv,
 			  enum pipe pipe, bool state)
@@ -1317,13 +1307,12 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
 #define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
 
 void assert_pipe(struct drm_i915_private *dev_priv,
+		 enum transcoder cpu_transcoder,
 		 enum pipe pipe, bool state)
 {
 	int reg;
 	u32 val;
 	bool cur_state;
-	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-								      pipe);
 
 	/* if we need the pipe quirk it must be always on */
 	if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
@@ -1615,7 +1604,7 @@ static void vlv_enable_pll(struct intel_crtc *crtc,
 	int reg = DPLL(crtc->pipe);
 	u32 dpll = pipe_config->dpll_hw_state.dpll;
 
-	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
 
 	/* No really, not for ILK+ */
 	BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
@@ -1655,7 +1644,7 @@ static void chv_enable_pll(struct intel_crtc *crtc,
 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
 	u32 tmp;
 
-	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
 
 	BUG_ON(!IS_CHERRYVIEW(dev_priv->dev));
 
@@ -1697,14 +1686,14 @@ static int intel_num_dvo_pipes(struct drm_device *dev)
 	return count;
 }
 
-static void i9xx_enable_pll(struct intel_crtc *crtc)
+static void i9xx_enable_pll(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;
 	int reg = DPLL(crtc->pipe);
 	u32 dpll = crtc->config->dpll_hw_state.dpll;
 
-	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
 
 	/* No really, not for ILK+ */
 	BUG_ON(INTEL_INFO(dev)->gen >= 5);
@@ -1757,13 +1746,14 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
 /**
  * i9xx_disable_pll - disable a PLL
  * @dev_priv: i915 private structure
- * @pipe: pipe PLL to disable
+ * @pipe_config: currently applied config
  *
  * Disable the PLL for @pipe, making sure the pipe is off first.
  *
  * Note!  This is for pre-ILK only.
  */
-static void i9xx_disable_pll(struct intel_crtc *crtc)
+static void i9xx_disable_pll(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;
@@ -1785,7 +1775,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc)
 		return;
 
 	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, pipe);
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, pipe);
 
 	I915_WRITE(DPLL(pipe), 0);
 	POSTING_READ(DPLL(pipe));
@@ -1795,9 +1785,6 @@ static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
 	u32 val = 0;
 
-	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, pipe);
-
 	/*
 	 * Leave integrated clock source and reference clock enabled for pipe B.
 	 * The latter is needed for VGA hotplug / manual detection.
@@ -1814,9 +1801,6 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
 	u32 val;
 
-	/* Make sure the pipe isn't still relying on us */
-	assert_pipe_disabled(dev_priv, pipe);
-
 	/* Set PLL en = 0 */
 	val = DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV;
 	if (pipe != PIPE_A)
@@ -1968,7 +1952,8 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc)
 }
 
 static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
-					   enum pipe pipe)
+					   enum pipe pipe,
+					   struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = dev_priv->dev;
 	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
@@ -1983,7 +1968,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 				   intel_crtc_to_shared_dpll(intel_crtc));
 
 	/* FDI must be feeding us bits for PCH ports */
-	assert_fdi_tx_enabled(dev_priv, pipe);
+	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
 	assert_fdi_rx_enabled(dev_priv, pipe);
 
 	if (HAS_PCH_CPT(dev)) {
@@ -2032,7 +2017,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 	BUG_ON(!HAS_PCH_SPLIT(dev_priv->dev));
 
 	/* FDI must be feeding us bits for PCH ports */
-	assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
+	assert_fdi_tx_enabled(dev_priv, cpu_transcoder, (enum pipe) cpu_transcoder);
 	assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);
 
 	/* Workaround: set timing override bit. */
@@ -2055,13 +2040,14 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 }
 
 static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv,
+					    enum transcoder cpu_transcoder,
 					    enum pipe pipe)
 {
 	struct drm_device *dev = dev_priv->dev;
 	uint32_t reg, val;
 
 	/* FDI relies on the transcoder */
-	assert_fdi_tx_disabled(dev_priv, pipe);
+	assert_fdi_tx_disabled(dev_priv, cpu_transcoder, pipe);
 	assert_fdi_rx_disabled(dev_priv, pipe);
 
 	/* Ports must be off as well */
@@ -2113,8 +2099,9 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe = crtc->pipe;
-	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-								      pipe);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	enum pipe pch_transcoder;
 	int reg;
 	u32 val;
@@ -2163,6 +2150,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
 /**
  * intel_disable_pipe - disable a pipe, asserting requirements
  * @crtc: crtc whose pipes is to be disabled
+ * @old_state: currently applied config
  *
  * Disable the pipe of @crtc, making sure that various hardware
  * specific requirements are met, if applicable, e.g. plane
@@ -2170,10 +2158,11 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
  *
  * Will wait until the pipe has shut down before returning.
  */
-static void intel_disable_pipe(struct intel_crtc *crtc)
+static void intel_disable_pipe(struct intel_crtc *crtc,
+			       struct intel_crtc_state *old_state)
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 	int reg;
 	u32 val;
@@ -2195,7 +2184,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
 	 * Double wide has implications for planes
 	 * so best keep it disabled when not needed.
 	 */
-	if (crtc->config->double_wide)
+	if (old_state->double_wide)
 		val &= ~PIPECONF_DOUBLE_WIDE;
 
 	/* Don't disable pipe or pipe PLLs if needed */
@@ -2205,7 +2194,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
 
 	I915_WRITE(reg, val);
 	if ((val & PIPECONF_ENABLE) == 0)
-		intel_wait_for_pipe_off(crtc);
+		intel_wait_for_pipe_off(crtc, old_state);
 }
 
 /*
@@ -3395,9 +3384,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp, tries;
 
-	/* FDI needs bits from pipe first */
-	assert_pipe_enabled(dev_priv, pipe);
-
 	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
 	   for train result */
 	reg = FDI_RX_IMR(pipe);
@@ -3737,7 +3723,8 @@ train_done:
 	DRM_DEBUG_KMS("FDI train done.\n");
 }
 
-static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
+static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc,
+				    struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3749,7 +3736,7 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
 	reg = FDI_RX_CTL(pipe);
 	temp = I915_READ(reg);
 	temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
-	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
 	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
 	I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
 
@@ -4093,7 +4080,7 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
  *   - DP transcoding bits
  *   - transcoder
  */
-static void ironlake_pch_enable(struct drm_crtc *crtc)
+static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4122,7 +4109,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 		temp = I915_READ(PCH_DPLL_SEL);
 		temp |= TRANS_DPLL_ENABLE(pipe);
 		sel = TRANS_DPLLB_SEL(pipe);
-		if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
+		if (pipe_config->shared_dpll == DPLL_ID_PCH_PLL_B)
 			temp |= sel;
 		else
 			temp &= ~sel;
@@ -4145,7 +4132,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 	intel_fdi_normal_train(crtc);
 
 	/* For PCH DP, enable TRANS_DP_CTL */
-	if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
+	if (HAS_PCH_CPT(dev) && pipe_config->has_dp_encoder) {
 		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
 		reg = TRANS_DP_CTL(pipe);
 		temp = I915_READ(reg);
@@ -4178,7 +4165,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 		I915_WRITE(reg, temp);
 	}
 
-	ironlake_enable_pch_transcoder(dev_priv, pipe);
+	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
 }
 
 static void lpt_pch_enable(struct drm_crtc *crtc)
@@ -4789,23 +4776,25 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
+	struct intel_crtc_state *pipe_config;
 
 	WARN_ON(!crtc->state->enable);
 
-	if (intel_crtc->active)
+	if (WARN_ON(intel_crtc->active))
 		return;
+	pipe_config = to_intel_crtc_state(crtc->state);
 
-	if (intel_crtc->config->has_pch_encoder)
+	if (pipe_config->has_pch_encoder)
 		intel_prepare_shared_dpll(intel_crtc);
 
-	if (intel_crtc->config->has_dp_encoder)
+	if (pipe_config->has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc, M1_N1);
 
 	intel_set_pipe_timings(intel_crtc);
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (pipe_config->has_pch_encoder) {
 		intel_cpu_transcoder_set_m_n(intel_crtc,
-				     &intel_crtc->config->fdi_m_n, NULL);
+				     &pipe_config->fdi_m_n, NULL);
 	}
 
 	ironlake_set_pipeconf(crtc);
@@ -4823,9 +4812,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 		/* Note: FDI PLL enabling _must_ be done before we enable the
 		 * cpu pipes, hence this is separate from all the other fdi/pch
 		 * enabling. */
-		ironlake_fdi_pll_enable(intel_crtc);
+		ironlake_fdi_pll_enable(intel_crtc, pipe_config);
 	} else {
-		assert_fdi_tx_disabled(dev_priv, pipe);
+		assert_fdi_tx_disabled(dev_priv, pipe_config->cpu_transcoder, pipe);
 		assert_fdi_rx_disabled(dev_priv, pipe);
 	}
 
@@ -4841,7 +4830,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	intel_enable_pipe(intel_crtc);
 
 	if (intel_crtc->config->has_pch_encoder)
-		ironlake_pch_enable(crtc);
+		ironlake_pch_enable(crtc, pipe_config);
 
 	assert_vblank_disabled(crtc);
 	drm_crtc_vblank_on(crtc);
@@ -4893,30 +4882,32 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config;
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 
 	WARN_ON(!crtc->state->enable);
 
-	if (intel_crtc->active)
+	if (WARN_ON(intel_crtc->active))
 		return;
 
+	pipe_config = to_intel_crtc_state(crtc->state);
 	if (intel_crtc_to_shared_dpll(intel_crtc))
 		intel_enable_shared_dpll(intel_crtc);
 
-	if (intel_crtc->config->has_dp_encoder)
+	if (pipe_config->has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc, M1_N1);
 
 	intel_set_pipe_timings(intel_crtc);
 
-	if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
-		I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
-			   intel_crtc->config->pixel_multiplier - 1);
+	if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
+		I915_WRITE(PIPE_MULT(pipe_config->cpu_transcoder),
+			   pipe_config->pixel_multiplier - 1);
 	}
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (pipe_config->has_pch_encoder) {
 		intel_cpu_transcoder_set_m_n(intel_crtc,
-				     &intel_crtc->config->fdi_m_n, NULL);
+				     &pipe_config->fdi_m_n, NULL);
 	}
 
 	haswell_set_pipeconf(crtc);
@@ -4930,9 +4921,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (pipe_config->has_pch_encoder) {
 		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 						      true);
+
 		dev_priv->display.fdi_link_train(crtc);
 	}
 
@@ -4991,7 +4983,8 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
 	}
 }
 
-static void ironlake_crtc_disable(struct drm_crtc *crtc)
+static void ironlake_crtc_disable(struct drm_crtc *crtc,
+				  struct intel_crtc_state *old_state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5006,10 +4999,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 	drm_crtc_vblank_off(crtc);
 	assert_vblank_disabled(crtc);
 
-	if (intel_crtc->config->has_pch_encoder)
+	if (old_state->has_pch_encoder)
 		intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
 
-	intel_disable_pipe(intel_crtc);
+	intel_disable_pipe(intel_crtc, old_state);
 
 	ironlake_pfit_disable(intel_crtc);
 
@@ -5017,10 +5010,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 		if (encoder->post_disable)
 			encoder->post_disable(encoder);
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (old_state->has_pch_encoder) {
 		ironlake_fdi_disable(crtc);
 
-		ironlake_disable_pch_transcoder(dev_priv, pipe);
+		ironlake_disable_pch_transcoder(dev_priv, old_state->cpu_transcoder, pipe);
 
 		if (HAS_PCH_CPT(dev)) {
 			/* disable TRANS_DP_CTL */
@@ -5041,7 +5034,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 	}
 }
 
-static void haswell_crtc_disable(struct drm_crtc *crtc)
+static void haswell_crtc_disable(struct drm_crtc *crtc,
+				 struct intel_crtc_state *old_state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5060,7 +5054,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 	if (intel_crtc->config->has_pch_encoder)
 		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 						      false);
-	intel_disable_pipe(intel_crtc);
+	intel_disable_pipe(intel_crtc, old_state);
 
 	if (intel_crtc->config->dp_encoder_is_mst)
 		intel_ddi_set_vc_payload_alloc(crtc, false);
@@ -5086,11 +5080,11 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 			encoder->post_disable(encoder);
 }
 
-static void i9xx_pfit_enable(struct intel_crtc *crtc)
+static void i9xx_pfit_enable(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;
-	struct intel_crtc_state *pipe_config = crtc->config;
 
 	if (!pipe_config->gmch_pfit.control)
 		return;
@@ -5100,7 +5094,7 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
 	 * according to register description and PRM.
 	 */
 	WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
-	assert_pipe_disabled(dev_priv, crtc->pipe);
+	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
 
 	I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios);
 	I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control);
@@ -5167,7 +5161,7 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 	unsigned long mask;
 	enum transcoder transcoder;
 
-	transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
+	transcoder = to_intel_crtc_state(crtc->state)->cpu_transcoder;
 
 	mask = BIT(POWER_DOMAIN_PIPE(pipe));
 	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
@@ -5767,22 +5761,24 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	bool is_dsi;
+	struct intel_crtc_state *pipe_config;
 
 	WARN_ON(!crtc->state->active);
 
-	if (intel_crtc->active)
+	if (WARN_ON(intel_crtc->active))
 		return;
+	pipe_config = to_intel_crtc_state(crtc->state);
 
 	is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
 
 	if (!is_dsi) {
 		if (IS_CHERRYVIEW(dev))
-			chv_prepare_pll(intel_crtc, intel_crtc->config);
+			chv_prepare_pll(intel_crtc, pipe_config);
 		else
-			vlv_prepare_pll(intel_crtc, intel_crtc->config);
+			vlv_prepare_pll(intel_crtc, pipe_config);
 	}
 
-	if (intel_crtc->config->has_dp_encoder)
+	if (pipe_config->has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc, M1_N1);
 
 	intel_set_pipe_timings(intel_crtc);
@@ -5806,16 +5802,16 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 
 	if (!is_dsi) {
 		if (IS_CHERRYVIEW(dev))
-			chv_enable_pll(intel_crtc, intel_crtc->config);
+			chv_enable_pll(intel_crtc, pipe_config);
 		else
-			vlv_enable_pll(intel_crtc, intel_crtc->config);
+			vlv_enable_pll(intel_crtc, pipe_config);
 	}
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
-	i9xx_pfit_enable(intel_crtc);
+	i9xx_pfit_enable(intel_crtc, pipe_config);
 
 	intel_crtc_load_lut(crtc);
 
@@ -5844,11 +5840,13 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
+	struct intel_crtc_state *pipe_config;
 	int pipe = intel_crtc->pipe;
 
-	WARN_ON(!crtc->state->active);
+	pipe_config = to_intel_crtc_state(crtc->state);
+	WARN_ON(!pipe_config->base.active);
 
-	if (intel_crtc->active)
+	if (WARN_ON(intel_crtc->active))
 		return;
 
 	i9xx_set_pll_dividers(intel_crtc);
@@ -5869,9 +5867,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
-	i9xx_enable_pll(intel_crtc);
+	i9xx_enable_pll(intel_crtc, pipe_config);
 
-	i9xx_pfit_enable(intel_crtc);
+	i9xx_pfit_enable(intel_crtc, pipe_config);
 
 	intel_crtc_load_lut(crtc);
 
@@ -5893,14 +5891,13 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc)
 	if (!crtc->config->gmch_pfit.control)
 		return;
 
-	assert_pipe_disabled(dev_priv, crtc->pipe);
-
 	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
 			 I915_READ(PFIT_CONTROL));
 	I915_WRITE(PFIT_CONTROL, 0);
 }
 
-static void i9xx_crtc_disable(struct drm_crtc *crtc)
+static void i9xx_crtc_disable(struct drm_crtc *crtc,
+			      struct intel_crtc_state *old_state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5922,7 +5919,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	drm_crtc_vblank_off(crtc);
 	assert_vblank_disabled(crtc);
 
-	intel_disable_pipe(intel_crtc);
+	intel_disable_pipe(intel_crtc, old_state);
 
 	i9xx_pfit_disable(intel_crtc);
 
@@ -5936,7 +5933,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 		else if (IS_VALLEYVIEW(dev))
 			vlv_disable_pll(dev_priv, pipe);
 		else
-			i9xx_disable_pll(intel_crtc);
+			i9xx_disable_pll(intel_crtc, old_state);
 	}
 
 	if (!IS_GEN2(dev))
@@ -6989,10 +6986,12 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
 {
 	struct intel_crtc *crtc =
 		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+	struct intel_crtc_state *state = to_intel_crtc_state(crtc->base.state);
 	struct intel_crtc_state pipe_config = {
 		.base.crtc = &crtc->base,
 		.pixel_multiplier = 1,
 		.dpll = *dpll,
+		.cpu_transcoder = state->cpu_transcoder,
 	};
 
 	if (IS_CHERRYVIEW(dev)) {
@@ -7016,6 +7015,16 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
  */
 void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
+	struct intel_crtc_state *state = to_intel_crtc_state(crtc->state);
+
+	/* Is state->cpu_transcoder correct to use? */
+	WARN_ON(crtc->state != &to_intel_crtc(crtc)->config->base);
+
+	/* Make sure the pipe isn't still relying on us */
+	assert_pipe_disabled(dev_priv, state->cpu_transcoder, pipe);
+
 	if (IS_CHERRYVIEW(dev))
 		chv_disable_pll(to_i915(dev), pipe);
 	else
@@ -12275,6 +12284,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 
 	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		struct intel_crtc_state *pipe_config;
 
 		if (!needs_modeset(crtc->state))
 			continue;
@@ -12282,8 +12292,9 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 		if (!old_crtc_state->active)
 			continue;
 
+		pipe_config = to_intel_crtc_state(old_crtc_state);
 		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
-		dev_priv->display.crtc_disable(crtc);
+		dev_priv->display.crtc_disable(crtc, pipe_config);
 
 		intel_crtc->active = false;
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 82dcc6ed8b1d..83de36bfddc1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2090,6 +2090,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 	u32 dpa_ctl;
 
 	assert_pipe_disabled(dev_priv,
+			     to_intel_crtc_state(crtc->state)->cpu_transcoder,
 			     to_intel_crtc(crtc)->pipe);
 
 	DRM_DEBUG_KMS("\n");
@@ -2116,6 +2117,7 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
 	u32 dpa_ctl;
 
 	assert_pipe_disabled(dev_priv,
+			     to_intel_crtc(crtc)->config->cpu_transcoder,
 			     to_intel_crtc(crtc)->pipe);
 
 	dpa_ctl = I915_READ(DP_A);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9ef89c91aa5c..58240e63630c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -998,8 +998,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
-enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
-					     enum pipe pipe);
 bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type);
 static inline void
 intel_wait_for_vblank(struct drm_device *dev, int pipe)
@@ -1085,9 +1083,11 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
 		       enum pipe pipe, bool state);
 #define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true)
 #define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false)
-void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+void assert_pipe(struct drm_i915_private *dev_priv,
+		 enum transcoder cpu_transcoder,
+		 enum pipe pipe, bool state);
+#define assert_pipe_enabled(d, c, p) assert_pipe(d, c, p, true)
+#define assert_pipe_disabled(d, c, p) assert_pipe(d, c, p, false)
 unsigned long intel_gen4_compute_page_offset(int *x, int *y,
 					     unsigned int tiling_mode,
 					     unsigned int bpp,
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 7d83527f95f7..67eafa27400b 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -837,9 +837,8 @@ static void pch_enable_backlight(struct intel_connector *connector)
 	struct drm_device *dev = connector->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = intel_get_pipe_from_connector(connector);
 	enum transcoder cpu_transcoder =
-		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
+		to_intel_crtc_state(connector->encoder->base.crtc->state)->cpu_transcoder;
 	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
 
 	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 8b9d325bda3c..b4aeb256128f 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1117,7 +1117,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder)
 			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
 			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
 
-	assert_pipe_disabled(dev_priv, intel_crtc->pipe);
+	assert_pipe_disabled(dev_priv, to_intel_crtc_state(intel_crtc->base.state)->cpu_transcoder, intel_crtc->pipe);
 
 	/* Filter ctl must be set before TV_WIN_SIZE */
 	I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (21 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it Maarten Lankhorst
@ 2015-05-11 14:24 ` Maarten Lankhorst
  2015-05-12  9:16   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 24/42] drm/i915: Remove use of crtc->config from intel_fbdev.c Maarten Lankhorst
                   ` (19 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:24 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This removes a lot of users for crtc->config.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_crt.c     | 21 ++++++----
 drivers/gpu/drm/i915/intel_ddi.c     | 78 +++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++-------
 drivers/gpu/drm/i915/intel_dp.c      | 49 +++++++++-------------
 drivers/gpu/drm/i915/intel_dp_mst.c  |  9 +++--
 drivers/gpu/drm/i915/intel_drv.h     | 13 +++---
 drivers/gpu/drm/i915/intel_dsi.c     | 11 +++--
 drivers/gpu/drm/i915/intel_dvo.c     | 15 ++++---
 drivers/gpu/drm/i915/intel_hdmi.c    | 20 +++++----
 drivers/gpu/drm/i915/intel_lvds.c    | 11 +++--
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +-
 drivers/gpu/drm/i915/intel_tv.c      |  3 +-
 12 files changed, 150 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 93bb5159d093..d94f6cb91d42 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -152,13 +152,13 @@ static void hsw_crt_pre_enable(struct intel_encoder *encoder)
 
 /* Note: The caller is required to filter out dpms modes not supported by the
  * platform. */
-static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
+static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode,
+			       struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
-	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
 	u32 adpa;
 
 	if (INTEL_INFO(dev)->gen >= 5)
@@ -202,13 +202,16 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
 	I915_WRITE(crt->adpa_reg, adpa);
 }
 
-static void intel_disable_crt(struct intel_encoder *encoder)
+static void intel_disable_crt(struct intel_encoder *encoder,
+			      struct intel_crtc_state *pipe_config)
 {
-	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
+	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF,
+			   &pipe_config->base.adjusted_mode);
 }
 
 
-static void hsw_crt_post_disable(struct intel_encoder *encoder)
+static void hsw_crt_post_disable(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -224,8 +227,10 @@ static void hsw_crt_post_disable(struct intel_encoder *encoder)
 static void intel_enable_crt(struct intel_encoder *encoder)
 {
 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	struct drm_crtc *crtc = encoder->base.crtc;
 
-	intel_crt_set_dpms(encoder, crt->connector->base.dpms);
+	intel_crt_set_dpms(encoder, crt->connector->base.dpms,
+			   &crtc->state->adjusted_mode);
 }
 
 /* Special dpms function to support cloning between dvo/sdvo/crt. */
@@ -265,9 +270,9 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
 		/* From off to on, enable the pipe first. */
 		intel_crtc_update_dpms(crtc);
 
-		intel_crt_set_dpms(encoder, mode);
+		intel_crt_set_dpms(encoder, mode, &crtc->state->adjusted_mode);
 	} else {
-		intel_crt_set_dpms(encoder, mode);
+		intel_crt_set_dpms(encoder, mode, &crtc->state->adjusted_mode);
 
 		intel_crtc_update_dpms(crtc);
 	}
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 807e15d41a1b..c5a9e36d6a0e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -430,7 +430,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	u32 temp, i, rx_ctl_val;
 
 	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
@@ -447,7 +448,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	/* Enable the PCH Receiver FDI PLL */
 	rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
 		     FDI_RX_PLL_ENABLE |
-		     FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+		     FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
 	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
 	POSTING_READ(_FDI_RXA_CTL);
 	udelay(220);
@@ -457,8 +458,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
 
 	/* Configure Port Clock Select */
-	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
-	WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
+	I915_WRITE(PORT_CLK_SEL(PORT_E), pipe_config->ddi_pll_sel);
+	WARN_ON(pipe_config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
 
 	/* Start the training iterating through available voltages and emphasis,
 	 * testing each value twice. */
@@ -476,7 +477,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 		 * port reversal bit */
 		I915_WRITE(DDI_BUF_CTL(PORT_E),
 			   DDI_BUF_CTL_ENABLE |
-			   ((intel_crtc->config->fdi_lanes - 1) << 1) |
+			   ((pipe_config->fdi_lanes - 1) << 1) |
 			   DDI_BUF_TRANS_SELECT(i / 2));
 		POSTING_READ(DDI_BUF_CTL(PORT_E));
 
@@ -1481,15 +1482,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	int type = intel_encoder->type;
 	uint32_t temp;
 
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
 		temp = TRANS_MSA_SYNC_CLK;
-		switch (intel_crtc->config->pipe_bpp) {
+		switch (pipe_config->pipe_bpp) {
 		case 18:
 			temp |= TRANS_MSA_6_BPC;
 			break;
@@ -1509,12 +1511,12 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 	}
 }
 
-void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc,
+				    enum transcoder cpu_transcoder,
+				    bool state)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
 	uint32_t temp;
 	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (state == true)
@@ -1532,7 +1534,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe = intel_crtc->pipe;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
 	uint32_t temp;
@@ -1541,7 +1544,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 	temp = TRANS_DDI_FUNC_ENABLE;
 	temp |= TRANS_DDI_SELECT_PORT(port);
 
-	switch (intel_crtc->config->pipe_bpp) {
+	switch (pipe_config->pipe_bpp) {
 	case 18:
 		temp |= TRANS_DDI_BPC_6;
 		break;
@@ -1558,9 +1561,9 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 		BUG();
 	}
 
-	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
+	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
 		temp |= TRANS_DDI_PVSYNC;
-	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
+	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
 		temp |= TRANS_DDI_PHSYNC;
 
 	if (cpu_transcoder == TRANSCODER_EDP) {
@@ -1571,8 +1574,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 			 * using motion blur mitigation (which we don't
 			 * support). */
 			if (IS_HASWELL(dev) &&
-			    (intel_crtc->config->pch_pfit.enabled ||
-			     intel_crtc->config->pch_pfit.force_thru))
+			    (pipe_config->pch_pfit.enabled ||
+			     pipe_config->pch_pfit.force_thru))
 				temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
 			else
 				temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1590,14 +1593,14 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
 	}
 
 	if (type == INTEL_OUTPUT_HDMI) {
-		if (intel_crtc->config->has_hdmi_sink)
+		if (pipe_config->has_hdmi_sink)
 			temp |= TRANS_DDI_MODE_SELECT_HDMI;
 		else
 			temp |= TRANS_DDI_MODE_SELECT_DVI;
 
 	} else if (type == INTEL_OUTPUT_ANALOG) {
 		temp |= TRANS_DDI_MODE_SELECT_FDI;
-		temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
+		temp |= (pipe_config->fdi_lanes - 1) << 1;
 
 	} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
 		   type == INTEL_OUTPUT_EDP) {
@@ -1747,17 +1750,19 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 
 	if (cpu_transcoder != TRANSCODER_EDP)
 		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
 			   TRANS_CLK_SEL_PORT(port));
 }
 
-void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
+void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc,
+				  enum transcoder cpu_transcoder)
 {
 	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
 
 	if (cpu_transcoder != TRANSCODER_EDP)
 		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
@@ -1902,7 +1907,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	}
 }
 
-static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
+static void intel_ddi_post_disable(struct intel_encoder *intel_encoder,
+				   struct intel_crtc_state *pipe_config)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_device *dev = encoder->dev;
@@ -1945,10 +1951,11 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = encoder->crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	int type = intel_encoder->type;
 
 	if (type == INTEL_OUTPUT_HDMI) {
@@ -1970,25 +1977,28 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
 
 		intel_edp_backlight_on(intel_dp);
 		intel_psr_enable(intel_dp);
-		intel_edp_drrs_enable(intel_dp);
+
+		if (pipe_config->has_drrs)
+			intel_edp_drrs_enable(intel_dp);
+		else
+			DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
 	}
 
-	if (intel_crtc->config->has_audio) {
+	if (pipe_config->has_audio) {
 		intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
 		intel_audio_codec_enable(intel_encoder);
 	}
 }
 
-static void intel_disable_ddi(struct intel_encoder *intel_encoder)
+static void intel_disable_ddi(struct intel_encoder *intel_encoder,
+			      struct intel_crtc_state *pipe_config)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_crtc *crtc = encoder->crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int type = intel_encoder->type;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	if (intel_crtc->config->has_audio) {
+	if (pipe_config->has_audio) {
 		intel_audio_codec_disable(intel_encoder);
 		intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
 	}
@@ -1996,7 +2006,8 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
 	if (type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-		intel_edp_drrs_disable(intel_dp);
+		if (pipe_config->has_drrs)
+			intel_edp_drrs_disable(intel_dp);
 		intel_psr_disable(intel_dp);
 		intel_edp_backlight_off(intel_dp);
 	}
@@ -2546,13 +2557,14 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
 	udelay(600);
 }
 
-void intel_ddi_fdi_disable(struct drm_crtc *crtc)
+void intel_ddi_fdi_disable(struct drm_crtc *crtc,
+			   struct intel_crtc_state *old_state)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
 	uint32_t val;
 
-	intel_ddi_post_disable(intel_encoder);
+	intel_ddi_post_disable(intel_encoder, old_state);
 
 	val = I915_READ(_FDI_RXA_CTL);
 	val &= ~FDI_RX_ENABLE;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 311a4b44bebe..7bc78b49f9f4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4953,7 +4953,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 		lpt_pch_enable(crtc);
 
 	if (intel_crtc->config->dp_encoder_is_mst)
-		intel_ddi_set_vc_payload_alloc(crtc, true);
+		intel_ddi_set_vc_payload_alloc(crtc,
+					       pipe_config->cpu_transcoder,
+					       true);
 
 	assert_vblank_disabled(crtc);
 	drm_crtc_vblank_on(crtc);
@@ -4994,7 +4996,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
 	u32 reg, temp;
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
-		encoder->disable(encoder);
+		encoder->disable(encoder, old_state);
 
 	drm_crtc_vblank_off(crtc);
 	assert_vblank_disabled(crtc);
@@ -5008,7 +5010,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
-			encoder->post_disable(encoder);
+			encoder->post_disable(encoder, old_state);
 
 	if (old_state->has_pch_encoder) {
 		ironlake_fdi_disable(crtc);
@@ -5045,7 +5047,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		intel_opregion_notify_encoder(encoder, false);
-		encoder->disable(encoder);
+		encoder->disable(encoder, old_state);
 	}
 
 	drm_crtc_vblank_off(crtc);
@@ -5057,7 +5059,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 	intel_disable_pipe(intel_crtc, old_state);
 
 	if (intel_crtc->config->dp_encoder_is_mst)
-		intel_ddi_set_vc_payload_alloc(crtc, false);
+		intel_ddi_set_vc_payload_alloc(crtc,
+					       old_state->cpu_transcoder,
+					       false);
 
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
@@ -5068,16 +5072,16 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 	else
 		MISSING_CASE(INTEL_INFO(dev)->gen);
 
-	intel_ddi_disable_pipe_clock(intel_crtc);
+	intel_ddi_disable_pipe_clock(intel_crtc, old_state->cpu_transcoder);
 
 	if (intel_crtc->config->has_pch_encoder) {
 		lpt_disable_pch_transcoder(dev_priv);
-		intel_ddi_fdi_disable(crtc);
+		intel_ddi_fdi_disable(crtc, old_state);
 	}
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
-			encoder->post_disable(encoder);
+			encoder->post_disable(encoder, old_state);
 }
 
 static void i9xx_pfit_enable(struct intel_crtc *crtc,
@@ -5914,7 +5918,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
 	intel_wait_for_vblank(dev, pipe);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
-		encoder->disable(encoder);
+		encoder->disable(encoder, old_state);
 
 	drm_crtc_vblank_off(crtc);
 	assert_vblank_disabled(crtc);
@@ -5925,7 +5929,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
-			encoder->post_disable(encoder);
+			encoder->post_disable(encoder, old_state);
 
 	if (!intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI)) {
 		if (IS_CHERRYVIEW(dev))
@@ -14672,12 +14676,12 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 {
 	struct intel_connector *connector;
 	struct drm_device *dev = encoder->base.dev;
+	struct drm_crtc *crtc = encoder->base.crtc;
 
 	/* We need to check both for a crtc link (meaning that the
 	 * encoder is active and trying to read from a pipe) and the
 	 * pipe itself being active. */
-	bool has_active_crtc = encoder->base.crtc &&
-		to_intel_crtc(encoder->base.crtc)->active;
+	bool has_active_crtc = crtc && to_intel_crtc(crtc)->active;
 
 	if (encoder->connectors_active && !has_active_crtc) {
 		DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
@@ -14687,13 +14691,15 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 		/* Connector is active, but has no active pipe. This is
 		 * fallout from our resume register restoring. Disable
 		 * the encoder manually again. */
-		if (encoder->base.crtc) {
+		if (crtc) {
+			struct intel_crtc_state *pipe_config =
+				to_intel_crtc_state(crtc->state);
 			DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
 				      encoder->base.base.id,
 				      encoder->base.name);
-			encoder->disable(encoder);
+			encoder->disable(encoder, pipe_config);
 			if (encoder->post_disable)
-				encoder->post_disable(encoder);
+				encoder->post_disable(encoder, pipe_config);
 		}
 		encoder->base.crtc = NULL;
 		encoder->connectors_active = false;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 83de36bfddc1..eda1b22c3111 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1499,17 +1499,19 @@ found:
 static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_crtc *crtc = dig_port->base.base.crtc;
+	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	u32 dpa_ctl;
 
 	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
-		      crtc->config->port_clock);
+		      pipe_config->port_clock);
 	dpa_ctl = I915_READ(DP_A);
 	dpa_ctl &= ~DP_PLL_FREQ_MASK;
 
-	if (crtc->config->port_clock == 162000) {
+	if (pipe_config->port_clock == 162000) {
 		/* For a long time we've carried around a ILK-DevA w/a for the
 		 * 160MHz clock. If we're really unlucky, it's still required.
 		 */
@@ -2108,7 +2110,8 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
 	udelay(200);
 }
 
-static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
+static void ironlake_edp_pll_off(struct intel_dp *intel_dp,
+				 struct intel_crtc_state *pipe_config)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
@@ -2117,7 +2120,7 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
 	u32 dpa_ctl;
 
 	assert_pipe_disabled(dev_priv,
-			     to_intel_crtc(crtc)->config->cpu_transcoder,
+			     pipe_config->cpu_transcoder,
 			     to_intel_crtc(crtc)->pipe);
 
 	dpa_ctl = I915_READ(DP_A);
@@ -2308,13 +2311,13 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 	}
 }
 
-static void intel_disable_dp(struct intel_encoder *encoder)
+static void intel_disable_dp(struct intel_encoder *encoder,
+			     struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct drm_device *dev = encoder->base.dev;
-	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 
-	if (crtc->config->has_audio)
+	if (pipe_config->has_audio)
 		intel_audio_codec_disable(encoder);
 
 	if (HAS_PSR(dev) && !HAS_DDI(dev))
@@ -2332,24 +2335,27 @@ static void intel_disable_dp(struct intel_encoder *encoder)
 		intel_dp_link_down(intel_dp);
 }
 
-static void ilk_post_disable_dp(struct intel_encoder *encoder)
+static void ilk_post_disable_dp(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	enum port port = dp_to_dig_port(intel_dp)->port;
 
 	intel_dp_link_down(intel_dp);
 	if (port == PORT_A)
-		ironlake_edp_pll_off(intel_dp);
+		ironlake_edp_pll_off(intel_dp, pipe_config);
 }
 
-static void vlv_post_disable_dp(struct intel_encoder *encoder)
+static void vlv_post_disable_dp(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 
 	intel_dp_link_down(intel_dp);
 }
 
-static void chv_post_disable_dp(struct intel_encoder *encoder)
+static void chv_post_disable_dp(struct intel_encoder *encoder,
+				struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
@@ -5249,7 +5255,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 	struct intel_encoder *encoder;
 	struct intel_digital_port *dig_port = NULL;
 	struct intel_dp *intel_dp = dev_priv->drrs.dp;
-	struct intel_crtc_state *config = NULL;
 	struct intel_crtc *intel_crtc = NULL;
 	u32 reg, val;
 	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
@@ -5278,8 +5283,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 		return;
 	}
 
-	config = intel_crtc->config;
-
 	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
 		DRM_DEBUG_KMS("Only Seamless DRRS supported.\n");
 		return;
@@ -5345,14 +5348,6 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_crtc *crtc = dig_port->base.base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	if (!intel_crtc->config->has_drrs) {
-		DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
-		return;
-	}
 
 	mutex_lock(&dev_priv->drrs.mutex);
 	if (WARN_ON(dev_priv->drrs.dp)) {
@@ -5377,12 +5372,6 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp)
 {
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_crtc *crtc = dig_port->base.base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-	if (!intel_crtc->config->has_drrs)
-		return;
 
 	mutex_lock(&dev_priv->drrs.mutex);
 	if (!dev_priv->drrs.dp) {
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 6e4cc5334f47..4992c8025520 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -101,7 +101,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
 }
 
-static void intel_mst_disable_dp(struct intel_encoder *encoder)
+static void intel_mst_disable_dp(struct intel_encoder *encoder,
+				 struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
@@ -118,7 +119,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder)
 	}
 }
 
-static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
+static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
+				      struct intel_crtc_state *pipe_config)
 {
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
@@ -136,7 +138,8 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
 	intel_dp->active_mst_links--;
 	intel_mst->port = NULL;
 	if (intel_dp->active_mst_links == 0) {
-		intel_dig_port->base.post_disable(&intel_dig_port->base);
+		intel_dig_port->base.post_disable(&intel_dig_port->base,
+						  pipe_config);
 		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 58240e63630c..eb87f82b5aff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -141,8 +141,9 @@ struct intel_encoder {
 	void (*pre_enable)(struct intel_encoder *);
 	void (*enable)(struct intel_encoder *);
 	void (*mode_set)(struct intel_encoder *intel_encoder);
-	void (*disable)(struct intel_encoder *);
-	void (*post_disable)(struct intel_encoder *);
+	void (*disable)(struct intel_encoder *, struct intel_crtc_state *);
+	void (*post_disable)(struct intel_encoder *,
+			     struct intel_crtc_state *);
 	/* Read out the current hw state of this connector, returning true if
 	 * the encoder is active. If the encoder is enabled it also set the pipe
 	 * it is connected to in the pipe parameter. */
@@ -910,13 +911,14 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
 void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 				       enum transcoder cpu_transcoder);
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
-void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
+void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc,
+				  enum transcoder cpu_transcoder);
 bool intel_ddi_pll_select(struct intel_crtc *crtc,
 			  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);
 bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
-void intel_ddi_fdi_disable(struct drm_crtc *crtc);
+void intel_ddi_fdi_disable(struct drm_crtc *crtc, struct intel_crtc_state *);
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config);
 struct intel_encoder *
@@ -925,7 +927,8 @@ intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state);
 void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
 void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
-void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
+void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc,
+				    enum transcoder, bool state);
 void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
 				enum port port, int type);
 
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 51966426addf..3f28b046751b 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -409,6 +409,9 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
+	
 	enum pipe pipe = intel_crtc->pipe;
 	enum port port;
 	u32 tmp;
@@ -422,7 +425,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
 	I915_WRITE(DPLL(pipe), tmp);
 
 	/* update the hw state for DPLL */
-	intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
+	pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
 		DPLL_REFA_CLK_ENABLE_VLV;
 
 	tmp = I915_READ(DSPCLK_GATE_D);
@@ -454,7 +457,8 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder)
 	 */
 }
 
-static void intel_dsi_pre_disable(struct intel_encoder *encoder)
+static void intel_dsi_pre_disable(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	enum port port;
@@ -556,7 +560,8 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
 	vlv_disable_dsi_pll(encoder);
 }
 
-static void intel_dsi_post_disable(struct intel_encoder *encoder)
+static void intel_dsi_post_disable(struct intel_encoder *encoder,
+				   struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index ece5bd754f85..4dac4ce5963a 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -166,7 +166,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
 	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
-static void intel_disable_dvo(struct intel_encoder *encoder)
+static void intel_disable_dvo(struct intel_encoder *encoder,
+			      struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
@@ -182,13 +183,14 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
-	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct drm_crtc *crtc = encoder->base.crtc;
+	struct drm_crtc_state *pipe_config = crtc->state;
 	u32 dvo_reg = intel_dvo->dev.dvo_reg;
 	u32 temp = I915_READ(dvo_reg);
 
 	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
-					 &crtc->config->base.mode,
-					 &crtc->config->base.adjusted_mode);
+					 &pipe_config->mode,
+					 &pipe_config->adjusted_mode);
 
 	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
 	I915_READ(dvo_reg);
@@ -201,7 +203,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
 {
 	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 	struct drm_crtc *crtc;
-	struct intel_crtc_state *config;
 
 	/* dvo supports only 2 dpms states. */
 	if (mode != DRM_MODE_DPMS_ON)
@@ -222,8 +223,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
 	/* We call connector dpms manually below in case pipe dpms doesn't
 	 * change due to cloning. */
 	if (mode == DRM_MODE_DPMS_ON) {
-		config = to_intel_crtc(crtc)->config;
-
 		intel_dvo->base.connectors_active = true;
 
 		intel_crtc_update_dpms(crtc);
@@ -296,7 +295,7 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder)
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
-	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &crtc->base.state->adjusted_mode;
 	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
 	int pipe = crtc->pipe;
 	u32 dvo_val;
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index d04e6dc97fe5..76994dc033a3 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -866,7 +866,8 @@ static void vlv_enable_hdmi(struct intel_encoder *encoder)
 {
 }
 
-static void intel_disable_hdmi(struct intel_encoder *encoder)
+static void intel_disable_hdmi(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -875,7 +876,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
 	u32 temp;
 	u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
 
-	if (crtc->config->has_audio)
+	if (pipe_config->has_audio)
 		intel_audio_codec_disable(encoder);
 
 	temp = I915_READ(intel_hdmi->hdmi_reg);
@@ -883,8 +884,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
 	/* HW workaround for IBX, we need to move the port to transcoder A
 	 * before disabling it. */
 	if (HAS_PCH_IBX(dev)) {
-		struct drm_crtc *crtc = encoder->base.crtc;
-		int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
+		int pipe = crtc ? crtc->pipe : -1;
 
 		if (temp & SDVO_PIPE_B_SELECT) {
 			temp &= ~SDVO_PIPE_B_SELECT;
@@ -1426,7 +1426,8 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->dpio_lock);
 }
 
-static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
+static void vlv_hdmi_post_disable(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -1442,7 +1443,8 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->dpio_lock);
 }
 
-static void chv_hdmi_post_disable(struct intel_encoder *encoder)
+static void chv_hdmi_post_disable(struct intel_encoder *encoder,
+				  struct intel_crtc_state *pipe_config)
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_device *dev = encoder->base.dev;
@@ -1483,8 +1485,10 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc =
 		to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
 	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
 	int pipe = intel_crtc->pipe;
 	int data, i, stagger;
@@ -1636,7 +1640,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->dpio_lock);
 
 	intel_hdmi->set_infoframes(&encoder->base,
-				   intel_crtc->config->has_hdmi_sink,
+				   pipe_config->has_hdmi_sink,
 				   adjusted_mode);
 
 	intel_enable_hdmi(encoder);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 9a9df0fa67f9..8aaaa24144f0 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -139,8 +139,10 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 	int pipe = crtc->pipe;
 	u32 temp;
 
@@ -168,7 +170,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
 
 	/* set the corresponsding LVDS_BORDER bit */
 	temp &= ~LVDS_BORDER_ENABLE;
-	temp |= crtc->config->gmch_pfit.lvds_border_bits;
+	temp |= pipe_config->gmch_pfit.lvds_border_bits;
 	/* Set the B0-B3 data pairs corresponding to whether we're going to
 	 * set the DPLLs for dual-channel mode or not.
 	 */
@@ -191,7 +193,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
 	if (INTEL_INFO(dev)->gen == 4) {
 		/* Bspec wording suggests that LVDS port dithering only exists
 		 * for 18bpp panels. */
-		if (crtc->config->dither && crtc->config->pipe_bpp == 18)
+		if (pipe_config->dither && pipe_config->pipe_bpp == 18)
 			temp |= LVDS_ENABLE_DITHER;
 		else
 			temp &= ~LVDS_ENABLE_DITHER;
@@ -235,7 +237,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
 	intel_panel_enable_backlight(intel_connector);
 }
 
-static void intel_disable_lvds(struct intel_encoder *encoder)
+static void intel_disable_lvds(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 0a0625761f42..6a68098f8b08 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1425,7 +1425,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 	     pipe_config->pixel_multiplier, encoder_pixel_multiplier);
 }
 
-static void intel_disable_sdvo(struct intel_encoder *encoder)
+static void intel_disable_sdvo(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index b4aeb256128f..9816a9f88ff5 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -863,7 +863,8 @@ intel_enable_tv(struct intel_encoder *encoder)
 }
 
 static void
-intel_disable_tv(struct intel_encoder *encoder)
+intel_disable_tv(struct intel_encoder *encoder,
+		 struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 24/42] drm/i915: Remove use of crtc->config from intel_fbdev.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (22 preceding siblings ...)
  2015-05-11 14:24 ` [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c Maarten Lankhorst
                   ` (18 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_fbdev.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
index 4e7e7da2e03b..cc180bfe4c1b 100644
--- a/drivers/gpu/drm/i915/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/intel_fbdev.c
@@ -468,7 +468,7 @@ retry:
 			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
 				      connector->name);
 			intel_mode_from_pipe_config(&encoder->crtc->hwmode,
-						    to_intel_crtc(encoder->crtc)->config);
+				to_intel_crtc_state(encoder->crtc->state));
 			modes[i] = &encoder->crtc->hwmode;
 		}
 		crtcs[i] = new_crtc;
@@ -566,7 +566,8 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 	for_each_crtc(dev, crtc) {
 		intel_crtc = to_intel_crtc(crtc);
 
-		if (!intel_crtc->active || !crtc->primary->fb) {
+		if (!crtc->state->active ||
+		    !crtc->primary->fb) {
 			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
 				      pipe_name(intel_crtc->pipe));
 			continue;
@@ -589,10 +590,12 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 	/* Now make sure all the pipes will fit into it */
 	for_each_crtc(dev, crtc) {
 		unsigned int cur_size;
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc->state);
 
 		intel_crtc = to_intel_crtc(crtc);
 
-		if (!intel_crtc->active) {
+		if (!pipe_config->base.active) {
 			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
 				      pipe_name(intel_crtc->pipe));
 			continue;
@@ -606,7 +609,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 		 * pipe.  Note we need to use the selected fb's pitch and bpp
 		 * rather than the current pipe's, since they differ.
 		 */
-		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
+		cur_size = pipe_config->base.adjusted_mode.crtc_hdisplay;
 		cur_size = cur_size * fb->base.bits_per_pixel / 8;
 		if (fb->base.pitches[0] < cur_size) {
 			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
@@ -617,15 +620,15 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 			break;
 		}
 
-		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
+		cur_size = pipe_config->base.adjusted_mode.crtc_vdisplay;
 		cur_size = intel_fb_align_height(dev, cur_size,
 						 fb->base.pixel_format,
 						 fb->base.modifier[0]);
 		cur_size *= fb->base.pitches[0];
 		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
 			      pipe_name(intel_crtc->pipe),
-			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
-			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
+			      pipe_config->base.adjusted_mode.crtc_hdisplay,
+			      pipe_config->base.adjusted_mode.crtc_vdisplay,
 			      fb->base.bits_per_pixel,
 			      cur_size);
 
@@ -657,7 +660,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
 	for_each_crtc(dev, crtc) {
 		intel_crtc = to_intel_crtc(crtc);
 
-		if (!intel_crtc->active)
+		if (!crtc->state->active)
 			continue;
 
 		WARN(!crtc->primary->fb,
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (23 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 24/42] drm/i915: Remove use of crtc->config from intel_fbdev.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12  9:20   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 26/42] drm/i915: Remove use of crtc->config from intel_ddi.c Maarten Lankhorst
                   ` (17 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_psr.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 5ee0fa57ed19..868817402c11 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -73,14 +73,15 @@ static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
 }
 
 static void intel_psr_write_vsc(struct intel_dp *intel_dp,
-				    struct edp_vsc_psr *vsc_psr)
+				struct edp_vsc_psr *vsc_psr)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
-	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder);
-	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config->cpu_transcoder);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(dig_port->base.base.crtc->state);
+	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
+	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(pipe_config->cpu_transcoder);
 	uint32_t *data = (uint32_t *) vsc_psr;
 	unsigned int i;
 
@@ -282,13 +283,13 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
 				EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
 }
 
-static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
+static bool intel_psr_match_conditions(struct intel_dp *intel_dp,
+				       struct intel_crtc_state *pipe_config)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = dig_port->base.base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	lockdep_assert_held(&dev_priv->psr.lock);
 	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
@@ -307,14 +308,14 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
 	}
 
 	if (IS_HASWELL(dev) &&
-	    I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) &
+	    I915_READ(HSW_STEREO_3D_CTL(pipe_config->cpu_transcoder)) &
 		      S3D_ENABLE) {
 		DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
 		return false;
 	}
 
 	if (IS_HASWELL(dev) &&
-	    intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+	    pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
 		DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
 		return false;
 	}
@@ -364,6 +365,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
 
 	if (!HAS_PSR(dev)) {
 		DRM_DEBUG_KMS("PSR not supported on this platform\n");
@@ -381,7 +384,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 		goto unlock;
 	}
 
-	if (!intel_psr_match_conditions(intel_dp))
+	if (!intel_psr_match_conditions(intel_dp, pipe_config))
 		goto unlock;
 
 	dev_priv->psr.busy_frontbuffer_bits = 0;
@@ -391,8 +394,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 
 		if (dev_priv->psr.psr2_support) {
 			/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */
-			if (crtc->config->pipe_src_w > 3200 ||
-				crtc->config->pipe_src_h > 2000)
+			if (pipe_config->pipe_src_w > 3200 ||
+				pipe_config->pipe_src_h > 2000)
 				dev_priv->psr.psr2_support = false;
 			else
 				skl_psr_setup_su_vsc(intel_dp);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 26/42] drm/i915: Remove use of crtc->config from intel_ddi.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (24 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c Maarten Lankhorst
                   ` (16 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c5a9e36d6a0e..388f02a8e6e1 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1835,7 +1835,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(encoder->crtc->state);
 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
 	int type = intel_encoder->type;
 	int hdmi_level;
@@ -1846,7 +1847,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 	}
 
 	if (IS_SKYLAKE(dev)) {
-		uint32_t dpll = crtc->config->ddi_pll_sel;
+		uint32_t dpll = pipe_config->ddi_pll_sel;
 		uint32_t val;
 
 		/*
@@ -1861,7 +1862,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
 				 DPLL_CTRL1_SSC(dpll) |
 				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-			val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
+			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
 
 			I915_WRITE(DPLL_CTRL1, val);
 			POSTING_READ(DPLL_CTRL1);
@@ -1878,8 +1879,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		I915_WRITE(DPLL_CTRL2, val);
 
 	} else if (INTEL_INFO(dev)->gen < 9) {
-		WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
-		I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
+		WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
+		I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
 	}
 
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
@@ -1902,8 +1903,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 					INTEL_OUTPUT_HDMI);
 		}
 		intel_hdmi->set_infoframes(encoder,
-					   crtc->config->has_hdmi_sink,
-					   &crtc->config->base.adjusted_mode);
+					   pipe_config->has_hdmi_sink,
+					   &pipe_config->base.adjusted_mode);
 	}
 }
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (25 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 26/42] drm/i915: Remove use of crtc->config from intel_ddi.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12  9:22   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 28/42] drm/i915: Remove use of crtc->config from intel_dp_mst.c Maarten Lankhorst
                   ` (15 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index eda1b22c3111..e6876faca7f0 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1536,7 +1536,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	enum port port = dp_to_dig_port(intel_dp)->port;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
-	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 
 	/*
 	 * There are four kinds of DP registers:
@@ -1564,7 +1566,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
 	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
 	intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
 
-	if (crtc->config->has_audio)
+	if (pipe_config->has_audio)
 		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
 
 	/* Split out the IBX/CPU vs CPT settings */
@@ -2504,6 +2506,8 @@ static void intel_enable_dp(struct intel_encoder *encoder)
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
 	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 	unsigned int lane_mask = 0x0;
 
@@ -2532,7 +2536,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
 	intel_dp_complete_link_train(intel_dp);
 	intel_dp_stop_link_train(intel_dp);
 
-	if (crtc->config->has_audio) {
+	if (pipe_config->has_audio) {
 		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
 				 pipe_name(crtc->pipe));
 		intel_audio_codec_enable(encoder);
@@ -2741,6 +2745,8 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
 	struct intel_crtc *intel_crtc =
 		to_intel_crtc(encoder->base.crtc);
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
 	int pipe = intel_crtc->pipe;
 	int data, i, stagger;
 	u32 val;
@@ -2782,13 +2788,13 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
 	}
 
 	/* Data lane stagger programming */
-	if (intel_crtc->config->port_clock > 270000)
+	if (pipe_config->port_clock > 270000)
 		stagger = 0x18;
-	else if (intel_crtc->config->port_clock > 135000)
+	else if (pipe_config->port_clock > 135000)
 		stagger = 0xd;
-	else if (intel_crtc->config->port_clock > 67500)
+	else if (pipe_config->port_clock > 67500)
 		stagger = 0x7;
-	else if (intel_crtc->config->port_clock > 33750)
+	else if (pipe_config->port_clock > 33750)
 		stagger = 0x4;
 	else
 		stagger = 0x2;
@@ -4302,7 +4308,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
 	if (WARN_ON(!intel_encoder->base.crtc))
 		return;
 
-	if (!to_intel_crtc(intel_encoder->base.crtc)->active)
+	if (!intel_encoder->base.crtc->state->active)
 		return;
 
 	/* Try to read receiver status if the link appears to be up */
@@ -5255,7 +5261,8 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 	struct intel_encoder *encoder;
 	struct intel_digital_port *dig_port = NULL;
 	struct intel_dp *intel_dp = dev_priv->drrs.dp;
-	struct intel_crtc *intel_crtc = NULL;
+	struct intel_crtc *intel_crtc;
+	struct intel_crtc_state *pipe_config;
 	u32 reg, val;
 	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
 
@@ -5277,6 +5284,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 	dig_port = dp_to_dig_port(intel_dp);
 	encoder = &dig_port->base;
 	intel_crtc = to_intel_crtc(encoder->base.crtc);
+	pipe_config = to_intel_crtc_state(intel_crtc->base.state);
 
 	if (!intel_crtc) {
 		DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
@@ -5298,11 +5306,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 		return;
 	}
 
-	if (!intel_crtc->active) {
-		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
-		return;
-	}
-
 	if (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev)) {
 		switch (index) {
 		case DRRS_HIGH_RR:
@@ -5316,7 +5319,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 			DRM_ERROR("Unsupported refreshrate type\n");
 		}
 	} else if (INTEL_INFO(dev)->gen > 6) {
-		reg = PIPECONF(intel_crtc->config->cpu_transcoder);
+		reg = PIPECONF(pipe_config->cpu_transcoder);
 		val = I915_READ(reg);
 
 		if (index > DRRS_HIGH_RR) {
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 28/42] drm/i915: Remove use of crtc->config from intel_dp_mst.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (26 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 29/42] drm/i915: Remove use of crtc->config from intel_dsi.c Maarten Lankhorst
                   ` (14 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp_mst.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 4992c8025520..4ecbc58c4e04 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -157,7 +157,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	struct intel_connector *found = NULL, *connector;
 	int slots;
 	struct drm_crtc *crtc = encoder->base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 
 	for_each_intel_connector(dev, connector) {
 		if (connector->base.state->best_encoder == &encoder->base) {
@@ -180,7 +181,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 		/* FIXME: add support for SKL */
 		if (INTEL_INFO(dev)->gen < 9)
 			I915_WRITE(PORT_CLK_SEL(port),
-				   intel_crtc->config->ddi_pll_sel);
+				   pipe_config->ddi_pll_sel);
 
 		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
 
@@ -194,7 +195,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 
 	ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
 				       intel_mst->port,
-				       intel_crtc->config->pbn, &slots);
+				       pipe_config->pbn, &slots);
 	if (ret == false) {
 		DRM_ERROR("failed to allocate vcpi\n");
 		return;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 29/42] drm/i915: Remove use of crtc->config from intel_dsi.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (27 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 28/42] drm/i915: Remove use of crtc->config from intel_dp_mst.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c Maarten Lankhorst
                   ` (13 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dsi.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3f28b046751b..ec5f4509dc87 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -692,14 +692,14 @@ static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
 }
 
 static void set_dsi_timings(struct drm_encoder *encoder,
-			    const struct drm_display_mode *mode)
+			    struct intel_crtc_state *pipe_config)
 {
+	const struct drm_display_mode *mode = &pipe_config->base.adjusted_mode;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 	enum port port;
-	unsigned int bpp = intel_crtc->config->pipe_bpp;
+	unsigned int bpp = pipe_config->pipe_bpp;
 	unsigned int lane_count = intel_dsi->lane_count;
 
 	u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp;
@@ -752,11 +752,13 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 	enum port port;
-	unsigned int bpp = intel_crtc->config->pipe_bpp;
+	unsigned int bpp = pipe_config->pipe_bpp;
 	u32 val, tmp;
 	u16 mode_hdisplay;
 
@@ -793,7 +795,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
 			mode_hdisplay << HORIZONTAL_ADDRESS_SHIFT);
 	}
 
-	set_dsi_timings(encoder, adjusted_mode);
+	set_dsi_timings(encoder, pipe_config);
 
 	val = intel_dsi->lane_count << DATA_LANES_PRG_REG_SHIFT;
 	if (is_cmd_mode(intel_dsi)) {
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (28 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 29/42] drm/i915: Remove use of crtc->config from intel_dsi.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12  9:26   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 31/42] drm/i915: Remove use of crtc->config in intel_sdvo.c Maarten Lankhorst
                   ` (12 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 58 +++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 76994dc033a3..9efc3dd62a00 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -345,14 +345,15 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
 	const uint32_t *data = frame;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(encoder->crtc->state);
+	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
 	u32 data_reg;
 	int i;
 	u32 val = I915_READ(ctl_reg);
 
 	data_reg = hsw_infoframe_data_reg(type,
-					  intel_crtc->config->cpu_transcoder,
+					  pipe_config->cpu_transcoder,
 					  dev_priv);
 	if (data_reg == 0)
 		return;
@@ -380,7 +381,9 @@ static bool hsw_infoframe_enabled(struct drm_encoder *encoder)
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
+	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
 	u32 val = I915_READ(ctl_reg);
 
 	return val & (VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_SPD_HSW |
@@ -430,7 +433,8 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
 					 struct drm_display_mode *adjusted_mode)
 {
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(encoder->crtc->state);
 	union hdmi_infoframe frame;
 	int ret;
 
@@ -445,7 +449,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
 	}
 
 	if (intel_hdmi->rgb_quant_range_selectable) {
-		if (intel_crtc->config->limited_color_range)
+		if (pipe_config->limited_color_range)
 			frame.avi.quantization_range =
 				HDMI_QUANTIZATION_RANGE_LIMITED;
 		else
@@ -679,9 +683,10 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
 			       struct drm_display_mode *adjusted_mode)
 {
 	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(encoder->crtc->state);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-	u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
+	u32 reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
 	u32 val = I915_READ(reg);
 
 	assert_hdmi_port_disabled(intel_hdmi);
@@ -709,7 +714,9 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
+	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 	u32 hdmi_val;
 
 	hdmi_val = SDVO_ENCODING_HDMI;
@@ -720,12 +727,12 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
 		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
 
-	if (crtc->config->pipe_bpp > 24)
+	if (pipe_config->pipe_bpp > 24)
 		hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
 	else
 		hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
 
-	if (crtc->config->has_hdmi_sink)
+	if (pipe_config->has_hdmi_sink)
 		hdmi_val |= HDMI_MODE_SELECT_HDMI;
 
 	if (HAS_PCH_CPT(dev))
@@ -819,11 +826,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	u32 temp;
 	u32 enable_bits = SDVO_ENABLE;
 
-	if (intel_crtc->config->has_audio)
+	if (pipe_config->has_audio)
 		enable_bits |= SDVO_AUDIO_ENABLE;
 
 	temp = I915_READ(intel_hdmi->hdmi_reg);
@@ -854,8 +863,8 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
 		POSTING_READ(intel_hdmi->hdmi_reg);
 	}
 
-	if (intel_crtc->config->has_audio) {
-		WARN_ON(!intel_crtc->config->has_hdmi_sink);
+	if (pipe_config->has_audio) {
+		WARN_ON(!pipe_config->has_hdmi_sink);
 		DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
 				 pipe_name(intel_crtc->pipe));
 		intel_audio_codec_enable(encoder);
@@ -1267,14 +1276,15 @@ done:
 static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
 {
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(encoder->base.crtc->state);
 	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 
 	intel_hdmi_prepare(encoder);
 
 	intel_hdmi->set_infoframes(&encoder->base,
-				   intel_crtc->config->has_hdmi_sink,
+				   pipe_config->has_hdmi_sink,
 				   adjusted_mode);
 }
 
@@ -1286,8 +1296,10 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc =
 		to_intel_crtc(encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(intel_crtc->base.state);
 	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	int pipe = intel_crtc->pipe;
 	u32 val;
@@ -1319,7 +1331,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->dpio_lock);
 
 	intel_hdmi->set_infoframes(&encoder->base,
-				   intel_crtc->config->has_hdmi_sink,
+				   pipe_config->has_hdmi_sink,
 				   adjusted_mode);
 
 	intel_enable_hdmi(encoder);
@@ -1531,13 +1543,13 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 	}
 
 	/* Data lane stagger programming */
-	if (intel_crtc->config->port_clock > 270000)
+	if (pipe_config->port_clock > 270000)
 		stagger = 0x18;
-	else if (intel_crtc->config->port_clock > 135000)
+	else if (pipe_config->port_clock > 135000)
 		stagger = 0xd;
-	else if (intel_crtc->config->port_clock > 67500)
+	else if (pipe_config->port_clock > 67500)
 		stagger = 0x7;
-	else if (intel_crtc->config->port_clock > 33750)
+	else if (pipe_config->port_clock > 33750)
 		stagger = 0x4;
 	else
 		stagger = 0x2;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 31/42] drm/i915: Remove use of crtc->config in intel_sdvo.c
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (29 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 32/42] drm/i915: Calculate haswell plane workaround Maarten Lankhorst
                   ` (11 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_sdvo.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 6a68098f8b08..93b31d66a1ab 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -995,7 +995,8 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
 {
 	uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
 	struct drm_crtc *crtc = intel_sdvo->base.base.crtc;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	union hdmi_infoframe frame;
 	int ret;
 	ssize_t len;
@@ -1008,7 +1009,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
 	}
 
 	if (intel_sdvo->rgb_quant_range_selectable) {
-		if (intel_crtc->config->limited_color_range)
+		if (pipe_config->limited_color_range)
 			frame.avi.quantization_range =
 				HDMI_QUANTIZATION_RANGE_LIMITED;
 		else
@@ -1181,9 +1182,11 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
 	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
 	struct drm_display_mode *adjusted_mode =
-		&crtc->config->base.adjusted_mode;
-	struct drm_display_mode *mode = &crtc->config->base.mode;
+		&pipe_config->base.adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->base.mode;
 	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
@@ -1225,7 +1228,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
 	if (!intel_sdvo_set_target_input(intel_sdvo))
 		return;
 
-	if (crtc->config->has_hdmi_sink) {
+	if (pipe_config->has_hdmi_sink) {
 		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
 		intel_sdvo_set_colorimetry(intel_sdvo,
 					   SDVO_COLORIMETRY_RGB256);
@@ -1245,7 +1248,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
 		DRM_INFO("Setting input timings on %s failed\n",
 			 SDVO_NAME(intel_sdvo));
 
-	switch (crtc->config->pixel_multiplier) {
+	switch (pipe_config->pixel_multiplier) {
 	default:
 		WARN(1, "unknown pixel multiplier specified\n");
 	case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
@@ -1260,7 +1263,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
 		/* The real mode polarity is set by the SDVO commands, using
 		 * struct intel_sdvo_dtd. */
 		sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
-		if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
+		if (!HAS_PCH_SPLIT(dev) && pipe_config->limited_color_range)
 			sdvox |= HDMI_COLOR_RANGE_16_235;
 		if (INTEL_INFO(dev)->gen < 5)
 			sdvox |= SDVO_BORDER_ENABLE;
@@ -1290,7 +1293,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
 	} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
 		/* done in crtc_mode_set as it lives inside the dpll register */
 	} else {
-		sdvox |= (crtc->config->pixel_multiplier - 1)
+		sdvox |= (pipe_config->pixel_multiplier - 1)
 			<< SDVO_PORT_MULTIPLY_SHIFT;
 	}
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 32/42] drm/i915: Calculate haswell plane workaround.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (30 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 31/42] drm/i915: Remove use of crtc->config in intel_sdvo.c Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12  9:43   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 33/42] drm/i915: remove crtc->active tracking completely Maarten Lankhorst
                   ` (10 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 109 +++++++++++++++++++++++++----------
 drivers/gpu/drm/i915/intel_drv.h     |   2 +
 2 files changed, 81 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7bc78b49f9f4..7a79659dca00 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4848,35 +4848,6 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
 	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
 }
 
-/*
- * This implements the workaround described in the "notes" section of the mode
- * set sequence documentation. When going from no pipes or single pipe to
- * multiple pipes, and planes are enabled after the pipe, we need to wait at
- * least 2 vblanks on the first pipe before enabling planes on the second pipe.
- */
-static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct intel_crtc *crtc_it, *other_active_crtc = NULL;
-
-	/* We want to get the other_active_crtc only if there's only 1 other
-	 * active crtc. */
-	for_each_intel_crtc(dev, crtc_it) {
-		if (!crtc_it->active || crtc_it == crtc)
-			continue;
-
-		if (other_active_crtc)
-			return;
-
-		other_active_crtc = crtc_it;
-	}
-	if (!other_active_crtc)
-		return;
-
-	intel_wait_for_vblank(dev, other_active_crtc->pipe);
-	intel_wait_for_vblank(dev, other_active_crtc->pipe);
-}
-
 static void haswell_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -4967,7 +4938,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
 	/* If we change the relative order between pipe/planes enabling, we need
 	 * to change the workaround. */
-	haswell_mode_set_planes_workaround(intel_crtc);
+	if (pipe_config->hsw_workaround_pipe != INVALID_PIPE) {
+		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
+		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
+	}
 }
 
 static void ironlake_pfit_disable(struct intel_crtc *crtc)
@@ -12147,6 +12121,74 @@ done:
 	return ret;
 }
 
+/*
+ * This implements the workaround described in the "notes" section of the mode
+ * set sequence documentation. When going from no pipes or single pipe to
+ * multiple pipes, and planes are enabled after the pipe, we need to wait at
+ * least 2 vblanks on the first pipe before enabling planes on the second pipe.
+ */
+static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct intel_crtc_state *first_crtc_state = NULL, *other_crtc_state = NULL;
+	struct intel_crtc *intel_crtc, *first_crtc = NULL, *enabled_crtc;
+	int enabled_crtcs = 0, ret, i;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc_state);
+
+		pipe_config->hsw_workaround_pipe = INVALID_PIPE;
+
+		if (!crtc_state->active)
+			continue;
+
+		if (!needs_modeset(crtc_state)) {
+			enabled_crtcs++;
+			enabled_crtc = to_intel_crtc(crtc);
+			continue;
+		}
+
+		if (first_crtc) {
+			other_crtc_state = pipe_config;
+			break;
+		}
+		first_crtc = to_intel_crtc(crtc);
+		first_crtc_state = pipe_config;
+	}
+
+	/* No workaround needed? */
+	if (!first_crtc || enabled_crtcs > 1)
+		return 0;
+
+	for_each_intel_crtc(state->dev, intel_crtc) {
+		if (state->crtcs[drm_crtc_index(&intel_crtc->base)])
+			continue;
+
+		ret = drm_modeset_lock(&intel_crtc->base.mutex,
+				       state->acquire_ctx);
+		if (ret)
+			return ret;
+
+		if (!intel_crtc->base.state->active)
+			continue;
+
+		/* 2 enabled crtcs means no need for w/a */
+		if (++enabled_crtcs >= 2)
+			return 0;
+
+		enabled_crtc = intel_crtc;
+	}
+
+	if (enabled_crtcs == 1)
+		first_crtc_state->hsw_workaround_pipe = enabled_crtc->pipe;
+	else if (other_crtc_state)
+		other_crtc_state->hsw_workaround_pipe = first_crtc->pipe;
+
+	return 0;
+}
+
 /* Code that should eventually be part of atomic_check() */
 static int __intel_set_mode_checks(struct drm_atomic_state *state)
 {
@@ -12158,6 +12200,13 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
 		return -EINVAL;
 	}
 
+	if (IS_HASWELL(state->dev)) {
+		ret = haswell_mode_set_planes_workaround(state);
+
+		if (ret)
+			return ret;
+	}
+
 	/*
 	 * See if the config requires any additional preparation, e.g.
 	 * to adjust global state with pipes off.  We need to do this
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eb87f82b5aff..6c2ba5dbcd79 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -437,6 +437,8 @@ struct intel_crtc_state {
 	int pbn;
 
 	struct intel_crtc_scaler_state scaler_state;
+
+	enum pipe hsw_workaround_pipe;
 };
 
 struct intel_pipe_wm {
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (31 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 32/42] drm/i915: Calculate haswell plane workaround Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12  9:55   ` Daniel Vetter
  2015-05-12 10:03   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1 Maarten Lankhorst
                   ` (9 subsequent siblings)
  42 siblings, 2 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Small behavioral change: DPLL_DVO_2X_MODE may stay enabled during modeset
for I830 if new state requires it, instead of being disabled and enabled
again.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 140 ++++++++++-------------------------
 drivers/gpu/drm/i915/intel_drv.h     |   6 --
 2 files changed, 40 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7a79659dca00..004067bd0b6c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1680,7 +1680,7 @@ static int intel_num_dvo_pipes(struct drm_device *dev)
 	int count = 0;
 
 	for_each_intel_crtc(dev, crtc)
-		count += crtc->active &&
+		count += crtc->base.state->active &&
 			intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO);
 
 	return count;
@@ -1703,7 +1703,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
 		assert_panel_unlocked(dev_priv, crtc->pipe);
 
 	/* Enable DVO 2x clock on both PLLs if necessary */
-	if (IS_I830(dev) && intel_num_dvo_pipes(dev) > 0) {
+	if (IS_I830(dev) && intel_num_dvo_pipes(dev)) {
 		/*
 		 * It appears to be important that we don't enable this
 		 * for the current pipe before otherwise configuring the
@@ -1762,7 +1762,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc,
 	/* Disable DVO 2x clock on both PLLs if necessary */
 	if (IS_I830(dev) &&
 	    intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) &&
-	    intel_num_dvo_pipes(dev) == 1) {
+	    !intel_num_dvo_pipes(dev)) {
 		I915_WRITE(DPLL(PIPE_B),
 			   I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE);
 		I915_WRITE(DPLL(PIPE_A),
@@ -2583,7 +2583,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 		if (c == &intel_crtc->base)
 			continue;
 
-		if (!i->active)
+		if (!c->state->active)
 			continue;
 
 		fb = c->primary->fb;
@@ -3167,11 +3167,9 @@ static void intel_update_primary_planes(struct drm_device *dev)
 	struct drm_crtc *crtc;
 
 	for_each_crtc(dev, crtc) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
 		drm_modeset_lock(&crtc->mutex, NULL);
 
-		if (intel_crtc->active) {
+		if (crtc->state->active) {
 			const struct intel_plane_state *state =
 				to_intel_plane_state(crtc->primary->state);
 
@@ -4619,7 +4617,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
 	bool reenable_ips = false;
 
 	/* The clocks have to be on to load the palette. */
-	if (!crtc->state->active || !intel_crtc->active)
+	if (!crtc->state->active)
 		return;
 
 	if (HAS_GMCH_DISPLAY(dev_priv->dev)) {
@@ -4778,10 +4776,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	struct intel_crtc_state *pipe_config;
 
-	WARN_ON(!crtc->state->enable);
+	WARN_ON(!crtc->state->active);
 
-	if (WARN_ON(intel_crtc->active))
-		return;
 	pipe_config = to_intel_crtc_state(crtc->state);
 
 	if (pipe_config->has_pch_encoder)
@@ -4799,8 +4795,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 
 	ironlake_set_pipeconf(crtc);
 
-	intel_crtc->active = true;
-
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
 
@@ -4808,7 +4802,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 		if (encoder->pre_enable)
 			encoder->pre_enable(encoder);
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (pipe_config->has_pch_encoder) {
 		/* Note: FDI PLL enabling _must_ be done before we enable the
 		 * cpu pipes, hence this is separate from all the other fdi/pch
 		 * enabling. */
@@ -4859,9 +4853,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
 	WARN_ON(!crtc->state->enable);
 
-	if (WARN_ON(intel_crtc->active))
-		return;
-
 	pipe_config = to_intel_crtc_state(crtc->state);
 	if (intel_crtc_to_shared_dpll(intel_crtc))
 		intel_enable_shared_dpll(intel_crtc);
@@ -4885,8 +4876,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
 	intel_set_pipe_csc(crtc);
 
-	intel_crtc->active = true;
-
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->pre_enable)
@@ -5743,8 +5732,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 
 	WARN_ON(!crtc->state->active);
 
-	if (WARN_ON(intel_crtc->active))
-		return;
 	pipe_config = to_intel_crtc_state(crtc->state);
 
 	is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
@@ -5770,8 +5757,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 
 	i9xx_set_pipeconf(intel_crtc);
 
-	intel_crtc->active = true;
-
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -5824,9 +5809,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 	pipe_config = to_intel_crtc_state(crtc->state);
 	WARN_ON(!pipe_config->base.active);
 
-	if (WARN_ON(intel_crtc->active))
-		return;
-
 	i9xx_set_pll_dividers(intel_crtc);
 
 	if (intel_crtc->config->has_dp_encoder)
@@ -5836,8 +5818,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 
 	i9xx_set_pipeconf(intel_crtc);
 
-	intel_crtc->active = true;
-
 	if (!IS_GEN2(dev))
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
@@ -5930,7 +5910,7 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 	struct drm_atomic_state *state;
 	int ret;
 
-	if (enable == intel_crtc->active)
+	if (enable == crtc->state->active)
 		return;
 
 	if (enable && !crtc->state->enable)
@@ -6045,9 +6025,9 @@ static void intel_connector_check_state(struct intel_connector *connector)
 
 			crtc = encoder->base.crtc;
 
-			I915_STATE_WARN(!crtc->state->active,
+			I915_STATE_WARN(!crtc->state->enable,
 					"crtc not enabled\n");
-			I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
+			I915_STATE_WARN(!crtc->state->active, "crtc not active\n");
 			I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
 			     "encoder active on the wrong pipe\n");
 		}
@@ -8798,7 +8778,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
 	struct intel_crtc *crtc;
 
 	for_each_intel_crtc(dev, crtc)
-		I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
+		I915_STATE_WARN(crtc->base.state->active, "CRTC for pipe %c enabled\n",
 		     pipe_name(crtc->pipe));
 
 	I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
@@ -11738,7 +11718,7 @@ static void check_wm_state(struct drm_device *dev)
 		struct skl_ddb_entry *hw_entry, *sw_entry;
 		const enum pipe pipe = intel_crtc->pipe;
 
-		if (!intel_crtc->active)
+		if (!intel_crtc->base.state->active)
 			continue;
 
 		/* planes */
@@ -11871,9 +11851,6 @@ check_crtc_state(struct drm_device *dev)
 		DRM_DEBUG_KMS("[CRTC:%d]\n",
 			      crtc->base.base.id);
 
-		I915_STATE_WARN(crtc->active && !crtc->base.state->enable,
-		     "active crtc, but not enabled in sw tracking\n");
-
 		for_each_intel_encoder(dev, encoder) {
 			if (encoder->base.crtc != &crtc->base)
 				continue;
@@ -11882,9 +11859,9 @@ check_crtc_state(struct drm_device *dev)
 				active = true;
 		}
 
-		I915_STATE_WARN(active != crtc->active,
+		I915_STATE_WARN(active != crtc->base.state->active,
 		     "crtc's computed active state doesn't match tracked active state "
-		     "(expected %i, found %i)\n", active, crtc->active);
+		     "(expected %i, found %i)\n", active, crtc->base.state->active);
 		I915_STATE_WARN(enabled != crtc->base.state->enable,
 		     "crtc's computed enabled state doesn't match tracked enabled state "
 		     "(expected %i, found %i)\n", enabled,
@@ -11896,7 +11873,7 @@ check_crtc_state(struct drm_device *dev)
 		/* hw state is inconsistent with the pipe quirk */
 		if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
 		    (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
-			active = crtc->active;
+			active = crtc->base.state->active;
 
 		for_each_intel_encoder(dev, encoder) {
 			enum pipe pipe;
@@ -11906,9 +11883,9 @@ check_crtc_state(struct drm_device *dev)
 				encoder->get_config(encoder, &pipe_config);
 		}
 
-		I915_STATE_WARN(crtc->active != active,
+		I915_STATE_WARN(crtc->base.state->active != active,
 		     "crtc active state doesn't match with hw state "
-		     "(expected %i, found %i)\n", crtc->active, active);
+		     "(expected %i, found %i)\n", crtc->base.state->active, active);
 
 		if (active &&
 		    !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
@@ -11931,7 +11908,7 @@ check_shared_dpll_state(struct drm_device *dev)
 
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
-		int enabled_crtcs = 0, active_crtcs = 0;
+		int active_crtcs = 0;
 		bool active;
 
 		memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
@@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
 
 		for_each_intel_crtc(dev, crtc) {
 			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
-				enabled_crtcs++;
-			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
 				active_crtcs++;
 		}
 		I915_STATE_WARN(pll->active != active_crtcs,
 		     "pll active crtcs mismatch (expected %i, found %i)\n",
 		     pll->active, active_crtcs);
-		I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
+		I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
 		     "pll enabled crtcs mismatch (expected %i, found %i)\n",
-		     hweight32(pll->config.crtc_mask), enabled_crtcs);
+		     hweight32(pll->config.crtc_mask), active_crtcs);
 
 		I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state,
 				       sizeof(dpll_hw_state)),
@@ -12264,10 +12239,10 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
 		to_intel_plane_state(plane->state)->hw_enabled = false;
 		DRM_DEBUG_ATOMIC("Plane %i is visible: %i\n", i, visible);
 
-		if (!visible)
+		if (crtc && needs_modeset(crtc->state))
+			intel_plane->disable_plane(plane, crtc, !visible);
+		else if (!visible)
 			funcs->atomic_update(plane, old_plane_state);
-		else if (needs_modeset(crtc->state))
-			intel_plane->disable_plane(plane, crtc, true);
 	}
 }
 
@@ -12349,8 +12324,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
 		dev_priv->display.crtc_disable(crtc, pipe_config);
 
-		intel_crtc->active = false;
-
 		if (intel_crtc_to_shared_dpll(intel_crtc))
 			intel_disable_shared_dpll(intel_crtc);
 	}
@@ -13035,11 +13008,9 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
 	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
 	intel_crtc->atomic.update_wm = mode_changed;
 	intel_crtc->atomic.disable_fbc = mode_changed;
+	intel_crtc->atomic.evade = !mode_changed && was_crtc_enabled;
 
 	idx = crtc->base.id;
-	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
-		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
-		idx, crtc->state->active, intel_crtc->active);
 
 	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
 			 idx, was_crtc_enabled, is_crtc_enabled);
@@ -13229,7 +13200,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 	intel_runtime_pm_get(dev_priv);
 
 	/* Perform vblank evasion around commit operation */
-	if (intel_crtc->active && !needs_modeset(crtc->state) &&
+	if (intel_crtc->atomic.evade &&
 	    !dev_priv->power_domains.init_power_on)
 		intel_crtc->atomic.evade =
 			intel_pipe_update_start(intel_crtc,
@@ -14537,7 +14508,7 @@ void intel_modeset_init(struct drm_device *dev)
 	drm_modeset_unlock_all(dev);
 
 	for_each_intel_crtc(dev, crtc) {
-		if (!crtc->active)
+		if (!crtc->base.state->active)
 			continue;
 
 		/*
@@ -14615,7 +14586,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 
 	/* restore vblank interrupts to correct state */
 	drm_crtc_vblank_reset(&crtc->base);
-	if (crtc->active) {
+	if (crtc->base.state->active) {
 		update_scanline_offset(crtc);
 		drm_crtc_vblank_on(&crtc->base);
 	}
@@ -14655,14 +14626,14 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 				connector->encoder->connectors_active = false;
 			}
 
-		WARN_ON(crtc->active);
+		WARN_ON(crtc->base.state->active);
 		crtc->base.state->enable = false;
 		crtc->base.state->active = false;
 		crtc->base.enabled = false;
 	}
 
 	if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
-	    crtc->pipe == PIPE_A && !crtc->active) {
+	    crtc->pipe == PIPE_A && !crtc->base.state->active) {
 		/* BIOS forgot to enable pipe A, this mostly happens after
 		 * resume. Force-enable the pipe to fix this, the update_dpms
 		 * call below we restore the pipe to the right state, but leave
@@ -14674,35 +14645,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 	 * have active connectors/encoders. */
 	intel_crtc_update_dpms(&crtc->base);
 
-	if (crtc->active != crtc->base.state->active) {
-		struct intel_encoder *encoder;
-
-		/* This can happen either due to bugs in the get_hw_state
-		 * functions or because the pipe is force-enabled due to the
-		 * pipe A quirk. */
-		DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
-			      crtc->base.base.id,
-			      crtc->base.state->enable ? "enabled" : "disabled",
-			      crtc->active ? "enabled" : "disabled");
-
-		crtc->base.state->enable = crtc->active;
-		crtc->base.state->active = crtc->active;
-		crtc->base.enabled = crtc->active;
-
-		/* Because we only establish the connector -> encoder ->
-		 * crtc links if something is active, this means the
-		 * crtc is now deactivated. Break the links. connector
-		 * -> encoder links are only establish when things are
-		 *  actually up, hence no need to break them. */
-		WARN_ON(crtc->active);
-
-		for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
-			WARN_ON(encoder->connectors_active);
-			encoder->base.crtc = NULL;
-		}
-	}
-
-	if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
+	if (crtc->base.state->active || HAS_GMCH_DISPLAY(dev)) {
 		/*
 		 * We start out with underrun reporting disabled to avoid races.
 		 * For correct bookkeeping mark this on active crtcs.
@@ -14730,7 +14673,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 	/* We need to check both for a crtc link (meaning that the
 	 * encoder is active and trying to read from a pipe) and the
 	 * pipe itself being active. */
-	bool has_active_crtc = crtc && to_intel_crtc(crtc)->active;
+	bool has_active_crtc = crtc && crtc->state->active;
 
 	if (encoder->connectors_active && !has_active_crtc) {
 		DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
@@ -14800,7 +14743,7 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 
-	if (!crtc->active)
+	if (!crtc->base.state->active)
 		return false;
 
 	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
@@ -14828,12 +14771,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 		if (crtc->base.state->active)
 			*crtc_mask |= drm_crtc_index(&crtc->base);
 
-		crtc->active = dev_priv->display.get_pipe_config(crtc,
-								 crtc->config);
-
-		crtc->base.state->enable = crtc->active;
-		crtc->base.state->active = crtc->active;
-		crtc->base.enabled = crtc->active;
+		crtc->base.enabled = crtc->base.state->enable =
+		crtc->base.state->active =
+			dev_priv->display.get_pipe_config(crtc, crtc->config);
 
 		plane_state = to_intel_plane_state(primary->state);
 		plane_state->hw_enabled = plane_state->visible =
@@ -14847,7 +14787,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 
 		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
 			      crtc->base.base.id,
-			      crtc->active ? "enabled" : "disabled");
+			      crtc->base.state->active ? "enabled" : "disabled");
 	}
 
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
@@ -14858,7 +14798,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 		pll->active = 0;
 		pll->config.crtc_mask = 0;
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) {
+			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll) {
 				pll->active++;
 				pll->config.crtc_mask |= 1 << crtc->pipe;
 			}
@@ -14927,9 +14867,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 	 * checking everywhere.
 	 */
 	for_each_intel_crtc(dev, crtc) {
-		if (crtc->active && i915.fastboot) {
+		if (crtc->base.state->active && i915.fastboot) {
 			intel_mode_from_pipe_config(&crtc->base.mode,
-						    crtc->config);
+				to_intel_crtc_state(crtc->base.state));
 			DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
 				      crtc->base.base.id);
 			drm_mode_debug_printmodeline(&crtc->base.mode);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6c2ba5dbcd79..1a0b0cd857c3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -492,12 +492,6 @@ struct intel_crtc {
 	enum pipe pipe;
 	enum plane plane;
 	u8 lut_r[256], lut_g[256], lut_b[256];
-	/*
-	 * Whether the crtc and the connected output pipeline is active. Implies
-	 * that crtc->enabled is set, i.e. the current mode configuration has
-	 * some outputs connected to this crtc.
-	 */
-	bool active;
 	unsigned long enabled_power_domains;
 	bool lowfreq_avail;
 	struct intel_overlay *overlay;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (32 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 33/42] drm/i915: remove crtc->active tracking completely Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12 10:11   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2 Maarten Lankhorst
                   ` (8 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Removed some occurences, roughly based on where the errors of
removing crtc->config occured. Because it's used a lot in this
file the changes are done in passes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 205 ++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_drv.h     |   4 +-
 drivers/gpu/drm/i915/intel_lvds.c    |   2 +-
 3 files changed, 105 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 004067bd0b6c..fb2ecb65aaaa 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1141,29 +1141,20 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
 #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
 #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
 
-struct intel_shared_dpll *
-intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
-{
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-
-	if (crtc->config->shared_dpll < 0)
-		return NULL;
-
-	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
-}
-
 /* For ILK+ */
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
-			struct intel_shared_dpll *pll,
+			enum intel_dpll_id shared_dpll,
 			bool state)
 {
-	bool cur_state;
 	struct intel_dpll_hw_state hw_state;
+	struct intel_shared_dpll *pll;
+	bool cur_state;
 
-	if (WARN (!pll,
+	if (WARN(shared_dpll < 0,
 		  "asserting DPLL %s with no DPLL\n", state_string(state)))
 		return;
 
+	pll = &dev_priv->shared_dplls[shared_dpll];
 	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
 	I915_STATE_WARN(cur_state != state,
 	     "%s assertion failure (expected %s, current %s)\n",
@@ -1691,7 +1682,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int reg = DPLL(crtc->pipe);
-	u32 dpll = crtc->config->dpll_hw_state.dpll;
+	u32 dpll = pipe_config->dpll_hw_state.dpll;
 
 	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
 
@@ -1721,7 +1712,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
 
 	if (INTEL_INFO(dev)->gen >= 4) {
 		I915_WRITE(DPLL_MD(crtc->pipe),
-			   crtc->config->dpll_hw_state.dpll_md);
+			   pipe_config->dpll_hw_state.dpll_md);
 	} else {
 		/* The pixel multiplier can only be updated once the
 		 * DPLL is enabled and the clocks are stable.
@@ -1859,20 +1850,19 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
 		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
 }
 
-static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
+static void intel_prepare_shared_dpll(struct drm_i915_private *dev_priv,
+				      enum intel_dpll_id shared_dpll)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
 
-	if (WARN_ON(pll == NULL))
+	if (WARN_ON(shared_dpll < 0))
 		return;
 
 	WARN_ON(!pll->config.crtc_mask);
 	if (pll->active == 0) {
 		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
 		WARN_ON(pll->on);
-		assert_shared_dpll_disabled(dev_priv, pll);
+		assert_shared_dpll_disabled(dev_priv, shared_dpll);
 
 		pll->mode_set(dev_priv, pll);
 	}
@@ -1886,25 +1876,23 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
  * The PCH PLL needs to be enabled before the PCH transcoder, since it
  * drives the transcoder clock.
  */
-static void intel_enable_shared_dpll(struct intel_crtc *crtc)
+static void intel_enable_shared_dpll(struct drm_i915_private *dev_priv,
+				     enum intel_dpll_id shared_dpll)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
 
-	if (WARN_ON(pll == NULL))
+	if (WARN_ON(shared_dpll < 0))
 		return;
 
 	if (WARN_ON(pll->config.crtc_mask == 0))
 		return;
 
-	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
-		      pll->name, pll->active, pll->on,
-		      crtc->base.base.id);
+	DRM_DEBUG_KMS("enable %s (active %d, on? %d)\n",
+		      pll->name, pll->active, pll->on);
 
 	if (pll->active++) {
 		WARN_ON(!pll->on);
-		assert_shared_dpll_enabled(dev_priv, pll);
+		assert_shared_dpll_enabled(dev_priv, shared_dpll);
 		return;
 	}
 	WARN_ON(pll->on);
@@ -1916,30 +1904,29 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
 	pll->on = true;
 }
 
-static void intel_disable_shared_dpll(struct intel_crtc *crtc)
+static void intel_disable_shared_dpll(struct drm_i915_private *dev_priv,
+				      enum intel_dpll_id shared_dpll)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
+
+	if (shared_dpll < 0)
+		return;
 
 	/* PCH only available on ILK+ */
-	BUG_ON(INTEL_INFO(dev)->gen < 5);
-	if (WARN_ON(pll == NULL))
-	       return;
+	BUG_ON(dev_priv->info.gen < 5);
 
 	if (WARN_ON(pll->config.crtc_mask == 0))
 		return;
 
-	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
-		      pll->name, pll->active, pll->on,
-		      crtc->base.base.id);
+	DRM_DEBUG_KMS("disable %s (active %d, on? %d)\n",
+		      pll->name, pll->active, pll->on);
 
 	if (WARN_ON(pll->active == 0)) {
-		assert_shared_dpll_disabled(dev_priv, pll);
+		assert_shared_dpll_disabled(dev_priv, shared_dpll);
 		return;
 	}
 
-	assert_shared_dpll_enabled(dev_priv, pll);
+	assert_shared_dpll_enabled(dev_priv, shared_dpll);
 	WARN_ON(!pll->on);
 	if (--pll->active)
 		return;
@@ -1964,8 +1951,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 	BUG_ON(!HAS_PCH_SPLIT(dev));
 
 	/* Make sure PCH DPLL is enabled */
-	assert_shared_dpll_enabled(dev_priv,
-				   intel_crtc_to_shared_dpll(intel_crtc));
+	assert_shared_dpll_enabled(dev_priv, pipe_config->shared_dpll);
 
 	/* FDI must be feeding us bits for PCH ports */
 	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
@@ -2126,7 +2112,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
 		else
 			assert_pll_enabled(dev_priv, pipe);
 	else {
-		if (crtc->config->has_pch_encoder) {
+		if (pipe_config->has_pch_encoder) {
 			/* if driving the PCH, we need FDI enabled */
 			assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
 			assert_fdi_tx_pll_enabled(dev_priv,
@@ -2622,6 +2608,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	bool visible = to_intel_plane_state(primary->state)->visible;
 	struct drm_i915_gem_object *obj;
 	int plane = intel_crtc->plane;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
@@ -2655,13 +2643,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 		 * which should always be the user's requested size.
 		 */
 		I915_WRITE(DSPSIZE(plane),
-			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
-			   (intel_crtc->config->pipe_src_w - 1));
+			   ((pipe_config->pipe_src_h - 1) << 16) |
+			   (pipe_config->pipe_src_w - 1));
 		I915_WRITE(DSPPOS(plane), 0);
 	} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
 		I915_WRITE(PRIMSIZE(plane),
-			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
-			   (intel_crtc->config->pipe_src_w - 1));
+			   ((pipe_config->pipe_src_h - 1) << 16) |
+			   (pipe_config->pipe_src_w - 1));
 		I915_WRITE(PRIMPOS(plane), 0);
 		I915_WRITE(PRIMCNSTALPHA(plane), 0);
 	}
@@ -2719,14 +2707,14 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
 		dspcntr |= DISPPLANE_ROTATE_180;
 
-		x += (intel_crtc->config->pipe_src_w - 1);
-		y += (intel_crtc->config->pipe_src_h - 1);
+		x += (pipe_config->pipe_src_w - 1);
+		y += (pipe_config->pipe_src_h - 1);
 
 		/* Finding the last pixel of the last line of the display
 		data and adding to linear_offset*/
 		linear_offset +=
-			(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
-			(intel_crtc->config->pipe_src_w - 1) * pixel_size;
+			(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
+			(pipe_config->pipe_src_w - 1) * pixel_size;
 	}
 
 	I915_WRITE(reg, dspcntr);
@@ -2818,17 +2806,20 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 					       fb->pitches[0]);
 	linear_offset -= intel_crtc->dspaddr_offset;
 	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc->state);
+
 		dspcntr |= DISPPLANE_ROTATE_180;
 
 		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
-			x += (intel_crtc->config->pipe_src_w - 1);
-			y += (intel_crtc->config->pipe_src_h - 1);
+			x += (pipe_config->pipe_src_w - 1);
+			y += (pipe_config->pipe_src_h - 1);
 
 			/* Finding the last pixel of the last line of the display
 			data and adding to linear_offset*/
 			linear_offset +=
-				(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
-				(intel_crtc->config->pipe_src_w - 1) * pixel_size;
+				(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
+				(pipe_config->pipe_src_w - 1) * pixel_size;
 		}
 	}
 
@@ -2901,12 +2892,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
 	struct intel_crtc_scaler_state *scaler_state;
 	int i;
 
-	if (!intel_crtc || !intel_crtc->config)
+	if (!intel_crtc)
 		return;
 
 	dev = intel_crtc->base.dev;
 	dev_priv = dev->dev_private;
-	scaler_state = &intel_crtc->config->scaler_state;
+	scaler_state =
+		&to_intel_crtc_state(intel_crtc->base.state)->scaler_state;
 
 	/* loop through and disable scalers that aren't in use */
 	for (i = 0; i < intel_crtc->num_scalers; i++) {
@@ -3298,6 +3290,8 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const struct drm_display_mode *adjusted_mode;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->base.state);
 
 	if (!i915.fastboot)
 		return;
@@ -3316,20 +3310,20 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
 	 * then update the pipesrc and pfit state, even on the flip path.
 	 */
 
-	adjusted_mode = &crtc->config->base.adjusted_mode;
+	adjusted_mode = &pipe_config->base.adjusted_mode;
 
 	I915_WRITE(PIPESRC(crtc->pipe),
 		   ((adjusted_mode->crtc_hdisplay - 1) << 16) |
 		   (adjusted_mode->crtc_vdisplay - 1));
-	if (!crtc->config->pch_pfit.enabled &&
+	if (!pipe_config->pch_pfit.enabled &&
 	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
 	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
 		I915_WRITE(PF_CTL(crtc->pipe), 0);
 		I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
 		I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
 	}
-	crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
-	crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
+	pipe_config->pipe_src_w = adjusted_mode->crtc_hdisplay;
+	pipe_config->pipe_src_h = adjusted_mode->crtc_vdisplay;
 }
 
 static void intel_fdi_normal_train(struct drm_crtc *crtc)
@@ -3379,6 +3373,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp, tries;
 
@@ -3396,7 +3392,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
 	temp &= ~FDI_DP_PORT_WIDTH_MASK;
-	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
 	temp &= ~FDI_LINK_TRAIN_NONE;
 	temp |= FDI_LINK_TRAIN_PATTERN_1;
 	I915_WRITE(reg, temp | FDI_TX_ENABLE);
@@ -3476,6 +3472,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp, i, retry;
 
@@ -3494,7 +3492,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
 	temp &= ~FDI_DP_PORT_WIDTH_MASK;
-	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
 	temp &= ~FDI_LINK_TRAIN_NONE;
 	temp |= FDI_LINK_TRAIN_PATTERN_1;
 	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
@@ -3608,6 +3606,8 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	int pipe = intel_crtc->pipe;
 	u32 reg, temp, i, j;
 
@@ -3645,7 +3645,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
 		reg = FDI_TX_CTL(pipe);
 		temp = I915_READ(reg);
 		temp &= ~FDI_DP_PORT_WIDTH_MASK;
-		temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
+		temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
 		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
 		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 		temp |= snb_b_fdi_train_param[j/2];
@@ -3914,11 +3914,10 @@ void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 }
 
 /* Program iCLKIP clock to the desired frequency */
-static void lpt_program_iclkip(struct drm_crtc *crtc)
+static void lpt_program_iclkip(struct drm_i915_private *dev_priv,
+			       struct intel_crtc_state *pipe_config)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
+	int clock = pipe_config->base.adjusted_mode.crtc_clock;
 	u32 divsel, phaseinc, auxdiv, phasedir = 0;
 	u32 temp;
 
@@ -4002,13 +4001,10 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
 	mutex_unlock(&dev_priv->dpio_lock);
 }
 
-static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
+static void ironlake_pch_transcoder_set_timings(struct drm_i915_private *dev_priv,
+						enum transcoder cpu_transcoder,
 						enum pipe pch_transcoder)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
-
 	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
 		   I915_READ(HTOTAL(cpu_transcoder)));
 	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
@@ -4026,7 +4022,8 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
 		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
 }
 
-static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
+static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev,
+				       bool enable)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t temp;
@@ -4047,15 +4044,15 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
 	POSTING_READ(SOUTH_CHICKEN1);
 }
 
-static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
+static void ivybridge_update_fdi_bc_bifurcation(struct drm_device *dev,
+					struct intel_crtc *intel_crtc,
+					struct intel_crtc_state *pipe_config)
 {
-	struct drm_device *dev = intel_crtc->base.dev;
-
 	switch (intel_crtc->pipe) {
 	case PIPE_A:
 		break;
 	case PIPE_B:
-		if (intel_crtc->config->fdi_lanes > 2)
+		if (pipe_config->fdi_lanes > 2)
 			cpt_set_fdi_bc_bifurcation(dev, false);
 		else
 			cpt_set_fdi_bc_bifurcation(dev, true);
@@ -4078,7 +4075,8 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
  *   - DP transcoding bits
  *   - transcoder
  */
-static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
+static void ironlake_pch_enable(struct drm_crtc *crtc,
+				struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4089,7 +4087,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
 	assert_pch_transcoder_disabled(dev_priv, pipe);
 
 	if (IS_IVYBRIDGE(dev))
-		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
+		ivybridge_update_fdi_bc_bifurcation(dev, intel_crtc,
+						    pipe_config);
 
 	/* Write the TU size bits before fdi link training, so that error
 	 * detection works. */
@@ -4121,11 +4120,12 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
 	 * Note that enable_shared_dpll tries to do the right thing, but
 	 * get_shared_dpll unconditionally resets the pll - we need that to have
 	 * the right LVDS enable sequence. */
-	intel_enable_shared_dpll(intel_crtc);
+	intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
 
 	/* set transcoder timing, panel must allow it */
 	assert_panel_unlocked(dev_priv, pipe);
-	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
+	ironlake_pch_transcoder_set_timings(dev_priv,
+					    pipe_config->cpu_transcoder, pipe);
 
 	intel_fdi_normal_train(crtc);
 
@@ -4166,19 +4166,17 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
 	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
 }
 
-static void lpt_pch_enable(struct drm_crtc *crtc)
+static void lpt_pch_enable(struct drm_i915_private *dev_priv,
+			   struct intel_crtc_state *pipe_config)
 {
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 
 	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
 
-	lpt_program_iclkip(crtc);
+	lpt_program_iclkip(dev_priv, pipe_config);
 
 	/* Set transcoder timing. */
-	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
+	ironlake_pch_transcoder_set_timings(dev_priv, cpu_transcoder, PIPE_A);
 
 	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
@@ -4781,7 +4779,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	pipe_config = to_intel_crtc_state(crtc->state);
 
 	if (pipe_config->has_pch_encoder)
-		intel_prepare_shared_dpll(intel_crtc);
+		intel_prepare_shared_dpll(dev_priv,
+					  pipe_config->shared_dpll);
 
 	if (pipe_config->has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc, M1_N1);
@@ -4854,8 +4853,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	WARN_ON(!crtc->state->enable);
 
 	pipe_config = to_intel_crtc_state(crtc->state);
-	if (intel_crtc_to_shared_dpll(intel_crtc))
-		intel_enable_shared_dpll(intel_crtc);
+	if (pipe_config->shared_dpll >= 0)
+		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
 
 	if (pipe_config->has_dp_encoder)
 		intel_dp_set_m_n(intel_crtc, M1_N1);
@@ -4910,7 +4909,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_enable_pipe(intel_crtc);
 
 	if (intel_crtc->config->has_pch_encoder)
-		lpt_pch_enable(crtc);
+		lpt_pch_enable(dev_priv, pipe_config);
 
 	if (intel_crtc->config->dp_encoder_is_mst)
 		intel_ddi_set_vc_payload_alloc(crtc,
@@ -11929,7 +11928,8 @@ check_shared_dpll_state(struct drm_device *dev)
 		     pll->on, active);
 
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
+			if (crtc->base.state->active &&
+			    to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
 				active_crtcs++;
 		}
 		I915_STATE_WARN(pll->active != active_crtcs,
@@ -12311,7 +12311,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 	__intel_set_mode_update_planes(dev, state);
 
 	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 		struct intel_crtc_state *pipe_config;
 
 		if (!needs_modeset(crtc->state))
@@ -12324,8 +12323,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
 		dev_priv->display.crtc_disable(crtc, pipe_config);
 
-		if (intel_crtc_to_shared_dpll(intel_crtc))
-			intel_disable_shared_dpll(intel_crtc);
+		intel_disable_shared_dpll(dev_priv, pipe_config->shared_dpll);
 	}
 
 	/* Only after disabling all output pipelines that will be changed can we
@@ -12719,7 +12717,9 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
 
 	/* Make sure no transcoder isn't still depending on us. */
 	for_each_intel_crtc(dev, crtc) {
-		if (intel_crtc_to_shared_dpll(crtc) == pll)
+		int i = pll - dev_priv->shared_dplls;
+
+		if (to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
 			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
 	}
 
@@ -14798,7 +14798,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 		pll->active = 0;
 		pll->config.crtc_mask = 0;
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll) {
+			if (crtc->base.state->active &&
+			    i == to_intel_crtc_state(crtc->base.state)->shared_dpll) {
 				pll->active++;
 				pll->config.crtc_mask |= 1 << crtc->pipe;
 			}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1a0b0cd857c3..7979a2f6838c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1058,10 +1058,8 @@ bool intel_wm_need_update(struct drm_plane *plane,
 			  struct drm_plane_state *state);
 
 /* shared dpll functions */
-struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
-			struct intel_shared_dpll *pll,
-			bool state);
+			enum intel_dpll_id, bool state);
 #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,
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 8aaaa24144f0..52788ed6f775 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -149,7 +149,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
 	if (HAS_PCH_SPLIT(dev)) {
 		assert_fdi_rx_pll_disabled(dev_priv, pipe);
 		assert_shared_dpll_disabled(dev_priv,
-					    intel_crtc_to_shared_dpll(crtc));
+					    pipe_config->shared_dpll);
 	} else {
 		assert_pll_disabled(dev_priv, pipe);
 	}
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (33 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1 Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12 10:17   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 36/42] drm/i915: get rid of crtc->config Maarten Lankhorst
                   ` (7 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Convert the rest of the file, but remove crtc->config in a separate
commit to hopefully allow easier bisecting.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 351 ++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_dp.c      |   4 +-
 drivers/gpu/drm/i915/intel_drv.h     |   4 +-
 3 files changed, 186 insertions(+), 173 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fb2ecb65aaaa..2c467cda74a4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -88,14 +88,20 @@ static int intel_framebuffer_init(struct drm_device *dev,
 				  struct intel_framebuffer *ifb,
 				  struct drm_mode_fb_cmd2 *mode_cmd,
 				  struct drm_i915_gem_object *obj);
-static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
-static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
+static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc,
+			      struct intel_crtc_state *pipe_config);
+static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
+				   struct intel_crtc_state *pipe_config);
 static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_crtc_state *pipe_config,
 					 struct intel_link_m_n *m_n,
 					 struct intel_link_m_n *m2_n2);
-static void ironlake_set_pipeconf(struct drm_crtc *crtc);
-static void haswell_set_pipeconf(struct drm_crtc *crtc);
-static void intel_set_pipe_csc(struct drm_crtc *crtc);
+static void ironlake_set_pipeconf(struct drm_crtc *crtc,
+				  struct intel_crtc_state *pipe_config);
+static void haswell_set_pipeconf(struct drm_crtc *crtc,
+				 struct intel_crtc_state *pipe_config);
+static void intel_set_pipe_csc(struct drm_crtc *crtc,
+			       struct intel_crtc_state *pipe_config);
 static void vlv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
 static void chv_prepare_pll(struct intel_crtc *crtc,
@@ -3021,7 +3027,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned int rotation;
 	int x_offset, y_offset;
 	unsigned long surf_addr;
-	struct intel_crtc_state *crtc_state = intel_crtc->config;
+	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->state);
 	struct intel_plane_state *plane_state;
 	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
 	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
@@ -3052,27 +3058,17 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
 					       fb->pixel_format);
 	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
 
-	/*
-	 * FIXME: intel_plane_state->src, dst aren't set when transitional
-	 * update_plane helpers are called from legacy paths.
-	 * Once full atomic crtc is available, below check can be avoided.
-	 */
-	if (drm_rect_width(&plane_state->src)) {
-		scaler_id = plane_state->scaler_id;
-		src_x = plane_state->src.x1 >> 16;
-		src_y = plane_state->src.y1 >> 16;
-		src_w = drm_rect_width(&plane_state->src) >> 16;
-		src_h = drm_rect_height(&plane_state->src) >> 16;
-		dst_x = plane_state->dst.x1;
-		dst_y = plane_state->dst.y1;
-		dst_w = drm_rect_width(&plane_state->dst);
-		dst_h = drm_rect_height(&plane_state->dst);
+	scaler_id = plane_state->scaler_id;
+	src_x = plane_state->src.x1 >> 16;
+	src_y = plane_state->src.y1 >> 16;
+	src_w = drm_rect_width(&plane_state->src) >> 16;
+	src_h = drm_rect_height(&plane_state->src) >> 16;
+	dst_x = plane_state->dst.x1;
+	dst_y = plane_state->dst.y1;
+	dst_w = drm_rect_width(&plane_state->dst);
+	dst_h = drm_rect_height(&plane_state->dst);
 
-		WARN_ON(x != src_x || y != src_y);
-	} else {
-		src_w = intel_crtc->config->pipe_src_w;
-		src_h = intel_crtc->config->pipe_src_h;
-	}
+	WARN_ON(x != src_x || y != src_y);
 
 	if (intel_rotation_90_or_270(rotation)) {
 		/* stride = Surface height in tiles */
@@ -4489,27 +4485,29 @@ skl_update_scaler_users(
 	return 0;
 }
 
-static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
+static void skylake_pfit_update(struct intel_crtc *crtc,
+				struct intel_crtc_state *pipe_config,
+				int enable)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe = crtc->pipe;
 	struct intel_crtc_scaler_state *scaler_state =
-		&crtc->config->scaler_state;
+		&pipe_config->scaler_state;
 
-	DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
+	DRM_DEBUG_KMS("for crtc_state = %p\n", pipe_config);
 
 	/* To update pfit, first update scaler state */
-	skl_update_scaler_users(crtc, crtc->config, NULL, NULL, !enable);
-	intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
+	skl_update_scaler_users(crtc, pipe_config, NULL, NULL, !enable);
+	intel_atomic_setup_scalers(crtc->base.dev, crtc, pipe_config);
 	skl_detach_scalers(crtc);
 	if (!enable)
 		return;
 
-	if (crtc->config->pch_pfit.enabled) {
+	if (pipe_config->pch_pfit.enabled) {
 		int id;
 
-		if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
+		if (WARN_ON(pipe_config->scaler_state.scaler_id < 0)) {
 			DRM_ERROR("Requesting pfit without getting a scaler first\n");
 			return;
 		}
@@ -4517,20 +4515,21 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
 		id = scaler_state->scaler_id;
 		I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
 			PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
-		I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
-		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
+		I915_WRITE(SKL_PS_WIN_POS(pipe, id), pipe_config->pch_pfit.pos);
+		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), pipe_config->pch_pfit.size);
 
-		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
+		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", pipe_config, id);
 	}
 }
 
-static void ironlake_pfit_enable(struct intel_crtc *crtc)
+static void ironlake_pfit_enable(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;
 	int pipe = crtc->pipe;
 
-	if (crtc->config->pch_pfit.enabled) {
+	if (pipe_config->pch_pfit.enabled) {
 		/* Force use of hard-coded filter coefficients
 		 * as some pre-programmed values are broken,
 		 * e.g. x201.
@@ -4540,8 +4539,8 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
 						 PF_PIPE_SEL_IVB(pipe));
 		else
 			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
-		I915_WRITE(PF_WIN_POS(pipe), crtc->config->pch_pfit.pos);
-		I915_WRITE(PF_WIN_SZ(pipe), crtc->config->pch_pfit.size);
+		I915_WRITE(PF_WIN_POS(pipe), pipe_config->pch_pfit.pos);
+		I915_WRITE(PF_WIN_SZ(pipe), pipe_config->pch_pfit.size);
 	}
 }
 
@@ -4550,7 +4549,7 @@ 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_enabled)
+	if (!to_intel_crtc_state(crtc->base.state)->ips_enabled)
 		return;
 
 	/* We can only enable IPS after we enable a plane and wait for a vblank */
@@ -4583,7 +4582,7 @@ 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_enabled)
+	if (!to_intel_crtc_state(crtc->base.state)->ips_enabled)
 		return;
 
 	assert_plane_enabled(dev_priv, crtc->plane);
@@ -4632,7 +4631,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
 	/* Workaround : Do not read or write the pipe palette/gamma data while
 	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
 	 */
-	if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
+	if (IS_HASWELL(dev) && to_intel_crtc_state(crtc->state)->ips_enabled &&
 	    ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
 	     GAMMA_MODE_MODE_SPLIT)) {
 		hsw_disable_ips(intel_crtc);
@@ -4783,16 +4782,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 					  pipe_config->shared_dpll);
 
 	if (pipe_config->has_dp_encoder)
-		intel_dp_set_m_n(intel_crtc, M1_N1);
+		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
 
-	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_timings(intel_crtc, pipe_config);
 
 	if (pipe_config->has_pch_encoder) {
-		intel_cpu_transcoder_set_m_n(intel_crtc,
+		intel_cpu_transcoder_set_m_n(intel_crtc, pipe_config,
 				     &pipe_config->fdi_m_n, NULL);
 	}
 
-	ironlake_set_pipeconf(crtc);
+	ironlake_set_pipeconf(crtc, pipe_config);
 
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
@@ -4811,7 +4810,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 		assert_fdi_rx_disabled(dev_priv, pipe);
 	}
 
-	ironlake_pfit_enable(intel_crtc);
+	ironlake_pfit_enable(intel_crtc, pipe_config);
 
 	/*
 	 * On ILK+ LUT must be loaded before the pipe is running but with
@@ -4822,7 +4821,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	intel_update_watermarks(crtc);
 	intel_enable_pipe(intel_crtc);
 
-	if (intel_crtc->config->has_pch_encoder)
+	if (pipe_config->has_pch_encoder)
 		ironlake_pch_enable(crtc, pipe_config);
 
 	assert_vblank_disabled(crtc);
@@ -4857,9 +4856,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
 
 	if (pipe_config->has_dp_encoder)
-		intel_dp_set_m_n(intel_crtc, M1_N1);
+		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
 
-	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_timings(intel_crtc, pipe_config);
 
 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
 		I915_WRITE(PIPE_MULT(pipe_config->cpu_transcoder),
@@ -4867,13 +4866,13 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	}
 
 	if (pipe_config->has_pch_encoder) {
-		intel_cpu_transcoder_set_m_n(intel_crtc,
+		intel_cpu_transcoder_set_m_n(intel_crtc, pipe_config,
 				     &pipe_config->fdi_m_n, NULL);
 	}
 
-	haswell_set_pipeconf(crtc);
+	haswell_set_pipeconf(crtc, pipe_config);
 
-	intel_set_pipe_csc(crtc);
+	intel_set_pipe_csc(crtc, pipe_config);
 
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -4890,9 +4889,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_ddi_enable_pipe_clock(intel_crtc);
 
 	if (INTEL_INFO(dev)->gen == 9)
-		skylake_pfit_update(intel_crtc, 1);
+		skylake_pfit_update(intel_crtc, pipe_config, 1);
 	else if (INTEL_INFO(dev)->gen < 9)
-		ironlake_pfit_enable(intel_crtc);
+		ironlake_pfit_enable(intel_crtc, pipe_config);
 	else
 		MISSING_CASE(INTEL_INFO(dev)->gen);
 
@@ -4908,10 +4907,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_update_watermarks(crtc);
 	intel_enable_pipe(intel_crtc);
 
-	if (intel_crtc->config->has_pch_encoder)
+	if (pipe_config->has_pch_encoder)
 		lpt_pch_enable(dev_priv, pipe_config);
 
-	if (intel_crtc->config->dp_encoder_is_mst)
+	if (pipe_config->dp_encoder_is_mst)
 		intel_ddi_set_vc_payload_alloc(crtc,
 					       pipe_config->cpu_transcoder,
 					       true);
@@ -4932,7 +4931,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	}
 }
 
-static void ironlake_pfit_disable(struct intel_crtc *crtc)
+static void ironlake_pfit_disable(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;
@@ -4940,7 +4940,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
 
 	/* To avoid upsetting the power well on haswell only disable the pfit if
 	 * it's in use. The hw state code will make sure we get this right. */
-	if (crtc->config->pch_pfit.enabled) {
+	if (pipe_config->pch_pfit.enabled) {
 		I915_WRITE(PF_CTL(pipe), 0);
 		I915_WRITE(PF_WIN_POS(pipe), 0);
 		I915_WRITE(PF_WIN_SZ(pipe), 0);
@@ -4968,7 +4968,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
 
 	intel_disable_pipe(intel_crtc, old_state);
 
-	ironlake_pfit_disable(intel_crtc);
+	ironlake_pfit_disable(intel_crtc, old_state);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
@@ -5005,7 +5005,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		intel_opregion_notify_encoder(encoder, false);
@@ -5015,12 +5015,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 	drm_crtc_vblank_off(crtc);
 	assert_vblank_disabled(crtc);
 
-	if (intel_crtc->config->has_pch_encoder)
+	if (old_state->has_pch_encoder)
 		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 						      false);
 	intel_disable_pipe(intel_crtc, old_state);
 
-	if (intel_crtc->config->dp_encoder_is_mst)
+	if (old_state->dp_encoder_is_mst)
 		intel_ddi_set_vc_payload_alloc(crtc,
 					       old_state->cpu_transcoder,
 					       false);
@@ -5028,15 +5028,15 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
 	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
 
 	if (INTEL_INFO(dev)->gen == 9)
-		skylake_pfit_update(intel_crtc, 0);
+		skylake_pfit_update(intel_crtc, old_state, 0);
 	else if (INTEL_INFO(dev)->gen < 9)
-		ironlake_pfit_disable(intel_crtc);
+		ironlake_pfit_disable(intel_crtc, old_state);
 	else
 		MISSING_CASE(INTEL_INFO(dev)->gen);
 
 	intel_ddi_disable_pipe_clock(intel_crtc, old_state->cpu_transcoder);
 
-	if (intel_crtc->config->has_pch_encoder) {
+	if (old_state->has_pch_encoder) {
 		lpt_disable_pch_transcoder(dev_priv);
 		intel_ddi_fdi_disable(crtc, old_state);
 	}
@@ -5126,13 +5126,15 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 	enum pipe pipe = intel_crtc->pipe;
 	unsigned long mask;
 	enum transcoder transcoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 
-	transcoder = to_intel_crtc_state(crtc->state)->cpu_transcoder;
+	transcoder = pipe_config->cpu_transcoder;
 
 	mask = BIT(POWER_DOMAIN_PIPE(pipe));
 	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
-	if (intel_crtc->config->pch_pfit.enabled ||
-	    intel_crtc->config->pch_pfit.force_thru)
+	if (pipe_config->pch_pfit.enabled ||
+	    pipe_config->pch_pfit.force_thru)
 		mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
 
 	for_each_encoder_on_crtc(dev, crtc, intel_encoder)
@@ -5595,7 +5597,8 @@ static int intel_mode_max_pixclk(struct drm_device *dev,
 			crtc_state =
 				intel_atomic_get_crtc_state(state, intel_crtc);
 		else
-			crtc_state = intel_crtc->config;
+			crtc_state = to_intel_crtc_state(intel_crtc->base.state);
+
 		if (IS_ERR(crtc_state))
 			return PTR_ERR(crtc_state);
 
@@ -5743,9 +5746,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 	}
 
 	if (pipe_config->has_dp_encoder)
-		intel_dp_set_m_n(intel_crtc, M1_N1);
+		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
 
-	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_timings(intel_crtc, pipe_config);
 
 	if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
 		struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5754,7 +5757,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 		I915_WRITE(CHV_CANVAS(pipe), 0);
 	}
 
-	i9xx_set_pipeconf(intel_crtc);
+	i9xx_set_pipeconf(intel_crtc, pipe_config);
 
 	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
@@ -5787,15 +5790,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 		encoder->enable(encoder);
 }
 
-static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
-	I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
-}
-
 static void i9xx_crtc_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -5808,14 +5802,15 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 	pipe_config = to_intel_crtc_state(crtc->state);
 	WARN_ON(!pipe_config->base.active);
 
-	i9xx_set_pll_dividers(intel_crtc);
+	I915_WRITE(FP0(pipe), pipe_config->dpll_hw_state.fp0);
+	I915_WRITE(FP1(pipe), pipe_config->dpll_hw_state.fp1);
 
-	if (intel_crtc->config->has_dp_encoder)
-		intel_dp_set_m_n(intel_crtc, M1_N1);
+	if (pipe_config->has_dp_encoder)
+		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
 
-	intel_set_pipe_timings(intel_crtc);
+	intel_set_pipe_timings(intel_crtc, pipe_config);
 
-	i9xx_set_pipeconf(intel_crtc);
+	i9xx_set_pipeconf(intel_crtc, pipe_config);
 
 	if (!IS_GEN2(dev))
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
@@ -5840,14 +5835,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 		encoder->enable(encoder);
 }
 
-static void i9xx_pfit_disable(struct intel_crtc *crtc)
+static void i9xx_pfit_disable(struct drm_i915_private *dev_priv)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (!crtc->config->gmch_pfit.control)
-		return;
-
 	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
 			 I915_READ(PFIT_CONTROL));
 	I915_WRITE(PFIT_CONTROL, 0);
@@ -5878,7 +5867,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
 
 	intel_disable_pipe(intel_crtc, old_state);
 
-	i9xx_pfit_disable(intel_crtc);
+	if (old_state->gmch_pfit.control)
+		i9xx_pfit_disable(dev_priv);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		if (encoder->post_disable)
@@ -6638,13 +6628,14 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
 }
 
 static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+					 struct intel_crtc_state *pipe_config,
 					 struct intel_link_m_n *m_n,
 					 struct intel_link_m_n *m2_n2)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe = crtc->pipe;
-	enum transcoder transcoder = crtc->config->cpu_transcoder;
+	enum transcoder transcoder = pipe_config->cpu_transcoder;
 
 	if (INTEL_INFO(dev)->gen >= 5) {
 		I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
@@ -6656,7 +6647,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
 		 * registers are not unnecessarily accessed).
 		 */
 		if (m2_n2 && (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen < 8) &&
-			crtc->config->has_drrs) {
+			pipe_config->has_drrs) {
 			I915_WRITE(PIPE_DATA_M2(transcoder),
 					TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
 			I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n);
@@ -6671,29 +6662,31 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
 	}
 }
 
-void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)
+void intel_dp_set_m_n(struct intel_crtc *crtc,
+		      struct intel_crtc_state *pipe_config,
+		      enum link_m_n_set m_n)
 {
 	struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
 
 	if (m_n == M1_N1) {
-		dp_m_n = &crtc->config->dp_m_n;
-		dp_m2_n2 = &crtc->config->dp_m2_n2;
+		dp_m_n = &pipe_config->dp_m_n;
+		dp_m2_n2 = &pipe_config->dp_m2_n2;
 	} else if (m_n == M2_N2) {
 
 		/*
 		 * M2_N2 registers are not supported. Hence m2_n2 divider value
 		 * needs to be programmed into M1_N1.
 		 */
-		dp_m_n = &crtc->config->dp_m2_n2;
+		dp_m_n = &pipe_config->dp_m2_n2;
 	} else {
 		DRM_ERROR("Unsupported divider value\n");
 		return;
 	}
 
-	if (crtc->config->has_pch_encoder)
-		intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
+	if (pipe_config->has_pch_encoder)
+		intel_pch_transcoder_set_m_n(crtc, &pipe_config->dp_m_n);
 	else
-		intel_cpu_transcoder_set_m_n(crtc, dp_m_n, dp_m2_n2);
+		intel_cpu_transcoder_set_m_n(crtc, pipe_config, dp_m_n, dp_m2_n2);
 }
 
 static void vlv_update_pll(struct intel_crtc *crtc,
@@ -6976,9 +6969,6 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
 	struct drm_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
 	struct intel_crtc_state *state = to_intel_crtc_state(crtc->state);
 
-	/* Is state->cpu_transcoder correct to use? */
-	WARN_ON(crtc->state != &to_intel_crtc(crtc)->config->base);
-
 	/* Make sure the pipe isn't still relying on us */
 	assert_pipe_disabled(dev_priv, state->cpu_transcoder, pipe);
 
@@ -7103,14 +7093,15 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
 	crtc_state->dpll_hw_state.dpll = dpll;
 }
 
-static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
+static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
+				   struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum pipe pipe = intel_crtc->pipe;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	struct drm_display_mode *adjusted_mode =
-		&intel_crtc->config->base.adjusted_mode;
+		&pipe_config->base.adjusted_mode;
 	uint32_t crtc_vtotal, crtc_vblank_end;
 	int vsyncshift = 0;
 
@@ -7168,8 +7159,8 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
 	 * always be the user's requested size.
 	 */
 	I915_WRITE(PIPESRC(pipe),
-		   ((intel_crtc->config->pipe_src_w - 1) << 16) |
-		   (intel_crtc->config->pipe_src_h - 1));
+		   ((pipe_config->pipe_src_w - 1) << 16) |
+		    (pipe_config->pipe_src_h - 1));
 }
 
 static void intel_get_pipe_timings(struct intel_crtc *crtc,
@@ -7233,7 +7224,8 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 	mode->flags |= pipe_config->base.adjusted_mode.flags;
 }
 
-static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
+static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc,
+			      struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -7245,17 +7237,17 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 	    (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
 		pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
 
-	if (intel_crtc->config->double_wide)
+	if (pipe_config->double_wide)
 		pipeconf |= PIPECONF_DOUBLE_WIDE;
 
 	/* only g4x and later have fancy bpc/dither controls */
 	if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
 		/* Bspec claims that we can't use dithering for 30bpp pipes. */
-		if (intel_crtc->config->dither && intel_crtc->config->pipe_bpp != 30)
+		if (pipe_config->dither && pipe_config->pipe_bpp != 30)
 			pipeconf |= PIPECONF_DITHER_EN |
 				    PIPECONF_DITHER_TYPE_SP;
 
-		switch (intel_crtc->config->pipe_bpp) {
+		switch (pipe_config->pipe_bpp) {
 		case 18:
 			pipeconf |= PIPECONF_6BPC;
 			break;
@@ -7280,7 +7272,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 		}
 	}
 
-	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
 		if (INTEL_INFO(dev)->gen < 4 ||
 		    intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
 			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
@@ -7289,7 +7281,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 	} else
 		pipeconf |= PIPECONF_PROGRESSIVE;
 
-	if (IS_VALLEYVIEW(dev) && intel_crtc->config->limited_color_range)
+	if (IS_VALLEYVIEW(dev) && pipe_config->limited_color_range)
 		pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
 
 	I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
@@ -8027,7 +8019,8 @@ static int ironlake_get_refclk(struct intel_crtc_state *crtc_state)
 	return 120000;
 }
 
-static void ironlake_set_pipeconf(struct drm_crtc *crtc)
+static void ironlake_set_pipeconf(struct drm_crtc *crtc,
+				  struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -8036,7 +8029,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
 
 	val = 0;
 
-	switch (intel_crtc->config->pipe_bpp) {
+	switch (pipe_config->pipe_bpp) {
 	case 18:
 		val |= PIPECONF_6BPC;
 		break;
@@ -8054,15 +8047,15 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
 		BUG();
 	}
 
-	if (intel_crtc->config->dither)
+	if (pipe_config->dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
 
-	if (intel_crtc->config->limited_color_range)
+	if (pipe_config->limited_color_range)
 		val |= PIPECONF_COLOR_RANGE_SELECT;
 
 	I915_WRITE(PIPECONF(pipe), val);
@@ -8076,7 +8069,8 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
  * is supported, but eventually this should handle various
  * RGB<->YCbCr scenarios as well.
  */
-static void intel_set_pipe_csc(struct drm_crtc *crtc)
+static void intel_set_pipe_csc(struct drm_crtc *crtc,
+			       struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -8091,7 +8085,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
 	 * consideration.
 	 */
 
-	if (intel_crtc->config->limited_color_range)
+	if (pipe_config->limited_color_range)
 		coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
 
 	/*
@@ -8115,7 +8109,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
 	if (INTEL_INFO(dev)->gen > 6) {
 		uint16_t postoff = 0;
 
-		if (intel_crtc->config->limited_color_range)
+		if (pipe_config->limited_color_range)
 			postoff = (16 * (1 << 12) / 255) & 0x1fff;
 
 		I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
@@ -8126,28 +8120,29 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
 	} else {
 		uint32_t mode = CSC_MODE_YUV_TO_RGB;
 
-		if (intel_crtc->config->limited_color_range)
+		if (pipe_config->limited_color_range)
 			mode |= CSC_BLACK_SCREEN_OFFSET;
 
 		I915_WRITE(PIPE_CSC_MODE(pipe), mode);
 	}
 }
 
-static void haswell_set_pipeconf(struct drm_crtc *crtc)
+static void haswell_set_pipeconf(struct drm_crtc *crtc,
+				 struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum pipe pipe = intel_crtc->pipe;
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	uint32_t val;
 
 	val = 0;
 
-	if (IS_HASWELL(dev) && intel_crtc->config->dither)
+	if (IS_HASWELL(dev) && pipe_config->dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
@@ -8161,7 +8156,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
 	if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
 		val = 0;
 
-		switch (intel_crtc->config->pipe_bpp) {
+		switch (pipe_config->pipe_bpp) {
 		case 18:
 			val |= PIPEMISC_DITHER_6_BPC;
 			break;
@@ -8179,7 +8174,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
 			BUG();
 		}
 
-		if (intel_crtc->config->dither)
+		if (pipe_config->dither)
 			val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
 
 		I915_WRITE(PIPEMISC(pipe), val);
@@ -8423,12 +8418,13 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
 }
 
 static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
-					 enum transcoder transcoder,
+					 struct intel_crtc_state *pipe_config,
 					 struct intel_link_m_n *m_n,
 					 struct intel_link_m_n *m2_n2)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder transcoder = pipe_config->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 
 	if (INTEL_INFO(dev)->gen >= 5) {
@@ -8444,7 +8440,7 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
 		 * registers are not unnecessarily read).
 		 */
 		if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
-			crtc->config->has_drrs) {
+			pipe_config->has_drrs) {
 			m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
 			m2_n2->link_n =	I915_READ(PIPE_LINK_N2(transcoder));
 			m2_n2->gmch_m =	I915_READ(PIPE_DATA_M2(transcoder))
@@ -8470,7 +8466,7 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
 	if (pipe_config->has_pch_encoder)
 		intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
 	else
-		intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+		intel_cpu_transcoder_get_m_n(crtc, pipe_config,
 					     &pipe_config->dp_m_n,
 					     &pipe_config->dp_m2_n2);
 }
@@ -8478,7 +8474,7 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
 static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
 					struct intel_crtc_state *pipe_config)
 {
-	intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+	intel_cpu_transcoder_get_m_n(crtc, pipe_config,
 				     &pipe_config->fdi_m_n, NULL);
 }
 
@@ -9331,6 +9327,8 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
 	int pipe = intel_crtc->pipe;
 	int x = crtc->cursor_x;
 	int y = crtc->cursor_y;
@@ -9339,10 +9337,10 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 	if (on)
 		base = intel_crtc->cursor_addr;
 
-	if (x >= intel_crtc->config->pipe_src_w)
+	if (x >= pipe_config->pipe_src_w)
 		base = 0;
 
-	if (y >= intel_crtc->config->pipe_src_h)
+	if (y >= pipe_config->pipe_src_h)
 		base = 0;
 
 	if (x < 0) {
@@ -9966,9 +9964,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+	struct intel_crtc_state *pipe_config =
+		to_intel_crtc_state(crtc->state);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	struct drm_display_mode *mode;
-	struct intel_crtc_state pipe_config;
+	struct intel_crtc_state fake_config;
 	int htot = I915_READ(HTOTAL(cpu_transcoder));
 	int hsync = I915_READ(HSYNC(cpu_transcoder));
 	int vtot = I915_READ(VTOTAL(cpu_transcoder));
@@ -9986,14 +9986,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 	 * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
 	 * to use a real value here instead.
 	 */
-	pipe_config.cpu_transcoder = (enum transcoder) pipe;
-	pipe_config.pixel_multiplier = 1;
-	pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
-	pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
-	pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
-	i9xx_crtc_clock_get(intel_crtc, &pipe_config);
-
-	mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier;
+	fake_config.cpu_transcoder = (enum transcoder) pipe;
+	fake_config.pixel_multiplier = 1;
+	fake_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
+	fake_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
+	fake_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
+	i9xx_crtc_clock_get(intel_crtc, &fake_config);
+
+	mode->clock = fake_config.port_clock / fake_config.pixel_multiplier;
 	mode->hdisplay = (htot & 0xffff) + 1;
 	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
 	mode->hsync_start = (hsync & 0xffff) + 1;
@@ -11839,12 +11839,13 @@ check_crtc_state(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *crtc;
 	struct intel_encoder *encoder;
-	struct intel_crtc_state pipe_config;
+	struct intel_crtc_state pipe_config, *sw_config;
 
 	for_each_intel_crtc(dev, crtc) {
 		bool enabled = false;
 		bool active = false;
 
+		sw_config = to_intel_crtc_state(crtc->base.state);
 		memset(&pipe_config, 0, sizeof(pipe_config));
 
 		DRM_DEBUG_KMS("[CRTC:%d]\n",
@@ -11887,11 +11888,11 @@ check_crtc_state(struct drm_device *dev)
 		     "(expected %i, found %i)\n", crtc->base.state->active, active);
 
 		if (active &&
-		    !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
+		    !intel_pipe_config_compare(dev, sw_config, &pipe_config)) {
 			I915_STATE_WARN(1, "pipe state doesn't match!\n");
 			intel_dump_pipe_config(crtc, &pipe_config,
 					       "[hw state]");
-			intel_dump_pipe_config(crtc, crtc->config,
+			intel_dump_pipe_config(crtc, sw_config,
 					       "[sw state]");
 		}
 	}
@@ -11990,7 +11991,8 @@ static void update_scanline_offset(struct intel_crtc *crtc)
 	 * one to the value.
 	 */
 	if (IS_GEN2(dev)) {
-		const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
+		const struct drm_display_mode *mode =
+			&crtc->base.state->adjusted_mode;
 		int vtotal;
 
 		vtotal = mode->crtc_vtotal;
@@ -13532,6 +13534,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
 	if (!crtc_state)
 		goto fail;
+
 	intel_crtc->config = crtc_state;
 	intel_crtc->base.state = &crtc_state->base;
 	crtc_state->base.crtc = &intel_crtc->base;
@@ -14574,19 +14577,20 @@ intel_check_plane_mapping(struct intel_crtc *crtc)
 	return true;
 }
 
-static void intel_sanitize_crtc(struct intel_crtc *crtc)
+static void intel_sanitize_crtc(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;
 	u32 reg;
 
 	/* Clear any frame start delays used for debugging left by the BIOS */
-	reg = PIPECONF(crtc->config->cpu_transcoder);
+	reg = PIPECONF(pipe_config->cpu_transcoder);
 	I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
 
 	/* restore vblank interrupts to correct state */
 	drm_crtc_vblank_reset(&crtc->base);
-	if (crtc->base.state->active) {
+	if (pipe_config->base.active) {
 		update_scanline_offset(crtc);
 		drm_crtc_vblank_on(&crtc->base);
 	}
@@ -14626,14 +14630,14 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 				connector->encoder->connectors_active = false;
 			}
 
-		WARN_ON(crtc->base.state->active);
-		crtc->base.state->enable = false;
-		crtc->base.state->active = false;
+		WARN_ON(pipe_config->base.active);
+		pipe_config->base.enable = false;
+		pipe_config->base.active = false;
 		crtc->base.enabled = false;
 	}
 
 	if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
-	    crtc->pipe == PIPE_A && !crtc->base.state->active) {
+	    crtc->pipe == PIPE_A && !pipe_config->base.active) {
 		/* BIOS forgot to enable pipe A, this mostly happens after
 		 * resume. Force-enable the pipe to fix this, the update_dpms
 		 * call below we restore the pipe to the right state, but leave
@@ -14645,7 +14649,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
 	 * have active connectors/encoders. */
 	intel_crtc_update_dpms(&crtc->base);
 
-	if (crtc->base.state->active || HAS_GMCH_DISPLAY(dev)) {
+	if (pipe_config->base.active || HAS_GMCH_DISPLAY(dev)) {
 		/*
 		 * We start out with underrun reporting disabled to avoid races.
 		 * For correct bookkeeping mark this on active crtcs.
@@ -14763,17 +14767,19 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 	for_each_intel_crtc(dev, crtc) {
 		struct drm_plane *primary = crtc->base.primary;
 		struct intel_plane_state *plane_state;
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc->base.state);
 
-		memset(crtc->config, 0, sizeof(*crtc->config));
+		memset(pipe_config, 0, sizeof(*pipe_config));
 
-		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
+		pipe_config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
 
 		if (crtc->base.state->active)
 			*crtc_mask |= drm_crtc_index(&crtc->base);
 
-		crtc->base.enabled = crtc->base.state->enable =
-		crtc->base.state->active =
-			dev_priv->display.get_pipe_config(crtc, crtc->config);
+		crtc->base.enabled = pipe_config->base.enable =
+		pipe_config->base.active =
+			dev_priv->display.get_pipe_config(crtc, pipe_config);
 
 		plane_state = to_intel_plane_state(primary->state);
 		plane_state->hw_enabled = plane_state->visible =
@@ -14818,7 +14824,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
 		if (encoder->get_hw_state(encoder, &pipe)) {
 			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 			encoder->base.crtc = &crtc->base;
-			encoder->get_config(encoder, crtc->config);
+			encoder->get_config(encoder,
+				to_intel_crtc_state(crtc->base.state));
 		} else {
 			encoder->base.crtc = NULL;
 		}
@@ -14883,9 +14890,13 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 	}
 
 	for_each_pipe(dev_priv, pipe) {
+		struct intel_crtc_state *pipe_config;
+
 		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-		intel_sanitize_crtc(crtc);
-		intel_dump_pipe_config(crtc, crtc->config,
+		pipe_config = to_intel_crtc_state(crtc->base.state);
+
+		intel_sanitize_crtc(crtc, pipe_config);
+		intel_dump_pipe_config(crtc, pipe_config,
 				       "[setup_hw_state]");
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e6876faca7f0..abf8082be40c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5309,10 +5309,10 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 	if (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev)) {
 		switch (index) {
 		case DRRS_HIGH_RR:
-			intel_dp_set_m_n(intel_crtc, M1_N1);
+			intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
 			break;
 		case DRRS_LOW_RR:
-			intel_dp_set_m_n(intel_crtc, M2_N2);
+			intel_dp_set_m_n(intel_crtc, pipe_config, M2_N2);
 			break;
 		case DRRS_MAX_RR:
 		default:
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 7979a2f6838c..6767ed91faaf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1102,7 +1102,9 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv);
 void bxt_disable_dc9(struct drm_i915_private *dev_priv);
 void intel_dp_get_m_n(struct intel_crtc *crtc,
 		      struct intel_crtc_state *pipe_config);
-void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n);
+void intel_dp_set_m_n(struct intel_crtc *crtc,
+		      struct intel_crtc_state *pipe_config,
+		      enum link_m_n_set m_n);
 int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
 void
 ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 36/42] drm/i915: get rid of crtc->config
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (34 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2 Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit Maarten Lankhorst
                   ` (6 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

This is now unused, goodbye. :-)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 2 --
 drivers/gpu/drm/i915/intel_drv.h     | 1 -
 2 files changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2c467cda74a4..65ee2cd0437c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11448,7 +11448,6 @@ intel_modeset_update_state(struct drm_atomic_state *state)
 		if (!state->crtcs[drm_crtc_index(crtc)])
 			continue;
 
-		to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
 		if (crtc->state->active && needs_modeset(crtc->state))
 			drm_calc_timestamping_constants(crtc, &crtc->state->adjusted_mode);
 
@@ -13535,7 +13534,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	if (!crtc_state)
 		goto fail;
 
-	intel_crtc->config = crtc_state;
 	intel_crtc->base.state = &crtc_state->base;
 	crtc_state->base.crtc = &intel_crtc->base;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6767ed91faaf..ee089ebca44f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -511,7 +511,6 @@ struct intel_crtc {
 	uint32_t cursor_base;
 
 	struct intel_initial_plane_config plane_config;
-	struct intel_crtc_state *config;
 
 	/* reset counter value when the last flip was submitted */
 	unsigned int reset_counter;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (35 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 36/42] drm/i915: get rid of crtc->config Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-12 13:03   ` Daniel Vetter
  2015-05-11 14:25 ` [PATCH 38/42] drm/i915: Use global atomic state for staged pll config Maarten Lankhorst
                   ` (5 subsequent siblings)
  42 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

crtc->config is gone, swap swap swap. :D

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  | 36 ++----------------------------------
 drivers/gpu/drm/i915/intel_display.c |  7 +++++--
 2 files changed, 7 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index ace6aeeb1359..0315dc44b17a 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -130,7 +130,6 @@ int intel_atomic_commit(struct drm_device *dev,
 			bool async)
 {
 	int ret;
-	int i;
 
 	if (async) {
 		DRM_DEBUG_KMS("i915 does not yet support async commit\n");
@@ -142,48 +141,17 @@ int intel_atomic_commit(struct drm_device *dev,
 		return ret;
 
 	/* Point of no return */
+	drm_atomic_helper_swap_state(dev, state);
 
 	/*
 	 * FIXME:  The proper sequence here will eventually be:
 	 *
-	 * drm_atomic_helper_swap_state(dev, state)
 	 * drm_atomic_helper_commit_modeset_disables(dev, state);
 	 * drm_atomic_helper_commit_planes(dev, state);
 	 * drm_atomic_helper_commit_modeset_enables(dev, state);
-	 * drm_atomic_helper_wait_for_vblanks(dev, state);
-	 * drm_atomic_helper_cleanup_planes(dev, state);
-	 * drm_atomic_state_free(state);
-	 *
-	 * once we have full atomic modeset.  For now, just manually update
-	 * plane states to avoid clobbering good states with dummy states
-	 * while nuclear pageflipping.
 	 */
-	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
-
-		if (!plane)
-			continue;
-
-		plane->state->state = state;
-		swap(state->plane_states[i], plane->state);
-		plane->state->state = NULL;
-	}
-
-	/* swap crtc_scaler_state */
-	for (i = 0; i < dev->mode_config.num_crtc; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc) {
-			continue;
-		}
-
-		to_intel_crtc_state(crtc->state)->scaler_state =
-			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
-
-		if (INTEL_INFO(dev)->gen >= 9)
-			skl_detach_scalers(to_intel_crtc(crtc));
-	}
-
 	drm_atomic_helper_commit_planes(dev, state);
+
 	drm_atomic_helper_wait_for_vblanks(dev, state);
 	drm_atomic_helper_cleanup_planes(dev, state);
 	drm_atomic_state_free(state);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 65ee2cd0437c..105bdf84e46a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13202,11 +13202,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
 
 	/* Perform vblank evasion around commit operation */
 	if (intel_crtc->atomic.evade &&
-	    !dev_priv->power_domains.init_power_on)
+	    !dev_priv->power_domains.init_power_on) {
+		if (dev_priv->info.gen >= 9)
+			skl_detach_scalers(to_intel_crtc(crtc));
+
 		intel_crtc->atomic.evade =
 			intel_pipe_update_start(intel_crtc,
 						&intel_crtc->atomic.start_vbl_count);
-	else
+	} else
 		intel_crtc->atomic.evade = false;
 }
 
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 38/42] drm/i915: Use global atomic state for staged pll config
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (36 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 39/42] drm/i915: Support modeset across multiple pipes Maarten Lankhorst
                   ` (4 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   1 -
 drivers/gpu/drm/i915/intel_atomic.c  |  49 ++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++------------------------
 drivers/gpu/drm/i915/intel_drv.h     |  13 ++++
 4 files changed, 95 insertions(+), 79 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3ba15df4c93a..07c16a83a092 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -319,7 +319,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 */
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 0315dc44b17a..8286a79f4db1 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -385,3 +385,52 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 
 	return 0;
 }
+
+static void intel_atomic_duplicate_dpll_state(struct drm_device *dev,
+					      struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	state->dpll_set = true;
+
+	/* Copy shared dpll state */
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
+
+		memcpy(&state->shared_dpll[i],
+		       &pll->config, sizeof(pll->config));
+	}
+}
+
+struct intel_shared_dpll_config *
+intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(s);
+
+	if (!state->dpll_set)
+		intel_atomic_duplicate_dpll_state(state->base.dev, state);
+
+	return state->shared_dpll;
+}
+
+struct drm_atomic_state *
+intel_atomic_new_state(struct drm_device *dev)
+{
+	struct intel_atomic_state *state = kzalloc(GFP_KERNEL, sizeof(*state));
+
+	if (!state || __drm_atomic_new_state(dev, &state->base) < 0) {
+		kfree(state);
+		return NULL;
+	}
+
+	return &state->base;
+}
+
+void intel_atomic_clear_state(struct drm_atomic_state *s)
+{
+	struct intel_atomic_state *state = to_intel_atomic_state(s);
+	__drm_atomic_clear_state(&state->base);
+	state->dpll_set = false;
+}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 105bdf84e46a..02e444384dc0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4182,8 +4182,11 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config *shared_dpll;
 	enum intel_dpll_id i;
 
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
 	if (HAS_PCH_IBX(dev_priv->dev)) {
 		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
 		i = (enum intel_dpll_id) crtc->pipe;
@@ -4192,7 +4195,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(shared_dpll[i].crtc_mask);
 
 		goto found;
 	}
@@ -4212,7 +4215,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 		pll = &dev_priv->shared_dplls[i];
 		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(shared_dpll[i].crtc_mask);
 
 		goto found;
 	}
@@ -4221,15 +4224,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 (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) {
+			   &shared_dpll[i].hw_state,
+			   sizeof(crtc_state->dpll_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,
+				      shared_dpll[i].crtc_mask,
 				      pll->active);
 			goto found;
 		}
@@ -4238,7 +4241,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 (shared_dpll[i].crtc_mask == 0) {
 			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
 				      crtc->base.base.id, pll->name);
 			goto found;
@@ -4248,83 +4251,33 @@ 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 (shared_dpll[i].crtc_mask == 0)
+		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;
+	shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
 
 	return pll;
 }
 
-/**
- * intel_shared_dpll_start_config - start a new PLL staged config
- * @dev_priv: DRM device
- * @clear_pipes: mask of pipes that will have their PLLs freed
- *
- * Starts a new PLL staged config, copying the current config but
- * releasing the references of pipes specified in clear_pipes.
- */
-static int intel_shared_dpll_start_config(struct drm_i915_private *dev_priv,
-					  unsigned clear_pipes)
-{
-	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];
-
-		pll->new_config = kmemdup(&pll->config, sizeof pll->config,
-					  GFP_KERNEL);
-		if (!pll->new_config)
-			goto cleanup;
-
-		pll->new_config->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_atomic_state *state)
 {
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_shared_dpll_config *shared_dpll;
 	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;
+	if (!to_intel_atomic_state(state)->dpll_set)
+		return;
 
+	shared_dpll = to_intel_atomic_state(state)->shared_dpll;
 	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 = shared_dpll[i];
 	}
 }
 
@@ -11419,13 +11372,12 @@ static void
 intel_modeset_update_state(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *intel_encoder;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_connector *connector;
 
-	intel_shared_dpll_commit(dev_priv);
+	intel_shared_dpll_commit(state);
 
 	for_each_intel_encoder(dev, intel_encoder) {
 		if (!intel_encoder->base.crtc)
@@ -12074,9 +12026,13 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 		}
 	}
 
-	ret = intel_shared_dpll_start_config(dev_priv, clear_pipes);
-	if (ret)
-		goto done;
+	if (clear_pipes) {
+		struct intel_shared_dpll_config *shared_dpll =
+			intel_atomic_get_shared_dpll_state(state);
+
+		for (i = 0; i < dev_priv->num_shared_dpll; i++)
+			shared_dpll[i].crtc_mask &= ~clear_pipes;
+	}
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (!needs_modeset(crtc_state) || !crtc_state->active)
@@ -12087,13 +12043,10 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 
 		ret = dev_priv->display.crtc_compute_clock(intel_crtc,
 							   intel_crtc_state);
-		if (ret) {
-			intel_shared_dpll_abort_config(dev_priv);
-			goto done;
-		}
+		if (ret)
+			return ret;
 	}
 
-done:
 	return ret;
 }
 
@@ -14073,6 +14026,8 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
 	.output_poll_changed = intel_fbdev_output_poll_changed,
 	.atomic_check = intel_atomic_check,
 	.atomic_commit = intel_atomic_commit,
+	.atomic_new_state = intel_atomic_new_state,
+	.atomic_clear_state = intel_atomic_clear_state,
 };
 
 /* Set up chip specific display functions */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ee089ebca44f..4971a5a35db4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -231,6 +231,13 @@ typedef struct dpll {
 	int	p;
 } intel_clock_t;
 
+struct intel_atomic_state {
+	struct drm_atomic_state base;
+
+	bool dpll_set;
+	struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS];
+};
+
 struct intel_plane_state {
 	struct drm_plane_state base;
 	struct drm_rect src;
@@ -611,6 +618,7 @@ struct cxsr_latency {
 	unsigned long cursor_hpll_disable;
 };
 
+#define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
 #define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
 #define to_intel_connector(x) container_of(x, struct intel_connector, base)
@@ -1388,6 +1396,11 @@ int intel_connector_atomic_get_property(struct drm_connector *connector,
 struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
+struct drm_atomic_state *intel_atomic_new_state(struct drm_device *dev);
+void intel_atomic_clear_state(struct drm_atomic_state *);
+struct intel_shared_dpll_config *
+intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s);
+
 static inline struct intel_crtc_state *
 intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 			    struct intel_crtc *crtc)
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 39/42] drm/i915: Support modeset across multiple pipes
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (37 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 38/42] drm/i915: Use global atomic state for staged pll config Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 40/42] drm/i915: Move cdclk and pll setup to intel_modeset_compute_config() Maarten Lankhorst
                   ` (3 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

Compute new pipe_configs for all crtcs in the atomic state. The commit
part of the mode set (__intel_set_mode()) is already enabled to support
multiple pipes, the only thing missing was calculating a new pipe_config
for every crtc.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 108 +++++++++++++++--------------------
 1 file changed, 45 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 02e444384dc0..450314008edb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -82,8 +82,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 static void ironlake_pch_clock_get(struct intel_crtc *crtc,
 				   struct intel_crtc_state *pipe_config);
 
-static int intel_set_mode(struct drm_crtc *crtc,
-			  struct drm_atomic_state *state);
+static int intel_set_mode(struct drm_atomic_state *state);
 static int intel_framebuffer_init(struct drm_device *dev,
 				  struct intel_framebuffer *ifb,
 				  struct drm_mode_fb_cmd2 *mode_cmd,
@@ -5883,7 +5882,7 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 		goto err;
 	}
 
-	ret = intel_set_mode(crtc, state);
+	ret = intel_set_mode(state);
 	if (!ret)
 		return;
 
@@ -9678,7 +9677,7 @@ retry:
 
 	drm_mode_copy(&crtc_state->base.mode, mode);
 
-	if (intel_set_mode(crtc, state)) {
+	if (intel_set_mode(state)) {
 		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
 		if (old->release_fb)
 			old->release_fb->funcs->destroy(old->release_fb);
@@ -9746,7 +9745,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 		if (ret)
 			goto fail;
 
-		ret = intel_set_mode(crtc, state);
+		ret = intel_set_mode(state);
 		if (ret)
 			goto fail;
 
@@ -11229,9 +11228,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 
 static int
 intel_modeset_pipe_config(struct drm_crtc *crtc,
-			  struct drm_atomic_state *state,
-			  struct intel_crtc_state *pipe_config)
+			  struct drm_atomic_state *state)
 {
+	struct drm_crtc_state *crtc_state;
+	struct intel_crtc_state *pipe_config;
 	struct intel_encoder *encoder;
 	struct drm_connector *connector;
 	struct drm_connector_state *connector_state;
@@ -11239,6 +11239,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 	int i;
 	bool retry = true;
 
+	crtc_state = state->crtc_states[drm_crtc_index(crtc)];
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	pipe_config = to_intel_crtc_state(crtc_state);
 	/*
 	 * XXX: Add all connectors to make the crtc state match the encoders.
 	 */
@@ -11958,45 +11963,35 @@ static void update_scanline_offset(struct intel_crtc *crtc)
 		crtc->scanline_offset = 1;
 }
 
-static struct intel_crtc_state *
-intel_modeset_compute_config(struct drm_crtc *crtc,
-			     struct drm_atomic_state *state)
+static int
+intel_modeset_compute_config(struct drm_atomic_state *state)
 {
-	struct intel_crtc_state *pipe_config;
-	int ret = 0;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int ret, i;
 
 	ret = drm_atomic_helper_check_modeset(state->dev, state);
 	if (ret)
-		return ERR_PTR(ret);
-
-	/*
-	 * Note this needs changes when we start tracking multiple modes
-	 * and crtcs.  At that point we'll need to compute the whole config
-	 * (i.e. one pipe_config for each crtc) rather than just the one
-	 * for this crtc.
-	 */
-	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
-	if (IS_ERR(pipe_config))
-		return pipe_config;
+		return ret;
 
-	if (!pipe_config->base.enable &&
-	    WARN_ON(pipe_config->base.active))
-		pipe_config->base.active = false;
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		if (!crtc_state->enable &&
+		    WARN_ON(crtc_state->active))
+			crtc_state->active = false;
 
-	if (!pipe_config->base.active)
-		goto done;
+		if (!crtc_state->active)
+			continue;
 
-	ret = intel_modeset_pipe_config(crtc, state, pipe_config);
-	if (ret)
-		return ERR_PTR(ret);
+		ret = intel_modeset_pipe_config(crtc, state);
+		if (ret)
+			return ret;
 
-	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]");
-done:
-	ret = drm_atomic_helper_check_planes(state->dev, state);
-	if (ret)
-		return ERR_PTR(ret);
+		intel_dump_pipe_config(to_intel_crtc(crtc),
+				       to_intel_crtc_state(crtc_state),
+				       "[modeset]");
+	}
 
-	return pipe_config;
+	return drm_atomic_helper_check_planes(state->dev, state);
 }
 
 static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
@@ -12312,37 +12307,27 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 	return 0;
 }
 
-static int intel_set_mode_with_config(struct drm_crtc *crtc,
-				      struct intel_crtc_state *pipe_config)
+static int intel_set_mode_checked(struct drm_atomic_state *state)
 {
+	struct drm_device *dev = state->dev;
 	int ret;
 
-	ret = __intel_set_mode(pipe_config->base.state);
-
+	ret = __intel_set_mode(state);
 	if (ret == 0)
-		intel_modeset_check_state(crtc->dev);
+		intel_modeset_check_state(dev);
 
 	return ret;
 }
 
-static int intel_set_mode(struct drm_crtc *crtc,
-			  struct drm_atomic_state *state)
+static int intel_set_mode(struct drm_atomic_state *state)
 {
-	struct intel_crtc_state *pipe_config;
-	int ret = 0;
-
-	pipe_config = intel_modeset_compute_config(crtc, state);
-	if (IS_ERR(pipe_config)) {
-		ret = PTR_ERR(pipe_config);
-		goto out;
-	}
+	int ret;
 
-	ret = intel_set_mode_with_config(crtc, pipe_config);
+	ret = intel_modeset_compute_config(state);
 	if (ret)
-		goto out;
+		return ret;
 
-out:
-	return ret;
+	return intel_set_mode_checked(state);
 }
 
 void intel_crtc_restore_mode(struct drm_crtc *crtc)
@@ -12407,7 +12392,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
 	intel_modeset_setup_plane_state(state, crtc, &crtc->mode,
 					crtc->primary->fb, crtc->x, crtc->y);
 
-	ret = intel_set_mode(crtc, state);
+	ret = intel_set_mode(state);
 	if (ret)
 		drm_atomic_state_free(state);
 }
@@ -12557,7 +12542,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
 	struct drm_atomic_state *state = NULL;
-	struct intel_crtc_state *pipe_config;
 	int ret;
 
 	BUG_ON(!set);
@@ -12588,15 +12572,13 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 	if (ret)
 		goto out;
 
-	pipe_config = intel_modeset_compute_config(set->crtc, state);
-	if (IS_ERR(pipe_config)) {
-		ret = PTR_ERR(pipe_config);
+	ret = intel_modeset_compute_config(state);
+	if (ret)
 		goto out;
-	}
 
 	intel_update_pipe_size(to_intel_crtc(set->crtc));
 
-	ret = intel_set_mode_with_config(set->crtc, pipe_config);
+	ret = intel_set_mode_checked(state);
 	if (ret) {
 		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
 			      set->crtc->base.id, ret);
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 40/42] drm/i915: Move cdclk and pll setup to intel_modeset_compute_config()
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (38 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 39/42] drm/i915: Support modeset across multiple pipes Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 41/42] drm/i915: Read hw state into an atomic state struct Maarten Lankhorst
                   ` (2 subsequent siblings)
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

It makes more sense there, since these are computation steps that can
fail.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 70 ++++++++++++++++++------------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 450314008edb..9a19d88cb5ce 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11963,37 +11963,6 @@ static void update_scanline_offset(struct intel_crtc *crtc)
 		crtc->scanline_offset = 1;
 }
 
-static int
-intel_modeset_compute_config(struct drm_atomic_state *state)
-{
-	struct drm_crtc *crtc;
-	struct drm_crtc_state *crtc_state;
-	int ret, i;
-
-	ret = drm_atomic_helper_check_modeset(state->dev, state);
-	if (ret)
-		return ret;
-
-	for_each_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!crtc_state->enable &&
-		    WARN_ON(crtc_state->active))
-			crtc_state->active = false;
-
-		if (!crtc_state->active)
-			continue;
-
-		ret = intel_modeset_pipe_config(crtc, state);
-		if (ret)
-			return ret;
-
-		intel_dump_pipe_config(to_intel_crtc(crtc),
-				       to_intel_crtc_state(crtc_state),
-				       "[modeset]");
-	}
-
-	return drm_atomic_helper_check_planes(state->dev, state);
-}
-
 static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
@@ -12238,6 +12207,41 @@ static void __intel_set_mode_cleanup_planes(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, old_state);
 }
 
+static int
+intel_modeset_compute_config(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	int ret, i;
+
+	ret = drm_atomic_helper_check_modeset(state->dev, state);
+	if (ret)
+		return ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		if (!crtc_state->enable &&
+		    WARN_ON(crtc_state->active))
+			crtc_state->active = false;
+
+		if (!crtc_state->active)
+			continue;
+
+		ret = intel_modeset_pipe_config(crtc, state);
+		if (ret)
+			return ret;
+
+		intel_dump_pipe_config(to_intel_crtc(crtc),
+				       to_intel_crtc_state(crtc_state),
+				       "[modeset]");
+	}
+
+	ret = drm_atomic_helper_check_planes(state->dev, state);
+	if (ret)
+		return ret;
+
+	return __intel_set_mode_checks(state);
+}
+
 static int __intel_set_mode(struct drm_atomic_state *state)
 {
 	struct drm_device *dev = state->dev;
@@ -12247,10 +12251,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
 	int ret;
 	int i;
 
-	ret = __intel_set_mode_checks(state);
-	if (ret < 0)
-		return ret;
-
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
 		return ret;
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 41/42] drm/i915: Read hw state into an atomic state struct
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (39 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 40/42] drm/i915: Move cdclk and pll setup to intel_modeset_compute_config() Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-11 14:25 ` [PATCH 42/42] drm/i915: return early in __intel_set_mode_setup_plls without modeset Maarten Lankhorst
  2015-05-13  7:04 ` [PATCH 00/42] drm/i915: Convert to atomic, part 2 Daniel Vetter
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

This lets us change the force restore path in setup_hw_state() to use a
single call to intel_mode_set() to restore all the previous user
requested state.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c  |  22 +--
 drivers/gpu/drm/i915/intel_display.c | 311 ++++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_drv.h     |   3 +
 3 files changed, 230 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 8286a79f4db1..fb79949783e3 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -386,21 +386,17 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 	return 0;
 }
 
-static void intel_atomic_duplicate_dpll_state(struct drm_device *dev,
-					      struct intel_atomic_state *state)
+void
+intel_atomic_duplicate_dpll_state(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll_config *shared_dpll)
 {
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_shared_dpll *pll;
 	enum intel_dpll_id i;
 
-	state->dpll_set = true;
-
 	/* Copy shared dpll state */
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		pll = &dev_priv->shared_dplls[i];
+		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
-		memcpy(&state->shared_dpll[i],
-		       &pll->config, sizeof(pll->config));
+		shared_dpll[i] = pll->config;
 	}
 }
 
@@ -409,8 +405,12 @@ intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
 {
 	struct intel_atomic_state *state = to_intel_atomic_state(s);
 
-	if (!state->dpll_set)
-		intel_atomic_duplicate_dpll_state(state->base.dev, state);
+	if (!state->dpll_set) {
+		state->dpll_set = true;
+
+		intel_atomic_duplicate_dpll_state(to_i915(state->base.dev),
+						  state->shared_dpll);
+	}
 
 	return state->shared_dpll;
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9a19d88cb5ce..386d9599d918 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14685,111 +14685,216 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 
-	if (!crtc->base.state->active)
+	if (!crtc->base.enabled)
 		return false;
 
 	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
 }
 
-static void intel_modeset_readout_hw_state(struct drm_device *dev,
-					   unsigned *crtc_mask)
+static int readout_hw_crtc_state(struct drm_atomic_state *state,
+				 struct intel_crtc *crtc)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum pipe pipe;
-	struct intel_crtc *crtc;
-	struct intel_encoder *encoder;
-	struct intel_connector *connector;
-	int i;
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_crtc_state *crtc_state;
+	struct drm_plane *primary = crtc->base.primary;
+	struct drm_plane_state *drm_plane_state;
+	struct intel_plane_state *plane_state;
 
-	*crtc_mask = 0;
-	for_each_intel_crtc(dev, crtc) {
-		struct drm_plane *primary = crtc->base.primary;
-		struct intel_plane_state *plane_state;
-		struct intel_crtc_state *pipe_config =
-			to_intel_crtc_state(crtc->base.state);
+	crtc_state = intel_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
 
-		memset(pipe_config, 0, sizeof(*pipe_config));
+	memset(crtc_state, 0, sizeof(*crtc_state));
+	crtc_state->base.crtc = &crtc->base;
+	crtc_state->base.state = state;
 
-		pipe_config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
+	crtc_state->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
 
-		if (crtc->base.state->active)
-			*crtc_mask |= drm_crtc_index(&crtc->base);
+	crtc_state->base.enable = crtc_state->base.active =
+	crtc->base.enabled = dev_priv->display.get_pipe_config(crtc, crtc_state);
 
-		crtc->base.enabled = pipe_config->base.enable =
-		pipe_config->base.active =
-			dev_priv->display.get_pipe_config(crtc, pipe_config);
+	drm_plane_state = drm_atomic_get_plane_state(state, primary);
+	if (IS_ERR(drm_plane_state))
+		return PTR_ERR(drm_plane_state);
 
-		plane_state = to_intel_plane_state(primary->state);
-		plane_state->hw_enabled = plane_state->visible =
-			primary_get_hw_state(crtc);
-		if (plane_state->visible)
-			crtc->base.state->plane_mask |=
-				1 << drm_plane_index(primary);
-		else
-			crtc->base.state->plane_mask &=
-				~(1 << drm_plane_index(primary));
+	plane_state = to_intel_plane_state(drm_plane_state);
+	plane_state->hw_enabled = plane_state->visible =
+		primary_get_hw_state(crtc);
 
-		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
-			      crtc->base.base.id,
-			      crtc->base.state->active ? "enabled" : "disabled");
-	}
+	if (plane_state->visible)
+		crtc_state->base.plane_mask |= 1 << drm_plane_index(primary);
+	else
+		crtc_state->base.plane_mask &= ~(1 << drm_plane_index(primary));
+
+	DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
+		      crtc->base.base.id,
+		      crtc_state->base.active ? "enabled" : "disabled");
+
+	return 0;
+}
 
+static int readout_hw_pll_state(struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_shared_dpll_config *shared_dpll;
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
+	int i;
+
+	shared_dpll = intel_atomic_get_shared_dpll_state(state);
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
 		pll->on = pll->get_hw_state(dev_priv, pll,
-					    &pll->config.hw_state);
+					    &shared_dpll[i].hw_state);
+
 		pll->active = 0;
-		pll->config.crtc_mask = 0;
-		for_each_intel_crtc(dev, crtc) {
-			if (crtc->base.state->active &&
-			    i == to_intel_crtc_state(crtc->base.state)->shared_dpll) {
+		shared_dpll[i].crtc_mask = 0;
+
+		for_each_intel_crtc(state->dev, crtc) {
+			crtc_state = intel_atomic_get_crtc_state(state, crtc);
+			if (IS_ERR(crtc_state))
+				return PTR_ERR(crtc_state);
+
+			if (crtc_state->base.active &&
+			    crtc_state->shared_dpll == i) {
 				pll->active++;
-				pll->config.crtc_mask |= 1 << crtc->pipe;
+				shared_dpll[i].crtc_mask |=
+					1 << crtc->pipe;
 			}
 		}
 
 		DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
-			      pll->name, pll->config.crtc_mask, pll->on);
+			      pll->name, shared_dpll[i].crtc_mask,
+			      pll->on);
 
-		if (pll->config.crtc_mask)
+		if (shared_dpll[i].crtc_mask)
 			intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
 	}
 
-	for_each_intel_encoder(dev, encoder) {
-		pipe = 0;
+	return 0;
+}
 
-		if (encoder->get_hw_state(encoder, &pipe)) {
-			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-			encoder->base.crtc = &crtc->base;
-			encoder->get_config(encoder,
-				to_intel_crtc_state(crtc->base.state));
-		} else {
-			encoder->base.crtc = NULL;
-		}
+static struct drm_connector_state *
+get_connector_state_for_encoder(struct drm_atomic_state *state,
+				struct intel_encoder *encoder)
+{
+	struct drm_connector *connector;
+	struct drm_connector_state *connector_state;
+	int i;
 
-		encoder->connectors_active = false;
-		DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
-			      encoder->base.base.id,
-			      encoder->base.name,
-			      encoder->base.crtc ? "enabled" : "disabled",
-			      pipe_name(pipe));
-	}
+	for_each_connector_in_state(state, connector, connector_state, i)
+		if (connector_state->best_encoder == &encoder->base)
+			return connector_state;
+
+	return NULL;
+}
+
+static int readout_hw_connector_encoder_state(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_crtc *crtc;
+	struct drm_crtc_state *drm_crtc_state;
+	struct intel_crtc_state *crtc_state;
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	struct drm_connector_state *connector_state;
+	enum pipe pipe;
 
 	for_each_intel_connector(dev, connector) {
+		connector_state =
+			drm_atomic_get_connector_state(state, &connector->base);
+		if (IS_ERR(connector_state))
+			return PTR_ERR(connector_state);
+
 		if (connector->get_hw_state(connector)) {
 			connector->base.dpms = DRM_MODE_DPMS_ON;
-			connector->encoder->connectors_active = true;
 			connector->base.encoder = &connector->encoder->base;
 		} else {
 			connector->base.dpms = DRM_MODE_DPMS_OFF;
 			connector->base.encoder = NULL;
 		}
+
+		/* We'll update the crtc field when reading encoder state */
+		connector_state->crtc = NULL;
+
+		connector_state->best_encoder = connector->base.encoder;
+
 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n",
 			      connector->base.base.id,
 			      connector->base.name,
 			      connector->base.encoder ? "enabled" : "disabled");
 	}
+
+	for_each_intel_encoder(dev, encoder) {
+		pipe = 0;
+
+		connector_state =
+			get_connector_state_for_encoder(state, encoder);
+
+		encoder->connectors_active = !!connector_state;
+
+		if (encoder->get_hw_state(encoder, &pipe)) {
+			encoder->base.crtc =
+				dev_priv->pipe_to_crtc_mapping[pipe];
+			crtc = to_intel_crtc(encoder->base.crtc);
+
+			drm_crtc_state =
+				state->crtc_states[drm_crtc_index(&crtc->base)];
+			crtc_state = to_intel_crtc_state(drm_crtc_state);
+
+			encoder->get_config(encoder, crtc_state);
+
+			if (connector_state)
+				connector_state->crtc = &crtc->base;
+		} else {
+			encoder->base.crtc = NULL;
+		}
+
+		DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
+			      encoder->base.base.id,
+			      encoder->base.name,
+			      encoder->base.crtc ? "enabled" : "disabled",
+			      pipe_name(pipe));
+	}
+
+	return 0;
+}
+
+static struct drm_atomic_state *
+intel_modeset_readout_hw_state(struct drm_device *dev)
+{
+	struct intel_crtc *crtc;
+	int ret = 0;
+
+	struct drm_atomic_state *state;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
+	for_each_intel_crtc(dev, crtc) {
+		ret = readout_hw_crtc_state(state, crtc);
+		if (ret)
+			goto err_free;
+	}
+
+	ret = readout_hw_pll_state(state);
+	if (ret)
+		goto err_free;
+
+	ret = readout_hw_connector_encoder_state(state);
+	if (ret)
+		goto err_free;
+
+	return state;
+
+err_free:
+	drm_atomic_state_free(state);
+	return ERR_PTR(ret);
 }
 
 /* Scan out the current hw modeset state, sanitizes it and maps it into the drm
@@ -14798,43 +14903,61 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 				  bool force_restore)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	enum pipe pipe;
-	struct intel_crtc *crtc;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	struct intel_encoder *encoder;
+	struct drm_atomic_state *state;
+	struct intel_shared_dpll_config shared_dplls[I915_NUM_PLLS];
 	int i;
 
-	unsigned crtc_mask;
+	state = intel_modeset_readout_hw_state(dev);
+	if (IS_ERR(state)) {
+		DRM_ERROR("Failed to read out hw state\n");
+		return;
+	}
+
+	drm_atomic_helper_swap_state(dev, state);
 
-	intel_modeset_readout_hw_state(dev, &crtc_mask);
+	/* swap sw/hw dpll state */
+	BUILD_BUG_ON(sizeof(shared_dplls) !=
+		     sizeof(to_intel_atomic_state(state)->shared_dpll));
 
-	/*
-	 * Now that we have the config, copy it to each CRTC struct
-	 * Note that this could go away if we move to using crtc_config
-	 * checking everywhere.
-	 */
-	for_each_intel_crtc(dev, crtc) {
-		if (crtc->base.state->active && i915.fastboot) {
-			intel_mode_from_pipe_config(&crtc->base.mode,
-				to_intel_crtc_state(crtc->base.state));
-			DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
-				      crtc->base.base.id);
-			drm_mode_debug_printmodeline(&crtc->base.mode);
-		}
-	}
+	intel_atomic_duplicate_dpll_state(dev_priv, shared_dplls);
+	intel_shared_dpll_commit(state);
+	memcpy(to_intel_atomic_state(state)->shared_dpll,
+	       shared_dplls, sizeof(*shared_dplls) * dev_priv->num_shared_dpll);
 
 	/* HW state is read out, now we need to sanitize this mess. */
 	for_each_intel_encoder(dev, encoder) {
 		intel_sanitize_encoder(encoder);
 	}
 
-	for_each_pipe(dev_priv, pipe) {
-		struct intel_crtc_state *pipe_config;
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		/* prevent unnneeded restores with force_restore */
+		crtc_state->active_changed =
+		crtc_state->mode_changed =
+		crtc_state->planes_changed = false;
+
+		if (crtc->enabled) {
+			intel_mode_from_pipe_config(&crtc->state->mode,
+				to_intel_crtc_state(crtc->state));
+
+			drm_mode_copy(&crtc->mode, &crtc->state->mode);
+			drm_mode_copy(&crtc->hwmode,
+				      &crtc->state->adjusted_mode);
+		}
 
-		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
-		pipe_config = to_intel_crtc_state(crtc->base.state);
+		intel_sanitize_crtc(intel_crtc,
+				    to_intel_crtc_state(crtc->state));
 
-		intel_sanitize_crtc(crtc, pipe_config);
-		intel_dump_pipe_config(crtc, pipe_config,
+		/*
+		 * sanitize_crtc may have forced an update of crtc->state,
+		 * so reload in intel_dump_pipe_config
+		 */
+		intel_dump_pipe_config(intel_crtc,
+				       to_intel_crtc_state(crtc->state),
 				       "[setup_hw_state]");
 	}
 
@@ -14858,19 +14981,17 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 		ilk_wm_get_hw_state(dev);
 
 	if (force_restore) {
-		i915_redisable_vga(dev);
+		int ret;
 
-		/*
-		 * We need to use raw interfaces for restoring state to avoid
-		 * checking (bogus) intermediate states.
-		 */
-		for_each_pipe(dev_priv, pipe) {
-			struct drm_crtc *crtc =
-				dev_priv->pipe_to_crtc_mapping[pipe];
+		i915_redisable_vga(dev);
 
-			if (crtc_mask & (1 << drm_crtc_index(crtc)))
-				intel_crtc_restore_mode(crtc);
+		ret = intel_set_mode(state);
+		if (ret) {
+			DRM_ERROR("Failed to restore previous mode\n");
+			drm_atomic_state_free(state);
 		}
+	} else {
+		drm_atomic_state_free(state);
 	}
 
 	intel_modeset_check_state(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4971a5a35db4..48520993c3ad 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1396,10 +1396,13 @@ int intel_connector_atomic_get_property(struct drm_connector *connector,
 struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
+
 struct drm_atomic_state *intel_atomic_new_state(struct drm_device *dev);
 void intel_atomic_clear_state(struct drm_atomic_state *);
 struct intel_shared_dpll_config *
 intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s);
+void intel_atomic_duplicate_dpll_state(struct drm_i915_private *,
+				       struct intel_shared_dpll_config *);
 
 static inline struct intel_crtc_state *
 intel_atomic_get_crtc_state(struct drm_atomic_state *state,
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH 42/42] drm/i915: return early in __intel_set_mode_setup_plls without modeset
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (40 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 41/42] drm/i915: Read hw state into an atomic state struct Maarten Lankhorst
@ 2015-05-11 14:25 ` Maarten Lankhorst
  2015-05-13  7:04 ` [PATCH 00/42] drm/i915: Convert to atomic, part 2 Daniel Vetter
  42 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-11 14:25 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Don't walk the crtc_state twice if there's no need for it.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 386d9599d918..4c17ab81dcb3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11972,6 +11972,7 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 	struct intel_crtc_state *intel_crtc_state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
+	struct intel_shared_dpll_config *shared_dpll;
 	int ret = 0;
 	int i;
 
@@ -11990,13 +11991,13 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
 		}
 	}
 
-	if (clear_pipes) {
-		struct intel_shared_dpll_config *shared_dpll =
-			intel_atomic_get_shared_dpll_state(state);
+	if (!clear_pipes)
+		return 0;
 
-		for (i = 0; i < dev_priv->num_shared_dpll; i++)
-			shared_dpll[i].crtc_mask &= ~clear_pipes;
-	}
+	shared_dpll = intel_atomic_get_shared_dpll_state(state);
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++)
+		shared_dpll[i].crtc_mask &= ~clear_pipes;
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		if (!needs_modeset(crtc_state) || !crtc_state->active)
-- 
2.1.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH 03/42] drm/i915: Only update required power domains.
  2015-05-11 14:24 ` [PATCH 03/42] drm/i915: Only update required power domains Maarten Lankhorst
@ 2015-05-11 17:00   ` Daniel Vetter
  2015-05-12 12:05     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:00 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:39PM +0200, Maarten Lankhorst wrote:
> This prevents unnecessarily updating power domains, while still
> enabling all power domains on initial setup.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 52 ++++++++++++++++++++++++++++--------
>  1 file changed, 41 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index af96d686aae2..42d0cc329b37 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5298,36 +5298,72 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
>  	return mask;
>  }
>  
> +static bool
> +needs_modeset(struct drm_crtc_state *state)

I think we should extract this from drm_atomic_helper.c. But that can be
done as a follow-up - if you track it ;-)
> +{
> +	return state->mode_changed || state->active_changed;
> +}
> +
>  static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = state->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
>  	struct intel_crtc *crtc;
> +	bool init_power = dev_priv->power_domains.init_power_on;
> +	bool any_power = init_power, any_modeset = false;
> +	unsigned long domains;
>  
>  	/*
>  	 * First get all needed power domains, then put all unneeded, to avoid
>  	 * any unnecessary toggling of the power wells.
>  	 */
>  	for_each_intel_crtc(dev, crtc) {
> +		int idx = drm_crtc_index(&crtc->base);
> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
>  		enum intel_display_power_domain domain;
>  
> -		if (!crtc->base.state->enable)
> +		if (!init_power && !crtc_state)
> +			continue;

		if (!needs_modeset)
			continue;

while you're optimizing this?

> +
> +		if (needs_modeset(crtc->base.state))
> +			any_modeset = true;
> +
> +		if (crtc->base.state->enable)
> +			pipe_domains[crtc->pipe] =
> +				get_crtc_power_domains(&crtc->base);
> +
> +		if (pipe_domains[crtc->pipe] == crtc->enabled_power_domains)
>  			continue;
>  
> -		pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
> +		WARN_ON(!init_power && !needs_modeset(crtc->base.state));
> +
> +		any_power = true;
> +		domains = pipe_domains[crtc->pipe] &
> +			  ~crtc->enabled_power_domains;
>  
> -		for_each_power_domain(domain, pipe_domains[crtc->pipe])
> +		for_each_power_domain(domain, domains)
>  			intel_display_power_get(dev_priv, domain);
>  	}
>  
> -	if (dev_priv->display.modeset_global_resources)
> +	if (any_modeset && dev_priv->display.modeset_global_resources)
>  		dev_priv->display.modeset_global_resources(state);
>  
> +	if (!any_power)
> +		return;
> +
>  	for_each_intel_crtc(dev, crtc) {
> +		int idx = drm_crtc_index(&crtc->base);
> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
>  		enum intel_display_power_domain domain;
>  
> -		for_each_power_domain(domain, crtc->enabled_power_domains)
> +		if (!init_power && !crtc_state)
> +			continue;

Same shortcut here?
-Daniel

> +
> +		domains = crtc->enabled_power_domains &
> +			  ~pipe_domains[crtc->pipe];
> +
> +		for_each_power_domain(domain, domains)
>  			intel_display_power_put(dev_priv, domain);
>  
>  		crtc->enabled_power_domains = pipe_domains[crtc->pipe];
> @@ -11539,12 +11575,6 @@ static bool intel_crtc_in_use(struct drm_crtc *crtc)
>  	return false;
>  }
>  
> -static bool
> -needs_modeset(struct drm_crtc_state *state)
> -{
> -	return state->mode_changed || state->active_changed;
> -}
> -
>  static void
>  intel_modeset_update_state(struct drm_atomic_state *state)
>  {
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2
  2015-05-11 14:24 ` [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2 Maarten Lankhorst
@ 2015-05-11 17:08   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:08 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:38PM +0200, Maarten Lankhorst wrote:
> Now that the dpll updates are (mostly) atomic, the .off() code is no longer used,
> and there are no more callers for intel_put_shared_dpll. Move all the updates
> done in intel_crtc_disable to intel_modeset_update_state, one less special case
> to worry about.

The commit message is a bit innaccurate: We do still have callers of
put_shared_dpll, but that work is superseeded by
intel_shared_dpll_start_config. Hopefully.

Because of that I think this should be two patches: First one to nuke
put_shared_dpll, second one to inline crtc_disable.

One comment below.

> 
> Changes since v1:
> - Move drm_atomic_helper_swap_state up.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   1 -
>  drivers/gpu/drm/i915/intel_display.c | 106 +++++++----------------------------
>  drivers/gpu/drm/i915/intel_drv.h     |   1 -
>  3 files changed, 19 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 6b3142a99171..a6d3ab94ec15 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -574,7 +574,6 @@ struct drm_i915_display_funcs {
>  				  struct intel_crtc_state *crtc_state);
>  	void (*crtc_enable)(struct drm_crtc *crtc);
>  	void (*crtc_disable)(struct drm_crtc *crtc);
> -	void (*off)(struct drm_crtc *crtc);
>  	void (*audio_codec_enable)(struct drm_connector *connector,
>  				   struct intel_encoder *encoder,
>  				   struct drm_display_mode *mode);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c5543f0bcda9..af96d686aae2 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4228,27 +4228,6 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
>  	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
>  }
>  
> -void intel_put_shared_dpll(struct intel_crtc *crtc)
> -{
> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> -
> -	if (pll == NULL)
> -		return;
> -
> -	if (!(pll->config.crtc_mask & (1 << crtc->pipe))) {
> -		WARN(1, "bad %s crtc mask\n", pll->name);
> -		return;
> -	}
> -
> -	pll->config.crtc_mask &= ~(1 << crtc->pipe);
> -	if (pll->config.crtc_mask == 0) {
> -		WARN_ON(pll->on);
> -		WARN_ON(pll->active);
> -	}

We're dropping the edge-detection warnings here. But I think the code in
check_shared_dpll_state should be paranoid enough to keep us covered.
Worth mentioning in the commit message though.
-Daniel

> -
> -	crtc->config->shared_dpll = DPLL_ID_PRIVATE;
> -}
> -
>  struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
>  						struct intel_crtc_state *crtc_state)
>  {
> @@ -5224,13 +5203,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>  		intel_disable_shared_dpll(intel_crtc);
>  }
>  
> -static void ironlake_crtc_off(struct drm_crtc *crtc)
> -{
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	intel_put_shared_dpll(intel_crtc);
> -}
> -
> -
>  static void i9xx_pfit_enable(struct intel_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->base.dev;
> @@ -6062,10 +6034,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  	mutex_unlock(&dev->struct_mutex);
>  }
>  
> -static void i9xx_crtc_off(struct drm_crtc *crtc)
> -{
> -}
> -
>  /* Master function to enable/disable CRTC and corresponding power wells */
>  void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  {
> @@ -6115,34 +6083,6 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc)
>  	crtc->state->active = enable;
>  }
>  
> -static void intel_crtc_disable(struct drm_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_connector *connector;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	/* crtc should still be enabled when we disable it. */
> -	WARN_ON(!crtc->state->enable);
> -
> -	intel_crtc_disable_planes(crtc);
> -	dev_priv->display.crtc_disable(crtc);
> -	dev_priv->display.off(crtc);
> -
> -	drm_plane_helper_disable(crtc->primary);
> -
> -	/* Update computed state. */
> -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> -		if (!connector->encoder || !connector->encoder->crtc)
> -			continue;
> -
> -		if (connector->encoder->crtc != crtc)
> -			continue;
> -
> -		connector->dpms = DRM_MODE_DPMS_OFF;
> -		to_intel_encoder(connector->encoder)->connectors_active = false;
> -	}
> -}
> -
>  void intel_encoder_destroy(struct drm_encoder *encoder)
>  {
>  	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> @@ -11614,26 +11554,22 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
>  	struct drm_connector *connector;
> -	int i;
>  
>  	intel_shared_dpll_commit(dev_priv);
> +	drm_atomic_helper_swap_state(state->dev, state);
>  
>  	for_each_intel_encoder(dev, intel_encoder) {
>  		if (!intel_encoder->base.crtc)
>  			continue;
>  
> -		for_each_crtc_in_state(state, crtc, crtc_state, i)
> -			if (crtc == intel_encoder->base.crtc)
> -				break;
> -
> -		if (crtc != intel_encoder->base.crtc)
> +		crtc = intel_encoder->base.crtc;
> +		crtc_state = state->crtc_states[drm_crtc_index(crtc)];
> +		if (!crtc_state || !needs_modeset(crtc->state))
>  			continue;
>  
> -		if (crtc_state->enable && needs_modeset(crtc_state))
> -			intel_encoder->connectors_active = false;
> +		intel_encoder->connectors_active = false;
>  	}
>  
> -	drm_atomic_helper_swap_state(state->dev, state);
>  	intel_modeset_fixup_state(state);
>  
>  	/* Double check state. */
> @@ -11645,14 +11581,12 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  		if (!connector->encoder || !connector->encoder->crtc)
>  			continue;
>  
> -		for_each_crtc_in_state(state, crtc, crtc_state, i)
> -			if (crtc == connector->encoder->crtc)
> -				break;
> -
> -		if (crtc != connector->encoder->crtc)
> +		crtc = connector->encoder->crtc;
> +		crtc_state = state->crtc_states[drm_crtc_index(crtc)];
> +		if (!crtc_state || !needs_modeset(crtc->state))
>  			continue;
>  
> -		if (crtc->state->enable && needs_modeset(crtc->state)) {
> +		if (crtc->state->enable) {
>  			struct drm_property *dpms_property =
>  				dev->mode_config.dpms_property;
>  
> @@ -11663,7 +11597,8 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  
>  			intel_encoder = to_intel_encoder(connector->encoder);
>  			intel_encoder->connectors_active = true;
> -		}
> +		} else
> +			connector->dpms = DRM_MODE_DPMS_OFF;
>  	}
>  
>  }
> @@ -12214,6 +12149,10 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
>  	if (IS_ERR(pipe_config))
>  		return pipe_config;
>  
> +	if (!pipe_config->base.enable &&
> +	    WARN_ON(pipe_config->base.active))
> +		pipe_config->base.active = false;
> +
>  	if (!pipe_config->base.enable)
>  		return pipe_config;
>  
> @@ -12341,12 +12280,10 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  		if (!needs_modeset(crtc_state))
>  			continue;
>  
> -		if (!crtc_state->enable) {
> -			intel_crtc_disable(crtc);
> -		} else if (crtc->state->enable) {
> -			intel_crtc_disable_planes(crtc);
> -			dev_priv->display.crtc_disable(crtc);
> -		}
> +		intel_crtc_disable_planes(crtc);
> +		dev_priv->display.crtc_disable(crtc);
> +		if (!crtc_state->enable)
> +			drm_plane_helper_disable(crtc->primary);
>  	}
>  
>  	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
> @@ -14064,7 +14001,6 @@ static void intel_init_display(struct drm_device *dev)
>  			haswell_crtc_compute_clock;
>  		dev_priv->display.crtc_enable = haswell_crtc_enable;
>  		dev_priv->display.crtc_disable = haswell_crtc_disable;
> -		dev_priv->display.off = ironlake_crtc_off;
>  		dev_priv->display.update_primary_plane =
>  			skylake_update_primary_plane;
>  	} else if (HAS_DDI(dev)) {
> @@ -14075,7 +14011,6 @@ static void intel_init_display(struct drm_device *dev)
>  			haswell_crtc_compute_clock;
>  		dev_priv->display.crtc_enable = haswell_crtc_enable;
>  		dev_priv->display.crtc_disable = haswell_crtc_disable;
> -		dev_priv->display.off = ironlake_crtc_off;
>  		dev_priv->display.update_primary_plane =
>  			ironlake_update_primary_plane;
>  	} else if (HAS_PCH_SPLIT(dev)) {
> @@ -14086,7 +14021,6 @@ static void intel_init_display(struct drm_device *dev)
>  			ironlake_crtc_compute_clock;
>  		dev_priv->display.crtc_enable = ironlake_crtc_enable;
>  		dev_priv->display.crtc_disable = ironlake_crtc_disable;
> -		dev_priv->display.off = ironlake_crtc_off;
>  		dev_priv->display.update_primary_plane =
>  			ironlake_update_primary_plane;
>  	} else if (IS_VALLEYVIEW(dev)) {
> @@ -14096,7 +14030,6 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
>  		dev_priv->display.crtc_enable = valleyview_crtc_enable;
>  		dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -		dev_priv->display.off = i9xx_crtc_off;
>  		dev_priv->display.update_primary_plane =
>  			i9xx_update_primary_plane;
>  	} else {
> @@ -14106,7 +14039,6 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
>  		dev_priv->display.crtc_enable = i9xx_crtc_enable;
>  		dev_priv->display.crtc_disable = i9xx_crtc_disable;
> -		dev_priv->display.off = i9xx_crtc_off;
>  		dev_priv->display.update_primary_plane =
>  			i9xx_update_primary_plane;
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 29262228f264..4c690403942c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1082,7 +1082,6 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>  #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);
> -void intel_put_shared_dpll(struct intel_crtc *crtc);
>  
>  void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
>  		      const struct dpll *dpll);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 04/42] drm/i915: use intel_crtc_control everywhere
  2015-05-11 14:24 ` [PATCH 04/42] drm/i915: use intel_crtc_control everywhere Maarten Lankhorst
@ 2015-05-11 17:11   ` Daniel Vetter
  2015-05-12 12:06     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:40PM +0200, Maarten Lankhorst wrote:
> @@ -6079,26 +6059,29 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  	enum intel_display_power_domain domain;
>  	unsigned long domains;
>  
> +	if (enable == intel_crtc->active)
> +		return;
> +
> +	if (enable && !crtc->state->enable)
> +		return;

I think we only need to check for !state->enable here. Changing dpms while
the crtc is fully of is totally legit. And at least -modesetting loves to
do just that iirc.

I'll will be caught by state->active implying state->enable, but that's
hard to read imo.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 05/42] drm/i915: Get rid of new_encoder.
  2015-05-11 14:24 ` [PATCH 05/42] drm/i915: Get rid of new_encoder Maarten Lankhorst
@ 2015-05-11 17:17   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:41PM +0200, Maarten Lankhorst wrote:

Too terse commit message, especially explaining why the changes in
restore_mode are what we want seems appropriate. And mentioning the
general replacement is connector->new_encoder ->
free_standing_state->best_encoder would be good too, to make restore_mode
stand out more.
-Daniel


> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 16 +++++-----------
>  drivers/gpu/drm/i915/intel_drv.h     |  6 ------
>  2 files changed, 5 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 70269da6a6b8..00b1552a1f91 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9796,7 +9796,6 @@ retry:
>  	if (ret)
>  		goto fail_unlock;
>  	intel_encoder->new_crtc = to_intel_crtc(crtc);
> -	to_intel_connector(connector)->new_encoder = intel_encoder;
>  
>  	intel_crtc = to_intel_crtc(crtc);
>  	intel_crtc->new_enabled = true;
> @@ -9915,7 +9914,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
>  		if (IS_ERR(crtc_state))
>  			goto fail;
>  
> -		to_intel_connector(connector)->new_encoder = NULL;
>  		intel_encoder->new_crtc = NULL;
>  		intel_crtc->new_enabled = false;
>  
> @@ -11066,12 +11064,6 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
>  {
>  	struct intel_crtc *crtc;
>  	struct intel_encoder *encoder;
> -	struct intel_connector *connector;
> -
> -	for_each_intel_connector(dev, connector) {
> -		connector->new_encoder =
> -			to_intel_encoder(connector->base.encoder);
> -	}
>  
>  	for_each_intel_encoder(dev, encoder) {
>  		encoder->new_crtc =
> @@ -11886,11 +11878,14 @@ check_connector_state(struct drm_device *dev)
>  	struct intel_connector *connector;
>  
>  	for_each_intel_connector(dev, connector) {
> +		struct drm_encoder *encoder = connector->base.encoder;
> +		struct drm_connector_state *state = connector->base.state;
> +
>  		/* This also checks the encoder/connector hw state with the
>  		 * ->get_hw_state callbacks. */
>  		intel_connector_check_state(connector);
>  
> -		I915_STATE_WARN(&connector->new_encoder->base != connector->base.encoder,
> +		I915_STATE_WARN(state->best_encoder != encoder,
>  		     "connector's staged encoder doesn't match current encoder\n");
>  	}
>  }
> @@ -12410,7 +12405,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>  			continue;
>  
>  		for_each_intel_connector(dev, connector) {
> -			if (connector->new_encoder != encoder)
> +			if (connector->base.state->best_encoder != &encoder->base)
>  				continue;
>  
>  			connector_state = drm_atomic_get_connector_state(state, &connector->base);
> @@ -12423,7 +12418,6 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>  			}
>  
>  			connector_state->crtc = crtc;
> -			connector_state->best_encoder = &encoder->base;
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7390fe9ba97d..44d1de9ee2db 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -195,12 +195,6 @@ struct intel_connector {
>  	 */
>  	struct intel_encoder *encoder;
>  
> -	/*
> -	 * The new encoder this connector will be driven. Only differs from
> -	 * encoder while a modeset is in progress.
> -	 */
> -	struct intel_encoder *new_encoder;
> -
>  	/* Reads out the current hw, returning true if the connector is enabled
>  	 * and active (i.e. dpms ON state). */
>  	bool (*get_hw_state)(struct intel_connector *);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 06/42] drm/i915: get rid of new_crtc
  2015-05-11 14:24 ` [PATCH 06/42] drm/i915: get rid of new_crtc Maarten Lankhorst
@ 2015-05-11 17:28   ` Daniel Vetter
  2015-05-12 12:07     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:28 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:42PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Same comment about the terse commit message as in the previous patch.

> ---
>  drivers/gpu/drm/i915/intel_display.c | 15 ++++-----------
>  drivers/gpu/drm/i915/intel_drv.h     |  5 -----
>  2 files changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 00b1552a1f91..a9ce827601d8 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9795,7 +9795,6 @@ retry:
>  	ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
>  	if (ret)
>  		goto fail_unlock;
> -	intel_encoder->new_crtc = to_intel_crtc(crtc);
>  
>  	intel_crtc = to_intel_crtc(crtc);
>  	intel_crtc->new_enabled = true;
> @@ -9914,7 +9913,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
>  		if (IS_ERR(crtc_state))
>  			goto fail;
>  
> -		intel_encoder->new_crtc = NULL;
>  		intel_crtc->new_enabled = false;
>  
>  		connector_state->best_encoder = NULL;
> @@ -11063,12 +11061,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
>  static void intel_modeset_update_staged_output_state(struct drm_device *dev)
>  {
>  	struct intel_crtc *crtc;
> -	struct intel_encoder *encoder;
> -
> -	for_each_intel_encoder(dev, encoder) {
> -		encoder->new_crtc =
> -			to_intel_crtc(encoder->base.crtc);
> -	}
>  
>  	for_each_intel_crtc(dev, crtc) {
>  		crtc->new_enabled = crtc->base.state->enable;
> @@ -11905,8 +11897,6 @@ check_encoder_state(struct drm_device *dev)
>  			      encoder->base.base.id,
>  			      encoder->base.name);
>  
> -		I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
> -		     "encoder's stage crtc doesn't match current crtc\n");
>  		I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
>  		     "encoder's active_connectors set, but no crtc\n");
>  
> @@ -11916,6 +11906,9 @@ check_encoder_state(struct drm_device *dev)
>  			enabled = true;
>  			if (connector->base.dpms != DRM_MODE_DPMS_OFF)
>  				active = true;
> +
> +			I915_STATE_WARN(connector->base.state->crtc != encoder->base.crtc,
> +			     "encoder's stage crtc doesn't match current crtc\n");

Hm the error message doesn't make that much sense any more. What about
"encoder's legacy crtc pointer doesn't match up with connector state"?
-Daniel

>  		}
>  		/*
>  		 * for MST connectors if we unplug the connector is gone
> @@ -12401,7 +12394,7 @@ void intel_crtc_restore_mode(struct drm_crtc *crtc)
>  	 * need to copy the staged config to the atomic state, otherwise the
>  	 * mode set will just reapply the state the HW is already in. */
>  	for_each_intel_encoder(dev, encoder) {
> -		if (&encoder->new_crtc->base != crtc)
> +		if (encoder->base.crtc != crtc)
>  			continue;
>  
>  		for_each_intel_connector(dev, connector) {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 44d1de9ee2db..f85761494dd1 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -130,11 +130,6 @@ struct intel_fbdev {
>  
>  struct intel_encoder {
>  	struct drm_encoder base;
> -	/*
> -	 * The new crtc this encoder will be driven from. Only differs from
> -	 * base->crtc while a modeset is in progress.
> -	 */
> -	struct intel_crtc *new_crtc;
>  
>  	enum intel_output_type type;
>  	unsigned int cloneable;
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2.
  2015-05-11 14:24 ` [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2 Maarten Lankhorst
@ 2015-05-11 17:33   ` Daniel Vetter
  2015-05-11 17:44     ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:33 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:43PM +0200, Maarten Lankhorst wrote:
> @@ -14679,7 +14646,8 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
>  	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
>  }
>  
> -static void intel_modeset_readout_hw_state(struct drm_device *dev)
> +static void intel_modeset_readout_hw_state(struct drm_device *dev,
> +					   unsigned *crtc_mask)

Why is crtc_mask a paramter?

>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum pipe pipe;
> @@ -14688,6 +14656,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  	struct intel_connector *connector;
>  	int i;
>  
> +	*crtc_mask = 0;
>  	for_each_intel_crtc(dev, crtc) {
>  		struct drm_plane *primary = crtc->base.primary;
>  		struct intel_plane_state *plane_state;
> @@ -14696,6 +14665,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  
>  		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
>  
> +		if (crtc->active)
> +			*crtc_mask |= drm_crtc_index(&crtc->base);
> +
>  		crtc->active = dev_priv->display.get_pipe_config(crtc,
>  								 crtc->config);
>  
> @@ -14778,7 +14750,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>  	struct intel_encoder *encoder;
>  	int i;
>  
> -	intel_modeset_readout_hw_state(dev);
> +	unsigned crtc_mask;
> +
> +	intel_modeset_readout_hw_state(dev, &crtc_mask);
>  
>  	/*
>  	 * Now that we have the config, copy it to each CRTC struct
> @@ -14837,10 +14811,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>  			struct drm_crtc *crtc =
>  				dev_priv->pipe_to_crtc_mapping[pipe];
>  
> -			intel_crtc_restore_mode(crtc);
> +			if (crtc_mask & (1 << drm_crtc_index(crtc)))
> +				intel_crtc_restore_mode(crtc);

this seems a bit backwards. If we push the crtc loop down into
intel_crct_restore_mode (and call it intel_restore_mode or so) then we
could reuse the ->enable state from atomic. I.e.

	/* all the code in intel_crtc_restore_mode except the set_mode
	 * call at the bottom */

	for_crc_in_atomic_state(crtc_state) 
		if (crtc_state->enable)
			intel_set_mode

That would look more atomic imo (we'll just need to replace this loop with
a drm_atomic_commit once we're there). And contain the restore state
tracking to one function instead of spreading it over readout_hw_state.

Thoughts?
-Daniel

>  		}
> -	} else {
> -		intel_modeset_update_staged_output_state(dev);
>  	}
>  
>  	intel_modeset_check_state(dev);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index f85761494dd1..1e892098eea2 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -515,7 +515,6 @@ struct intel_crtc {
>  
>  	struct intel_initial_plane_config plane_config;
>  	struct intel_crtc_state *config;
> -	bool new_enabled;
>  
>  	/* reset counter value when the last flip was submitted */
>  	unsigned int reset_counter;
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2.
  2015-05-11 17:33   ` Daniel Vetter
@ 2015-05-11 17:44     ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 17:44 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 07:33:01PM +0200, Daniel Vetter wrote:
> On Mon, May 11, 2015 at 04:24:43PM +0200, Maarten Lankhorst wrote:
> > @@ -14679,7 +14646,8 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
> >  	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
> >  }
> >  
> > -static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > +static void intel_modeset_readout_hw_state(struct drm_device *dev,
> > +					   unsigned *crtc_mask)
> 
> Why is crtc_mask a paramter?
> 
> >  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	enum pipe pipe;
> > @@ -14688,6 +14656,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  	struct intel_connector *connector;
> >  	int i;
> >  
> > +	*crtc_mask = 0;
> >  	for_each_intel_crtc(dev, crtc) {
> >  		struct drm_plane *primary = crtc->base.primary;
> >  		struct intel_plane_state *plane_state;
> > @@ -14696,6 +14665,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  
> >  		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
> >  
> > +		if (crtc->active)
> > +			*crtc_mask |= drm_crtc_index(&crtc->base);
> > +
> >  		crtc->active = dev_priv->display.get_pipe_config(crtc,
> >  								 crtc->config);
> >  
> > @@ -14778,7 +14750,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
> >  	struct intel_encoder *encoder;
> >  	int i;
> >  
> > -	intel_modeset_readout_hw_state(dev);
> > +	unsigned crtc_mask;
> > +
> > +	intel_modeset_readout_hw_state(dev, &crtc_mask);
> >  
> >  	/*
> >  	 * Now that we have the config, copy it to each CRTC struct
> > @@ -14837,10 +14811,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
> >  			struct drm_crtc *crtc =
> >  				dev_priv->pipe_to_crtc_mapping[pipe];
> >  
> > -			intel_crtc_restore_mode(crtc);
> > +			if (crtc_mask & (1 << drm_crtc_index(crtc)))
> > +				intel_crtc_restore_mode(crtc);
> 
> this seems a bit backwards. If we push the crtc loop down into
> intel_crct_restore_mode (and call it intel_restore_mode or so) then we
> could reuse the ->enable state from atomic. I.e.
> 
> 	/* all the code in intel_crtc_restore_mode except the set_mode
> 	 * call at the bottom */
> 
> 	for_crc_in_atomic_state(crtc_state) 
> 		if (crtc_state->enable)
> 			intel_set_mode
> 
> That would look more atomic imo (we'll just need to replace this loop with
> a drm_atomic_commit once we're there). And contain the restore state
> tracking to one function instead of spreading it over readout_hw_state.

This doesn't work, and we actually need to pull the atomic state copying
out of restore_mode up into readout_hw_state so that we can use it instead
of ->new_* pointers and intel_crtc->config. And that needs to happen
_before_ remove the new_ pointers ofc.

Otherwise (i.e. after this patch) well overwrite object linking in
readout_hw_state and then restore_mode will do something silly.

Or do I still miss something?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state
  2015-05-11 14:24 ` [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state Maarten Lankhorst
@ 2015-05-11 18:12   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-11 18:12 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:44PM +0200, Maarten Lankhorst wrote:
> Assume the function is locked with drm_modeset_lock_all for now.

s/toggle/control/ in the commit message.

And a bit of blabla would be good to explain why we need to make a
mass-replacement of state->enable to state->active here now. And looking
at the enable/active replacement in detail I think we should do this in an
upfront patch first (the state should be consistent already). And have the
reworking of intel_crtc_control in a separate split-out patch.

> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c      |  2 +-
>  drivers/gpu/drm/i915/intel_display.c | 79 ++++++++++++++++++++++--------------
>  2 files changed, 50 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9da955e4f355..a6816503a080 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -796,7 +796,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
>  		return -EINVAL;
>  	}
>  
> -	if (!crtc->state->enable) {
> +	if (!crtc->state->active) {
>  		DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
>  		return -EBUSY;
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 8c2fb951029b..a21b2e51c054 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c

One s/state->enable/state->active/ in modeset_update_crtc_power_domains
seems to be missing.

> @@ -4656,7 +4656,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
>  	bool reenable_ips = false;
>  
>  	/* The clocks have to be on to load the palette. */
> -	if (!crtc->state->enable || !intel_crtc->active)
> +	if (!crtc->state->active || !intel_crtc->active)

Replace the check for intel_crtc->active with a WARN_ON?

>  		return;
>  
>  	if (HAS_GMCH_DISPLAY(dev_priv->dev)) {
> @@ -5767,7 +5767,7 @@ static int valleyview_modeset_global_pipes(struct drm_atomic_state *state)
>  
>  	/* add all active pipes to the state */
>  	for_each_crtc(state->dev, crtc) {
> -		if (!crtc->state->enable)
> +		if (!crtc->state->active)
>  			continue;
>  
>  		crtc_state = drm_atomic_get_crtc_state(state, crtc);

The second state->enable looks a bit funky, imo

	if (crtc_state->active)
		crtc_state->active_changed

after this patch would make a lot of sense. That way we won't try to frob
pipes which are already off.

> @@ -5865,7 +5865,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  	int pipe = intel_crtc->pipe;
>  	bool is_dsi;
>  
> -	WARN_ON(!crtc->state->enable);
> +	WARN_ON(!crtc->state->active);

You don't update haswell/ironlake_crtc_enable, which is inconsistent.

>  
>  	if (intel_crtc->active)
>  		return;
> @@ -5943,7 +5943,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
>  
> -	WARN_ON(!crtc->state->enable);
> +	WARN_ON(!crtc->state->active);
>  
>  	if (intel_crtc->active)
>  		return;

intel_connector_check_state should gain a

			I915_STATE_WARN(!crtc->state->active,
					"crtc not active\n");

imo.

Similar for check_crtc_state:

		I915_STATE_WARN(active != crtc->state->active,
		     "crtc's computed active state doesn't match sw active state "
		     "(expected %i, found %i)\n", active, crtc->active);


> @@ -6054,10 +6054,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  {
>  	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum intel_display_power_domain domain;
> -	unsigned long domains;
> +	struct intel_crtc_state *pipe_config;
> +	struct drm_plane_state *plane_state;
> +	struct drm_atomic_state *state;
> +	int ret;
>  
>  	if (enable == intel_crtc->active)
>  		return;
> @@ -6065,24 +6068,40 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  	if (enable && !crtc->state->enable)
>  		return;
>  
> -	crtc->state->active = enable;
> -	if (enable) {
> -		domains = get_crtc_power_domains(crtc);
> -		for_each_power_domain(domain, domains)
> -			intel_display_power_get(dev_priv, domain);
> -		intel_crtc->enabled_power_domains = domains;
> +	/* this function should be called with drm_modeset_lock_all for now */
> +	if (WARN_ON(!ctx))
> +		return;
> +	lockdep_assert_held(&ctx->ww_ctx);
>  
> -		dev_priv->display.crtc_enable(crtc);
> -		intel_crtc_enable_planes(crtc);
> -	} else {
> -		intel_crtc_disable_planes(crtc);
> -		dev_priv->display.crtc_disable(crtc);
> +	state = drm_atomic_state_alloc(dev);
> +	if (WARN_ON(!state))
> +		return;
>  
> -		domains = intel_crtc->enabled_power_domains;
> -		for_each_power_domain(domain, domains)
> -			intel_display_power_put(dev_priv, domain);
> -		intel_crtc->enabled_power_domains = 0;
> +	state->acquire_ctx = ctx;
> +	state->allow_modeset = true;
> +
> +	pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> +	if (IS_ERR(pipe_config)) {
> +		ret = PTR_ERR(pipe_config);
> +		goto err;
>  	}
> +	pipe_config->base.active = enable;
> +
> +	plane_state = drm_atomic_get_plane_state(state, crtc->primary);
> +	if (IS_ERR(plane_state)) {
> +		ret = PTR_ERR(plane_state);
> +		goto err;
> +	}
> +
> +	ret = intel_set_mode(crtc, state);
> +	if (!ret)
> +		return;
> +
> +	DRM_ERROR("Failed to toggle crtc!\n");
> +
> +err:
> +	DRM_ERROR("Updating crtc active failed with %i\n", ret);
> +	drm_atomic_state_free(state);
>  }
>  
>  /**
> @@ -6158,7 +6177,7 @@ static void intel_connector_check_state(struct intel_connector *connector)
>  
>  			crtc = encoder->base.crtc;
>  
> -			I915_STATE_WARN(!crtc->state->enable,
> +			I915_STATE_WARN(!crtc->state->active,
>  					"crtc not enabled\n");
>  			I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
>  			I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
> @@ -11554,7 +11573,7 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  		if (!crtc_state || !needs_modeset(crtc->state))
>  			continue;
>  
> -		if (crtc->state->enable) {
> +		if (crtc->state->active) {
>  			struct drm_property *dpms_property =
>  				dev->mode_config.dpms_property;
>  
> @@ -12018,7 +12037,7 @@ check_shared_dpll_state(struct drm_device *dev)
>  		     pll->on, active);
>  
>  		for_each_intel_crtc(dev, crtc) {
> -			if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
> +			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
>  				enabled_crtcs++;
>  			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
>  				active_crtcs++;
> @@ -12185,7 +12204,7 @@ static int __intel_set_mode_setup_plls(struct drm_atomic_state *state)
>  		goto done;
>  
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!needs_modeset(crtc_state) || !crtc_state->enable)
> +		if (!needs_modeset(crtc_state) || !crtc_state->active)
>  			continue;
>  
>  		intel_crtc = to_intel_crtc(crtc);
> @@ -12265,7 +12284,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	 * pipes; here we assume a single modeset_pipe and only track the
>  	 * single crtc and mode.
>  	 */
> -	if (pipe_config->base.enable && needs_modeset(&pipe_config->base)) {
> +	if (pipe_config->base.active && needs_modeset(&pipe_config->base)) {
>  		modeset_crtc->mode = pipe_config->base.mode;
>  
>  		/*
> @@ -12290,7 +12309,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  
>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!needs_modeset(crtc->state) || !crtc->state->enable)

Why did you drop this needs_modeset check here? Won't this lead to an
enabled pipe getting enabled again, which is troublesome?

> +		if (!crtc->state->active)
>  			continue;
>  
>  		update_scanline_offset(to_intel_crtc(crtc));

__intel_mode_set also seems to have some troublesome use of state->enable.
Or missing checks for state->active maybe, dunno.

> @@ -14516,7 +14535,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  	 * have active connectors/encoders. */
>  	intel_crtc_update_dpms(&crtc->base);
>  
> -	if (crtc->active != crtc->base.state->enable) {
> +	if (crtc->active != crtc->base.state->active) {
>  		struct intel_encoder *encoder;
>  
>  		/* This can happen either due to bugs in the get_hw_state
> @@ -14665,7 +14684,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  
>  		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
>  
> -		if (crtc->active)
> +		if (crtc->base.state->active)
>  			*crtc_mask |= drm_crtc_index(&crtc->base);
>  
>  		crtc->active = dev_priv->display.get_pipe_config(crtc,

These two hunks look like follow-up or independant work to switch from
intel_crtc->active to state->active. Imo better separate.

Cheers, Daniel
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
  2015-05-11 14:24 ` [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper Maarten Lankhorst
@ 2015-05-12  6:59   ` Daniel Vetter
  2015-05-12 12:41     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  6:59 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:45PM +0200, Maarten Lankhorst wrote:
> This should be safe.

Usual request: A few more details about what you've changed to help guide
the review would be great. E.g. which functions from the atomic helpers
you're trying to copy here exactly.

It looks like this models set_routing_links. I think it would be rather
useful to expose this to drivers as a helper function, maybe with a more
useful name like drm_atomic_helper_update_legacy_state or similar.

Another thing I've noticed is that atomic helpers lost the call to
drm_calc_timestamping_constants. Would be good to add that to the same
function.
-Daniel

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 82 ++++++++++++++++++------------------
>  1 file changed, 41 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a21b2e51c054..956c9964275d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11084,36 +11084,48 @@ static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
>  	}
>  }
>  
> -/* Fixup legacy state after an atomic state swap.
> +/*
> + * Fixup legacy state in a similar way to
> + * drm_atomic_helper.c:set_routing_links.
>   */
>  static void intel_modeset_fixup_state(struct drm_atomic_state *state)
>  {
> -	struct intel_crtc *crtc;
> -	struct intel_encoder *encoder;
> -	struct intel_connector *connector;
> +	struct drm_connector *connector;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_connector_state *conn_state;
> +	struct drm_crtc *crtc;
> +	int i;
>  
> -	for_each_intel_connector(state->dev, connector) {
> -		connector->base.encoder = connector->base.state->best_encoder;
> -		if (connector->base.encoder)
> -			connector->base.encoder->crtc =
> -				connector->base.state->crtc;
> +	/*
> +	 * swap crtc and connector and update legacy state,
> +	 * plane state already gets swapped
> +	 * by the plane helpers. Once .crtc_disable is fixed
> +	 * all state should be swapped before disabling crtc's.
> +	 */
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		crtc->enabled = crtc->state->enable;
> +		crtc->mode = crtc->state->mode;
>  	}
>  
> -	/* Update crtc of disabled encoders */
> -	for_each_intel_encoder(state->dev, encoder) {
> -		int num_connectors = 0;
> -
> -		for_each_intel_connector(state->dev, connector)
> -			if (connector->base.encoder == &encoder->base)
> -				num_connectors++;
> +	/* clear out existing links */
> +	for_each_connector_in_state(state, connector, conn_state, i) {
> +		if (!connector->encoder)
> +			continue;
>  
> -		if (num_connectors == 0)
> -			encoder->base.crtc = NULL;
> +		WARN_ON(!connector->encoder->crtc);
> +		connector->encoder->crtc = NULL;
> +		connector->encoder = NULL;
>  	}
>  
> -	for_each_intel_crtc(state->dev, crtc) {
> -		crtc->base.enabled = crtc->base.state->enable;
> -		crtc->config = to_intel_crtc_state(crtc->base.state);
> +	for_each_connector_in_state(state, connector, conn_state, i) {
> +		if (!connector->state->crtc)
> +			continue;
> +
> +		if (WARN_ON(!connector->state->best_encoder))
> +			continue;
> +
> +		connector->encoder = connector->state->best_encoder;
> +		connector->encoder->crtc = connector->state->crtc;
>  	}
>  }
>  
> @@ -11559,9 +11571,16 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  
>  	intel_modeset_fixup_state(state);
>  
> -	/* Double check state. */
>  	for_each_crtc(dev, crtc) {
> +		/* Double check state. */
>  		WARN_ON(crtc->state->enable != intel_crtc_in_use(crtc));
> +
> +		if (!state->crtcs[drm_crtc_index(crtc)])
> +			continue;
> +
> +		to_intel_crtc(crtc)->config = to_intel_crtc_state(crtc->state);
> +		if (crtc->state->active && needs_modeset(crtc->state))
> +			drm_calc_timestamping_constants(crtc, &crtc->state->adjusted_mode);
>  	}
>  
>  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> @@ -12277,25 +12296,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  			drm_plane_helper_disable(crtc->primary);
>  	}
>  
> -	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
> -	 * to set it here already despite that we pass it down the callchain.
> -	 *
> -	 * Note we'll need to fix this up when we start tracking multiple
> -	 * pipes; here we assume a single modeset_pipe and only track the
> -	 * single crtc and mode.
> -	 */
> -	if (pipe_config->base.active && needs_modeset(&pipe_config->base)) {
> -		modeset_crtc->mode = pipe_config->base.mode;
> -
> -		/*
> -		 * Calculate and store various constants which
> -		 * are later needed by vblank and swap-completion
> -		 * timestamping. They are derived from true hwmode.
> -		 */
> -		drm_calc_timestamping_constants(modeset_crtc,
> -						&pipe_config->base.adjusted_mode);
> -	}
> -
>  	/* Only after disabling all output pipelines that will be changed can we
>  	 * update the the output configuration. */
>  	intel_modeset_update_state(state);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-11 14:24 ` [PATCH 10/42] drm/i915: make plane helpers fully atomic Maarten Lankhorst
@ 2015-05-12  8:18   ` Daniel Vetter
  2015-05-12 13:33     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  8:18 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
> This kills off most of the transitional helpers and uses atomic plane updates
> in the modeset path to update everything.
> 
> Getting rid of the transitional plane helpers meant that planes had to be added
> in the crtc check function. On modeset a connector can be moved to a different
> crtc, and this is not handled correctly otherwise.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Ok pile of comments on this one. I don't yet fully grasp it all, but at
the very bottom I've jotted down a list of ideas for how to move forward
with this one.

> ---
>  drivers/gpu/drm/i915/intel_atomic_plane.c |  59 ++-
>  drivers/gpu/drm/i915/intel_display.c      | 655 ++++++++++++++++++------------
>  drivers/gpu/drm/i915/intel_drv.h          |   2 +-
>  drivers/gpu/drm/i915/intel_sprite.c       |  80 +---
>  4 files changed, 441 insertions(+), 355 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> index 86ba4b2c3a65..85b87e4d4b6e 100644
> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> @@ -110,32 +110,40 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
>  				    struct drm_plane_state *state)
>  {
>  	struct drm_crtc *crtc = state->crtc;
> -	struct intel_crtc *intel_crtc;
> -	struct intel_crtc_state *crtc_state;
> +	struct drm_crtc_state *crtc_state;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct intel_plane_state *intel_state = to_intel_plane_state(state);
>  
> -	crtc = crtc ? crtc : plane->crtc;
> -	intel_crtc = to_intel_crtc(crtc);
> -
> +	intel_state->visible = false;
>  	/*
>  	 * Both crtc and plane->crtc could be NULL if we're updating a
>  	 * property while the plane is disabled.  We don't actually have
>  	 * anything driver-specific we need to test in that case, so
>  	 * just return success.
>  	 */
> -	if (!crtc)
> +	if (!crtc) {
> +		DRM_DEBUG_ATOMIC("Invisible: no crtc\n");
>  		return 0;
> +	}
> +
> +	crtc_state = state->state->crtc_states[drm_crtc_index(crtc)];

Please reuse drm_atomic_get_crtc_state, this deref magic is hard to read.
Maybe we should have a nofail variant of those to encode the below WARN_ON
even ...

> +	if (WARN_ON(!crtc_state))
> +		return 0;
> +
> +	if (!crtc_state->enable) {
> +		DRM_DEBUG_ATOMIC("Invisible: crtc off\n");
>  
> -	/* FIXME: temporary hack necessary while we still use the plane update
> -	 * helper. */
> -	if (state->state) {
> -		crtc_state =
> -			intel_atomic_get_crtc_state(state->state, intel_crtc);
> -		if (IS_ERR(crtc_state))
> -			return PTR_ERR(crtc_state);
> -	} else {
> -		crtc_state = intel_crtc->config;
> +		/*
> +		 * Probably allowed after converting to atomic. Right
> +		 * now it probably means we have the state confused.
> +		 */
> +		I915_STATE_WARN_ON(plane->type == DRM_PLANE_TYPE_PRIMARY);

This is already possible with the primary plane support - you can disable
it (though not change the mode at the same time).

> +		return 0;
> +	}
> +
> +	if (!crtc_state->active) {
> +		DRM_DEBUG_ATOMIC("Invisible: dpms off\n");
> +		return 0;
>  	}
>  
>  	/*
> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
>  	intel_state->clip.x1 = 0;
>  	intel_state->clip.y1 = 0;
> -	intel_state->clip.x2 =
> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
> -	intel_state->clip.y2 =
> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
> -
> -	/*
> -	 * Disabling a plane is always okay; we just need to update
> -	 * fb tracking in a special way since cleanup_fb() won't
> -	 * get called by the plane helpers.
> -	 */
> -	if (state->fb == NULL && plane->state->fb != NULL) {
> -		/*
> -		 * 'prepare' is never called when plane is being disabled, so
> -		 * we need to handle frontbuffer tracking as a special case
> -		 */
> -		intel_crtc->atomic.disabled_planes |=
> -			(1 << drm_plane_index(plane));
> -	}
> +	drm_crtc_get_hv_timing(&crtc_state->mode,
> +			       &intel_state->clip.x2,
> +			       &intel_state->clip.y2);

Imo this is obfuscating things a bit, why not just unconditionally copy
pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
most platforms must match the primary plane window except for gen2 and
gen9+.

>  
>  	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
>  		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 956c9964275d..9610f76a2489 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -100,14 +100,16 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
> +				   struct drm_crtc_state *crtc_state);

I consider forward declarations evil, but given how much of a mess
intel_display.c is it doesn't really matter much ;-)

>  static void intel_begin_crtc_commit(struct drm_crtc *crtc);
>  static void intel_finish_crtc_commit(struct drm_crtc *crtc);
>  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
>  	struct intel_crtc_state *crtc_state);
>  static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
>  			   int num_connectors);
> -static void intel_crtc_enable_planes(struct drm_crtc *crtc);
> -static void intel_crtc_disable_planes(struct drm_crtc *crtc);
> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
> +static void intel_post_enable_primary(struct drm_crtc *crtc);
>  
>  static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
>  {
> @@ -2220,28 +2222,6 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>  	POSTING_READ(reg);
>  }
>  
> -/**
> - * intel_enable_primary_hw_plane - enable the primary plane on a given pipe
> - * @plane:  plane to be enabled
> - * @crtc: crtc for the plane
> - *
> - * Enable @plane on @crtc, making sure that the pipe is running first.
> - */
> -static void intel_enable_primary_hw_plane(struct drm_plane *plane,
> -					  struct drm_crtc *crtc)
> -{
> -	struct drm_device *dev = plane->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	/* If the pipe isn't enabled, we can't pump pixels and may hang */
> -	assert_pipe_enabled(dev_priv, intel_crtc->pipe);
> -	to_intel_plane_state(plane->state)->visible = true;
> -
> -	dev_priv->display.update_primary_plane(crtc, plane->fb,
> -					       crtc->x, crtc->y);
> -}
> -
>  static bool need_vtd_wa(struct drm_device *dev)
>  {
>  #ifdef CONFIG_INTEL_IOMMU
> @@ -3161,11 +3141,20 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_plane_state *plane_state =
> +		to_intel_plane_state(crtc->primary->state);
> +	bool was_visible = plane_state->visible;
>  
> -	if (dev_priv->display.disable_fbc)
> +	/* Not supported right now by the helper, but lets be thorough. */
> +	if (was_visible && !fb)
> +		intel_pre_disable_primary(crtc);
> +	else if (was_visible && dev_priv->display.disable_fbc)
>  		dev_priv->display.disable_fbc(dev);
>  
> +	plane_state->visible = !!fb;
>  	dev_priv->display.update_primary_plane(crtc, fb, x, y);
> +	if (!was_visible && fb)
> +		intel_post_enable_primary(crtc);

This contains a vblank_wait (at least for broadwell) which is a no-go in
set_base_atomic. Given that this is only used by kgdb and I'm not aware of
anyone using that and we also don't have any testcase for this code I
think the best would be to just not touch this and let it keep on
bitrotting ...

>  
>  	return 0;
>  }
> @@ -3192,16 +3181,17 @@ static void intel_update_primary_planes(struct drm_device *dev)
>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
>  		drm_modeset_lock(&crtc->mutex, NULL);
> -		/*
> -		 * FIXME: Once we have proper support for primary planes (and
> -		 * disabling them without disabling the entire crtc) allow again
> -		 * a NULL crtc->primary->fb.
> -		 */
> -		if (intel_crtc->active && crtc->primary->fb)
> +
> +		if (intel_crtc->active) {
> +			const struct intel_plane_state *state =
> +				to_intel_plane_state(crtc->primary->state);
> +
>  			dev_priv->display.update_primary_plane(crtc,
> -							       crtc->primary->fb,
> -							       crtc->x,
> -							       crtc->y);
> +							state->base.fb,
> +							state->src.x1 >> 16,
> +							state->src.y1 >> 16);
> +		}

I think the above hunk could be split out. And I'm not sure it's required
really, this is just to catch up on CS flips. Which won't be used any more
once we have atomic, but until then the legacy state stuff used here
should be good enough.

> +
>  		drm_modeset_unlock(&crtc->mutex);
>  	}
>  }
> @@ -4572,20 +4562,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
>  	}
>  }
>  
> -static void intel_enable_sprite_planes(struct drm_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->dev;
> -	enum pipe pipe = to_intel_crtc(crtc)->pipe;
> -	struct drm_plane *plane;
> -	struct intel_plane *intel_plane;
> -
> -	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
> -		intel_plane = to_intel_plane(plane);
> -		if (intel_plane->pipe == pipe)
> -			intel_plane_restore(&intel_plane->base);
> -	}
> -}
> -
>  void hsw_enable_ips(struct intel_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->base.dev;
> @@ -4815,44 +4791,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
>  	hsw_disable_ips(intel_crtc);
>  }
>  
> -static void intel_crtc_enable_planes(struct drm_crtc *crtc)
> -{
> -	intel_enable_primary_hw_plane(crtc->primary, crtc);
> -	intel_enable_sprite_planes(crtc);
> -	intel_crtc_update_cursor(crtc, true);
> -
> -	intel_post_enable_primary(crtc);
> -}
> -
> -static void intel_crtc_disable_planes(struct drm_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->dev;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct intel_plane *intel_plane;
> -	int pipe = intel_crtc->pipe;
> -
> -	intel_crtc_wait_for_pending_flips(crtc);
> -
> -	intel_pre_disable_primary(crtc);
> -
> -	intel_crtc_dpms_overlay_disable(intel_crtc);
> -	for_each_intel_plane(dev, intel_plane) {
> -		if (intel_plane->pipe == pipe) {
> -			struct drm_crtc *from = intel_plane->base.crtc;
> -
> -			intel_plane->disable_plane(&intel_plane->base,
> -						   from ?: crtc, true);
> -		}
> -	}
> -
> -	/*
> -	 * FIXME: Once we grow proper nuclear flip support out of this we need
> -	 * to compute the mask of flip planes precisely. For the time being
> -	 * consider this a flip to a NULL plane.
> -	 */
> -	intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
> -}
> -
>  static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -11061,6 +10999,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
>  	.load_lut = intel_crtc_load_lut,
>  	.atomic_begin = intel_begin_crtc_commit,
>  	.atomic_flush = intel_finish_crtc_commit,
> +	.atomic_check = intel_atomic_check_crtc,
>  };
>  
>  /* Transitional helper to copy current connector/encoder state to
> @@ -11426,16 +11365,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>  	int i;
>  	bool retry = true;
>  
> -	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
> -		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> -		return -EINVAL;
> -	}
> -
> -	if (!check_digital_port_conflicts(state)) {
> -		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
> -		return -EINVAL;
> -	}
> -

I think it would help if you'd split out the addition of the crtc_check
function into a separate prep patch. At least I don't see a depency here
...

>  	clear_intel_crtc_state(pipe_config);
>  
>  	pipe_config->cpu_transcoder =
> @@ -11553,9 +11482,27 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
>  	struct drm_connector *connector;
> +	struct drm_connector_state *connector_state;
> +	int i;
>  
>  	intel_shared_dpll_commit(dev_priv);
> -	drm_atomic_helper_swap_state(state->dev, state);
> +
> +	/*
> +	 * swap crtc and connector state, plane state is already swapped in
> +	 * __intel_set_mode_update_planes. Once .crtc_disable is fixed
> +	 * all state should be swapped before disabling crtc's.
> +	 */
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		crtc->state->state = state;
> +		swap(state->crtc_states[i], crtc->state);
> +		crtc->state->state = NULL;
> +	}
> +
> +	for_each_connector_in_state(state, connector, connector_state, i) {
> +		connector->state->state = state;
> +		swap(state->connector_states[i], connector->state);
> +		connector->state->state = NULL;
> +	}
>  
>  	for_each_intel_encoder(dev, intel_encoder) {
>  		if (!intel_encoder->base.crtc)
> @@ -12163,8 +12110,8 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
>  	    WARN_ON(pipe_config->base.active))
>  		pipe_config->base.active = false;
>  
> -	if (!pipe_config->base.enable)
> -		return pipe_config;
> +	if (!pipe_config->base.active)
> +		goto done;
>  
>  	ret = intel_modeset_pipe_config(crtc, state, pipe_config);
>  	if (ret)
> @@ -12182,8 +12129,8 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
>  	 * required changes and forcing a mode set.
>  	 */
>  
> -	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,"[modeset]");
> -
> +	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, "[modeset]");
> +done:
>  	ret = drm_atomic_helper_check_planes(state->dev, state);
>  	if (ret)
>  		return ERR_PTR(ret);
> @@ -12247,6 +12194,11 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
>  	struct drm_device *dev = state->dev;
>  	int ret;
>  
> +	if (!check_digital_port_conflicts(state)) {
> +		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
> +		return -EINVAL;
> +	}
> +
>  	/*
>  	 * See if the config requires any additional preparation, e.g.
>  	 * to adjust global state with pipes off.  We need to do this
> @@ -12267,6 +12219,112 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
>  	return 0;
>  }
>  
> +static void __intel_set_mode_update_planes(struct drm_device *dev,
> +					   struct drm_atomic_state *state)
> +{
> +	int i;
> +	struct drm_plane_state *old_plane_state;
> +	struct drm_crtc_state *crtc_state;
> +	struct drm_plane *plane;
> +	struct drm_crtc *crtc;
> +
> +	/*
> +	 * For now only swap plane state, will be replaced with a
> +	 * call to drm_atomic_helper_swap_state
> +	 */
> +	for_each_plane_in_state(state, plane, old_plane_state, i) {
> +		struct drm_plane *plane = state->planes[i];
> +
> +		if (!plane)
> +			continue;
> +
> +		plane->state->state = state;
> +		swap(state->plane_states[i], plane->state);
> +		plane->state->state = NULL;
> +	}
> +
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		const struct drm_crtc_helper_funcs *funcs;
> +
> +		funcs = crtc->helper_private;
> +
> +		if (!funcs || !funcs->atomic_begin)
> +			continue;
> +
> +		/* XXX: Hack because crtc state is not swapped */
> +		crtc->state->mode_changed = crtc_state->mode_changed;
> +		crtc->state->active_changed = crtc_state->active_changed;
> +
> +		DRM_DEBUG_ATOMIC("Calling atomic_begin on crtc %i\n", i);
> +		funcs->atomic_begin(crtc);
> +	}
> +
> +	for_each_plane_in_state(state, plane, old_plane_state, i) {
> +		bool visible = to_intel_plane_state(plane->state)->visible;
> +		struct intel_plane *intel_plane = to_intel_plane(plane);
> +		const struct drm_plane_helper_funcs *funcs =
> +			plane->helper_private;
> +
> +		crtc = plane->state->crtc;
> +
> +		/* no point in disabling if already disabled */
> +		if (!to_intel_plane_state(old_plane_state)->visible &&
> +		    !to_intel_plane_state(old_plane_state)->hw_enabled)
> +			continue;
> +
> +		to_intel_plane_state(plane->state)->hw_enabled = false;
> +		DRM_DEBUG_ATOMIC("Plane %i is visible: %i\n", i, visible);
> +
> +		if (!visible)
> +			funcs->atomic_update(plane, old_plane_state);
> +		else if (needs_modeset(crtc->state))
> +			intel_plane->disable_plane(plane, crtc, true);
> +	}
> +}
> +
> +static void __intel_set_mode_cleanup_planes(struct drm_device *dev,
> +					    struct drm_atomic_state *old_state)
> +{
> +	int nplanes = dev->mode_config.num_total_plane;
> +	int ncrtcs = dev->mode_config.num_crtc;
> +	int i;
> +
> +	for (i = 0; i < nplanes; i++) {
> +		const struct drm_plane_helper_funcs *funcs;
> +		struct drm_plane *plane = old_state->planes[i];
> +		struct drm_plane_state *old_plane_state;
> +
> +		if (!plane)
> +			continue;
> +
> +		funcs = plane->helper_private;
> +		old_plane_state = old_state->plane_states[i];
> +
> +		if (to_intel_plane_state(plane->state)->visible) {
> +			DRM_DEBUG_ATOMIC("Plane %i is updated\n", i);
> +			funcs->atomic_update(plane, old_plane_state);
> +		} else
> +			DRM_DEBUG_ATOMIC("Plane %i is left alone\n", i);
> +	}
> +
> +	for (i = 0; i < ncrtcs; i++) {
> +		const struct drm_crtc_helper_funcs *funcs;
> +		struct drm_crtc *crtc = old_state->crtcs[i];
> +
> +		if (!crtc)
> +			continue;
> +
> +		funcs = crtc->helper_private;
> +
> +		if (!funcs || !funcs->atomic_flush)
> +			continue;
> +
> +		DRM_DEBUG_ATOMIC("Calling atomic_flush on crtc %i\n", i);
> +		funcs->atomic_flush(crtc);
> +	}
> +	drm_atomic_helper_cleanup_planes(dev, old_state);
> +}
> +
>  static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  			    struct intel_crtc_state *pipe_config)
>  {
> @@ -12275,7 +12333,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	struct drm_atomic_state *state = pipe_config->base.state;
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
> -	int ret = 0;
> +	int ret;
>  	int i;
>  
>  	ret = __intel_set_mode_checks(state);
> @@ -12286,14 +12344,14 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	if (ret)
>  		return ret;
>  
> +	__intel_set_mode_update_planes(dev, state);

This calls crtc->atomic_begin, which does an irq_disable ...

> +
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>  		if (!needs_modeset(crtc_state))
>  			continue;
>  
> -		intel_crtc_disable_planes(crtc);
> +		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>  		dev_priv->display.crtc_disable(crtc);
> -		if (!crtc_state->enable)
> -			drm_plane_helper_disable(crtc->primary);
>  	}
>  
>  	/* Only after disabling all output pipelines that will be changed can we
> @@ -12305,8 +12363,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  
>  	modeset_update_crtc_power_domains(state);
>  
> -	drm_atomic_helper_commit_planes(dev, state);
> -
>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>  		if (!crtc->state->active)
> @@ -12314,13 +12370,13 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  
>  		update_scanline_offset(to_intel_crtc(crtc));
>  
> -		dev_priv->display.crtc_enable(crtc);
> -		intel_crtc_enable_planes(crtc);
> +		if (needs_modeset(crtc->state))
> +			dev_priv->display.crtc_enable(crtc);
>  	}
>  
> -	/* FIXME: add subpixel order */
> +	__intel_set_mode_cleanup_planes(dev, state);

which is only cleared in atomic_flush here. We need both of these at the
bottom here. In atomic-helpers-speak the sequence should be

drm_atomic_helper_commit_modeset_disables();
drm_atomic_helper_commit_modeset_enables();
drm_atomic_helper_commit_planes();

with the note that our crtc_disable must do the unconditional plane
disabling itself. I.e. you can't just remove disable_planes without
replacement, that one needs to be open-coded (using plane->atomic_disable
if possible).

Doing things this way would also alleviate any need to split up swap_state
as you do in this patch here.

>  
> -	drm_atomic_helper_cleanup_planes(dev, state);

Please keep this separate and don't hide it in another function, it's a
distinct step from the hw update (which is now done in the misnamed
intel_set_mode_cleanup_planes).

> +	/* FIXME: add subpixel order */
>  
>  	drm_atomic_state_free(state);
>  
> @@ -12568,20 +12624,11 @@ intel_modeset_stage_output_state(struct drm_device *dev,
>  	return 0;
>  }
>  
> -static bool primary_plane_visible(struct drm_crtc *crtc)
> -{
> -	struct intel_plane_state *plane_state =
> -		to_intel_plane_state(crtc->primary->state);
> -
> -	return plane_state->visible;
> -}
> -
>  static int intel_crtc_set_config(struct drm_mode_set *set)
>  {
>  	struct drm_device *dev;
>  	struct drm_atomic_state *state = NULL;
>  	struct intel_crtc_state *pipe_config;
> -	bool primary_plane_was_visible;
>  	int ret;
>  
>  	BUG_ON(!set);
> @@ -12620,38 +12667,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
>  
>  	intel_update_pipe_size(to_intel_crtc(set->crtc));
>  
> -	primary_plane_was_visible = primary_plane_visible(set->crtc);
> -
>  	ret = intel_set_mode_with_config(set->crtc, pipe_config);
> -
> -	if (ret == 0 &&
> -	    pipe_config->base.enable &&
> -	    pipe_config->base.planes_changed &&
> -	    !needs_modeset(&pipe_config->base)) {
> -		struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
> -
> -		/*
> -		 * We need to make sure the primary plane is re-enabled if it
> -		 * has previously been turned off.
> -		 */
> -		if (ret == 0 && !primary_plane_was_visible &&
> -		    primary_plane_visible(set->crtc)) {
> -			WARN_ON(!intel_crtc->active);
> -			intel_post_enable_primary(set->crtc);
> -		}
> -
> -		/*
> -		 * In the fastboot case this may be our only check of the
> -		 * state after boot.  It would be better to only do it on
> -		 * the first update, but we don't have a nice way of doing that
> -		 * (and really, set_config isn't used much for high freq page
> -		 * flipping, so increasing its cost here shouldn't be a big
> -		 * deal).
> -		 */
> -		if (i915.fastboot && ret == 0)
> -			intel_modeset_check_state(set->crtc->dev);
> -	}
> -
>  	if (ret) {
>  		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
>  			      set->crtc->base.id, ret);
> @@ -12791,6 +12807,9 @@ bool intel_wm_need_update(struct drm_plane *plane,
>  	    plane->state->rotation != state->rotation)
>  		return true;
>  
> +	if (plane->state->crtc_w != state->crtc_w)
> +		return true;
> +
>  	return false;
>  }
>  
> @@ -12819,6 +12838,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>  	unsigned frontbuffer_bits = 0;
>  	int ret = 0;
>  
> +	if (!to_intel_plane_state(plane->state)->visible)
> +		old_obj = NULL;
> +
>  	if (!obj)
>  		return 0;
>  
> @@ -12915,10 +12937,8 @@ intel_check_primary_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
>  {
>  	struct drm_device *dev = plane->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = state->base.crtc;
>  	struct intel_crtc *intel_crtc;
> -	struct intel_crtc_state *crtc_state;
>  	struct drm_framebuffer *fb = state->base.fb;
>  	struct drm_rect *dest = &state->dst;
>  	struct drm_rect *src = &state->src;
> @@ -12926,90 +12946,46 @@ intel_check_primary_plane(struct drm_plane *plane,
>  	bool can_position = false;
>  	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
>  	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> -	int ret;
>  
> -	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> -	crtc_state = state->base.state ?
> -		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
>  	if (INTEL_INFO(dev)->gen >= 9) {
> +		struct intel_crtc_state *crtc_state =
> +			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
> +
>  		min_scale = 1;
>  		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  		can_position = true;
>  	}
>  
> -	ret = drm_plane_helper_check_update(plane, crtc, fb,
> -					    src, dest, clip,
> -					    min_scale,
> -					    max_scale,
> -					    can_position, true,
> -					    &state->visible);
> -	if (ret)
> -		return ret;
> -
> -	if (intel_crtc->active) {
> -		struct intel_plane_state *old_state =
> -			to_intel_plane_state(plane->state);
> -
> -		intel_crtc->atomic.wait_for_flips = true;
> -
> -		/*
> -		 * FBC does not work on some platforms for rotated
> -		 * planes, so disable it when rotation is not 0 and
> -		 * update it when rotation is set back to 0.
> -		 *
> -		 * FIXME: This is redundant with the fbc update done in
> -		 * the primary plane enable function except that that
> -		 * one is done too late. We eventually need to unify
> -		 * this.
> -		 */
> -		if (state->visible &&
> -		    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
> -		    dev_priv->fbc.crtc == intel_crtc &&
> -		    state->base.rotation != BIT(DRM_ROTATE_0)) {
> -			intel_crtc->atomic.disable_fbc = true;
> -		}
> -
> -		if (state->visible && !old_state->visible) {
> -			/*
> -			 * BDW signals flip done immediately if the plane
> -			 * is disabled, even if the plane enable is already
> -			 * armed to occur at the next vblank :(
> -			 */
> -			if (IS_BROADWELL(dev))
> -				intel_crtc->atomic.wait_vblank = true;
> -		}
> -
> -		intel_crtc->atomic.fb_bits |=
> -			INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
> -
> -		intel_crtc->atomic.update_fbc = true;
> -
> -		if (intel_wm_need_update(plane, &state->base))
> -			intel_crtc->atomic.update_wm = true;
> -	}
> +	return drm_plane_helper_check_update(plane, crtc, fb,
> +					     src, dest, clip,
> +					     min_scale, max_scale,
> +					     can_position, true,
> +					     &state->visible);
> +}
>  
> -	if (INTEL_INFO(dev)->gen >= 9) {
> -		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> -			to_intel_plane(plane), state, 0);
> -		if (ret)
> -			return ret;
> -	}
> +static void
> +intel_disable_primary_plane(struct drm_plane *plane,
> +			    struct drm_crtc *crtc,
> +			    bool force)
> +{
> +	struct drm_device *dev = plane->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	return 0;
> +	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
>  }
>  
>  static void
>  intel_commit_primary_plane(struct drm_plane *plane,
> -			   struct intel_plane_state *state)
> +			   struct intel_plane_state *new_state)
>  {
> -	struct drm_crtc *crtc = state->base.crtc;
> -	struct drm_framebuffer *fb = state->base.fb;
> +	struct drm_crtc *crtc = new_state->base.crtc;
> +	struct drm_framebuffer *fb = new_state->base.fb;
>  	struct drm_device *dev = plane->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc;
> -	struct drm_rect *src = &state->src;
> +	struct drm_rect *src = &new_state->src;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
> @@ -13018,25 +12994,178 @@ intel_commit_primary_plane(struct drm_plane *plane,
>  	crtc->x = src->x1 >> 16;
>  	crtc->y = src->y1 >> 16;
>  
> -	if (intel_crtc->active) {
> -		if (state->visible)
> -			/* FIXME: kill this fastboot hack */
> -			intel_update_pipe_size(intel_crtc);
> +	if (!new_state->visible ||
> +	    WARN_ON(new_state->visible && !crtc->state->active)) {
> +		intel_disable_primary_plane(plane, crtc, false);
> +	} else {
> +		/* FIXME: kill this fastboot hack */
> +		intel_update_pipe_size(intel_crtc);
>  
> -		dev_priv->display.update_primary_plane(crtc, plane->fb,
> -						       crtc->x, crtc->y);
> +		dev_priv->display.update_primary_plane(crtc, fb,
> +						       src->x1 >> 16,
> +						       src->y1 >> 16);
>  	}
>  }
>  
> -static void
> -intel_disable_primary_plane(struct drm_plane *plane,
> -			    struct drm_crtc *crtc,
> -			    bool force)
> +/* Transitional checking here, mostly for plane updates */
> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
> +				   struct drm_crtc_state *crtc_state)
>  {
> -	struct drm_device *dev = plane->dev;
> +	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_atomic_state *state = crtc_state->state;
> +	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_plane *plane;
> +	unsigned plane_mask;
> +	int idx, ret;
> +	bool mode_changed = needs_modeset(crtc_state);
> +	bool is_crtc_enabled = crtc_state->active;
> +	bool was_crtc_enabled = crtc->state->active;
>  
> -	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
> +	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
> +		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> +		return -EINVAL;
> +	}

I think we need two have 2 blocks in the crtc_check function: One part
that just updates watermarks (when state->plane_changed is set) and one
part that deals with the modeset checks (adding planes, checking cloning
and all that) when needs_modeset(state) is true.

> +
> +	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
> +	intel_crtc->atomic.update_wm = mode_changed;
> +
> +	idx = crtc->base.id;
> +	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
> +		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
> +		idx, crtc->state->active, intel_crtc->active);

State computation is async, you cant check this in the atomic_check
functions. If you think this is useful then we'd need to check this every
time before we update intel_crtc->active. But we have the various WARN_ON
all over the place (converted over to crtc->state->active) so I think
we're more than covered and can just rip out our own intel_crtc->active
eventually. At least that's kinda been my idea with state->active too.

> +
> +	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
> +			 idx, was_crtc_enabled, is_crtc_enabled);
> +
> +	plane_mask = crtc_state->plane_mask | crtc->state->plane_mask;
> +	drm_for_each_plane_mask(plane, dev, plane_mask) {
> +		int i = drm_plane_index(plane);
> +		struct drm_plane_state *plane_state = state->plane_states[i];
> +		struct intel_plane_state *old_plane_state;
> +		bool turn_off, turn_on, visible, was_visible;
> +		struct drm_framebuffer *fb;
> +
> +		if (!plane_state) {
> +			const struct drm_plane_helper_funcs *funcs;
> +			int ret;
> +
> +			if (!mode_changed || !plane->state->fb)
> +				continue;
> +
> +			plane_state = drm_atomic_get_plane_state(state, plane);

We need to check for the crtc constrains before acquiring the plane state,
otherwise all the locking goes single-threaded. On intel hw we can do that
because the plane->crtc links are static, you can look at
intel_plane->pipe.

> +			if (IS_ERR(plane_state))
> +				return PTR_ERR(plane_state);
> +
> +			funcs = plane->helper_private;
> +			ret = funcs->atomic_check(plane, plane_state);
> +			if (ret)
> +				return ret;
> +		}
> +		old_plane_state = to_intel_plane_state(plane->state);
> +
> +		was_visible = was_crtc_enabled && (old_plane_state->visible ||
> +			      old_plane_state->hw_enabled);
> +		visible = to_intel_plane_state(plane_state)->visible &&
> +			      is_crtc_enabled;
> +
> +		if (plane->state->crtc != crtc)
> +			was_visible = false;
> +		if (plane_state->crtc != crtc)
> +			visible = false;
> +
> +		if (!was_visible && !visible)
> +			continue;
> +
> +		turn_off = was_visible && (!visible || mode_changed);
> +		turn_on = visible && (!was_visible || mode_changed);
> +		fb = plane_state->fb;
> +
> +		DRM_DEBUG_ATOMIC("Crtc %i has plane %i with fb %i\n", idx,
> +			plane->base.id, fb ? fb->base.id : -1);
> +		DRM_DEBUG_ATOMIC("\tvisible %i -> %i, off %i, on %i, ms %i\n",
> +			was_visible, visible, turn_off, turn_on, mode_changed);
> +
> +		/* plane being turned off as part of modeset or changes? */
> +		if (intel_wm_need_update(plane, plane_state))
> +			intel_crtc->atomic.update_wm = true;
> +
> +		if (INTEL_INFO(dev)->gen >= 9 &&
> +		    plane->base.type != DRM_PLANE_TYPE_CURSOR) {
> +			ret = skl_update_scaler_users(intel_crtc, pipe_config,
> +					to_intel_plane(plane),
> +					to_intel_plane_state(plane_state), 0);
> +			if (ret)
> +				return ret;
> +		}
> +
> +		/*
> +		 * 'prepare' is never called when plane is being disabled, so
> +		 * we need to handle frontbuffer tracking as a special case
> +		 */
> +		if (old_plane_state->base.fb && !visible)
> +			intel_crtc->atomic.disabled_planes |= 1 << i;
> +
> +		switch (plane->base.type) {

We should probably store the frontbuffer tracking mask in intel_plane
somewhere.

> +		case DRM_PLANE_TYPE_PRIMARY:
> +			if (visible)
> +				intel_crtc->atomic.fb_bits |=
> +				    INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
> +
> +			intel_crtc->atomic.wait_for_flips = true;
> +			intel_crtc->atomic.pre_disable_primary = turn_off;
> +			intel_crtc->atomic.post_enable_primary = turn_on;
> +
> +			if (turn_off)
> +				intel_crtc->atomic.disable_fbc = true;
> +
> +			/*
> +			 * FBC does not work on some platforms for rotated
> +			 * planes, so disable it when rotation is not 0 and
> +			 * update it when rotation is set back to 0.
> +			 *
> +			 * FIXME: This is redundant with the fbc update done in
> +			 * the primary plane enable function except that that
> +			 * one is done too late. We eventually need to unify
> +			 * this.
> +			 */
> +
> +			if (visible &&
> +			    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
> +			    dev_priv->fbc.crtc == intel_crtc &&
> +			    plane_state->rotation != BIT(DRM_ROTATE_0))
> +				intel_crtc->atomic.disable_fbc = true;
> +
> +			/*
> +			 * BDW signals flip done immediately if the plane
> +			 * is disabled, even if the plane enable is already
> +			 * armed to occur at the next vblank :(
> +			 */
> +			if (turn_on && IS_BROADWELL(dev))
> +				intel_crtc->atomic.wait_vblank = true;
> +
> +			intel_crtc->atomic.update_fbc = true;
> +			break;
> +		case DRM_PLANE_TYPE_CURSOR:
> +			if (visible)
> +				intel_crtc->atomic.fb_bits |=
> +				    INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe);
> +			break;
> +		case DRM_PLANE_TYPE_OVERLAY:
> +			if (visible)
> +				intel_crtc->atomic.fb_bits |=
> +				    INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
> +
> +			if (turn_off) {
> +				intel_crtc->atomic.wait_vblank = true;
> +				intel_crtc->atomic.update_sprite_watermarks |=
> +					1 << i;
> +			}
> +			break;
> +		}

I'm completely lost as to why we need to move all the plane->atomic_check
code into a loop in the crtc_check function?

> +	}
> +	return 0;
>  }
>  
>  static void intel_begin_crtc_commit(struct drm_crtc *crtc)
> @@ -13087,10 +13216,13 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
>  	intel_runtime_pm_get(dev_priv);
>  
>  	/* Perform vblank evasion around commit operation */
> -	if (intel_crtc->active)
> +	if (intel_crtc->active && !needs_modeset(crtc->state) &&
> +	    !dev_priv->power_domains.init_power_on)
>  		intel_crtc->atomic.evade =
>  			intel_pipe_update_start(intel_crtc,
>  						&intel_crtc->atomic.start_vbl_count);
> +	else
> +		intel_crtc->atomic.evade = false;
>  }
>  
>  static void intel_finish_crtc_commit(struct drm_crtc *crtc)
> @@ -13099,6 +13231,7 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_plane *p;
> +	unsigned plane_mask;
>  
>  	if (intel_crtc->atomic.evade)
>  		intel_pipe_update_end(intel_crtc,
> @@ -13120,12 +13253,13 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
>  	if (intel_crtc->atomic.post_enable_primary)
>  		intel_post_enable_primary(crtc);
>  
> -	drm_for_each_legacy_plane(p, &dev->mode_config.plane_list)
> -		if (intel_crtc->atomic.update_sprite_watermarks & drm_plane_index(p))
> -			intel_update_sprite_watermarks(p, crtc, 0, 0, 0,
> -						       false, false);
> +	plane_mask = intel_crtc->atomic.update_sprite_watermarks;
> +	drm_for_each_plane_mask(p, dev, plane_mask)
> +		intel_update_sprite_watermarks(p, crtc, 0, 0, 0, false, false);
>  
>  	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
> +	crtc->state->mode_changed = false;
> +	crtc->state->active_changed = false;
>  }
>  
>  /**
> @@ -13238,13 +13372,9 @@ intel_check_cursor_plane(struct drm_plane *plane,
>  	struct drm_rect *src = &state->src;
>  	const struct drm_rect *clip = &state->clip;
>  	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
> -	struct intel_crtc *intel_crtc;
>  	unsigned stride;
>  	int ret;
>  
> -	crtc = crtc ? crtc : plane->crtc;
> -	intel_crtc = to_intel_crtc(crtc);
> -
>  	ret = drm_plane_helper_check_update(plane, crtc, fb,
>  					    src, dest, clip,
>  					    DRM_PLANE_HELPER_NO_SCALING,
> @@ -13256,7 +13386,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
>  
>  	/* if we want to turn off the cursor ignore width and height */
>  	if (!obj)
> -		goto finish;
> +		return 0;
>  
>  	/* Check for which cursor types we support */
>  	if (!cursor_size_ok(dev, state->base.crtc_w, state->base.crtc_h)) {
> @@ -13273,19 +13403,10 @@ intel_check_cursor_plane(struct drm_plane *plane,
>  
>  	if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
>  		DRM_DEBUG_KMS("cursor cannot be tiled\n");
> -		ret = -EINVAL;
> -	}
> -
> -finish:
> -	if (intel_crtc->active) {
> -		if (plane->state->crtc_w != state->base.crtc_w)
> -			intel_crtc->atomic.update_wm = true;
> -
> -		intel_crtc->atomic.fb_bits |=
> -			INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe);
> +		return -EINVAL;
>  	}
>  
> -	return ret;
> +	return 0;
>  }
>  
>  static void
> @@ -13306,20 +13427,26 @@ intel_disable_cursor_plane(struct drm_plane *plane,
>  
>  static void
>  intel_commit_cursor_plane(struct drm_plane *plane,
> -			  struct intel_plane_state *state)
> +			  struct intel_plane_state *new_state)
>  {
> -	struct drm_crtc *crtc = state->base.crtc;
> +	struct drm_crtc *crtc = new_state->base.crtc;
>  	struct drm_device *dev = plane->dev;
>  	struct intel_crtc *intel_crtc;
> -	struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
> +	struct drm_i915_gem_object *obj = intel_fb_obj(new_state->base.fb);
>  	uint32_t addr;
>  
>  	crtc = crtc ? crtc : plane->crtc;
>  	intel_crtc = to_intel_crtc(crtc);
>  
> -	plane->fb = state->base.fb;
> -	crtc->cursor_x = state->base.crtc_x;
> -	crtc->cursor_y = state->base.crtc_y;
> +	plane->fb = new_state->base.fb;
> +	crtc->cursor_x = new_state->base.crtc_x;
> +	crtc->cursor_y = new_state->base.crtc_y;
> +
> +	if (!new_state->visible ||
> +	    WARN_ON(new_state->visible && !crtc->state->active)) {

As an aside: We must move over to compute ->visible irrespective of
->active. I haven't check whether you fix that later on already, but this
is important to be able to check wm constraints correctly. The
crtc_state->active handling should imo be done in the common code by
simply not calling any of the plane or crtc functions hw update if the
crtc is off.

Of course that means we need to add all planes both for ->mode_changed and
for ->active_changed, but needs_modeset(crtc_state) takes care of that
already.

Aside: The idea behind the split between drm_atomic_helper_check_planes
and drm_atomic_helper_check_modeset is that the former handles planes-only
updates while the latter handles modeset. We can't fully use
check_modesets because we don't use crtc helpers, but I think reusing the
same idea still has merit:

- We create an intel_check_modeset which calls the helper's check_modeset
  plus afterwards all the modeset checks (dpll, cloning checks, adding
  plane states and global resources) that we do in crtc_compute_config and
  friends right now. That one would also add plane states as needed (but
  not call plane->atomic_check). All of this would be skipped if
  needs_modeset isn't true.

- After that we'd call the helper's plane_check functions which does
  exclusively plane-update related checks. crtc/plane->atomic_check
  wouldn't contain any modeset related checks (like the encoder cloning or
  plane adding you're doing right now).

> +		intel_disable_cursor_plane(plane, crtc, false);
> +		return;
> +	}
>  
>  	if (intel_crtc->cursor_bo == obj)
>  		goto update;
> @@ -13333,10 +13460,9 @@ intel_commit_cursor_plane(struct drm_plane *plane,
>  
>  	intel_crtc->cursor_addr = addr;
>  	intel_crtc->cursor_bo = obj;
> -update:
>  
> -	if (intel_crtc->active)
> -		intel_crtc_update_cursor(crtc, state->visible);
> +update:
> +	intel_crtc_update_cursor(crtc, new_state->visible);
>  }
>  
>  static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
> @@ -14695,7 +14821,14 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  		crtc->base.enabled = crtc->active;
>  
>  		plane_state = to_intel_plane_state(primary->state);
> -		plane_state->visible = primary_get_hw_state(crtc);
> +		plane_state->hw_enabled = plane_state->visible =
> +			primary_get_hw_state(crtc);
> +		if (plane_state->visible)
> +			crtc->base.state->plane_mask |=
> +				1 << drm_plane_index(primary);
> +		else
> +			crtc->base.state->plane_mask &=
> +				~(1 << drm_plane_index(primary));
>  
>  		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
>  			      crtc->base.base.id,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1e892098eea2..9ef89c91aa5c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -235,7 +235,7 @@ struct intel_plane_state {
>  	struct drm_rect src;
>  	struct drm_rect dst;
>  	struct drm_rect clip;
> -	bool visible;
> +	bool visible, hw_enabled;
>  
>  	/*
>  	 * scaler_id
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 497e7953ad4d..28291ab0993f 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -759,7 +759,6 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  {
>  	struct drm_device *dev = plane->dev;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(state->base.crtc);
> -	struct intel_crtc_state *crtc_state;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct drm_framebuffer *fb = state->base.fb;
>  	int crtc_x, crtc_y;
> @@ -771,16 +770,9 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	int hscale, vscale;
>  	int max_scale, min_scale;
>  	int pixel_size;
> -	int ret;
> -
> -	intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc);
> -	crtc_state = state->base.state ?
> -		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>  
> -	if (!fb) {
> -		state->visible = false;
> -		goto finish;
> -	}
> +	if (!fb)
> +		return 0;
>  
>  	/* Don't modify another pipe's plane */
>  	if (intel_plane->pipe != intel_crtc->pipe) {
> @@ -803,6 +795,9 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
>  
>  	if (INTEL_INFO(dev)->gen >= 9) {
> +		struct intel_crtc_state *crtc_state =
> +			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
> +
>  		min_scale = 1;
>  		max_scale = skl_max_scale(intel_crtc, crtc_state);
>  	}
> @@ -816,7 +811,7 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
>  	BUG_ON(vscale < 0);
>  
> -	state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
> +	state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
>  
>  	crtc_x = dst->x1;
>  	crtc_y = dst->y1;
> @@ -921,36 +916,6 @@ intel_check_sprite_plane(struct drm_plane *plane,
>  	dst->y1 = crtc_y;
>  	dst->y2 = crtc_y + crtc_h;
>  
> -finish:
> -	/*
> -	 * If the sprite is completely covering the primary plane,
> -	 * we can disable the primary and save power.
> -	 */
> -	if (intel_crtc->active) {
> -		intel_crtc->atomic.fb_bits |=
> -			INTEL_FRONTBUFFER_SPRITE(intel_crtc->pipe);
> -
> -		if (intel_wm_need_update(plane, &state->base))
> -			intel_crtc->atomic.update_wm = true;
> -
> -		if (!state->visible) {
> -			/*
> -			 * Avoid underruns when disabling the sprite.
> -			 * FIXME remove once watermark updates are done properly.
> -			 */
> -			intel_crtc->atomic.wait_vblank = true;
> -			intel_crtc->atomic.update_sprite_watermarks |=
> -				(1 << drm_plane_index(plane));
> -		}
> -	}
> -
> -	if (INTEL_INFO(dev)->gen >= 9) {
> -		ret = skl_update_scaler_users(intel_crtc, crtc_state, intel_plane,
> -			state, 0);
> -		if (ret)
> -			return ret;
> -	}
> -
>  	return 0;
>  }
>  
> @@ -959,7 +924,6 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>  			  struct intel_plane_state *state)
>  {
>  	struct drm_crtc *crtc = state->base.crtc;
> -	struct intel_crtc *intel_crtc;
>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	struct drm_framebuffer *fb = state->base.fb;
>  	int crtc_x, crtc_y;
> @@ -967,26 +931,22 @@ intel_commit_sprite_plane(struct drm_plane *plane,
>  	uint32_t src_x, src_y, src_w, src_h;
>  
>  	crtc = crtc ? crtc : plane->crtc;
> -	intel_crtc = to_intel_crtc(crtc);
> -
>  	plane->fb = fb;
>  
> -	if (intel_crtc->active) {
> -		if (state->visible) {
> -			crtc_x = state->dst.x1;
> -			crtc_y = state->dst.y1;
> -			crtc_w = drm_rect_width(&state->dst);
> -			crtc_h = drm_rect_height(&state->dst);
> -			src_x = state->src.x1 >> 16;
> -			src_y = state->src.y1 >> 16;
> -			src_w = drm_rect_width(&state->src) >> 16;
> -			src_h = drm_rect_height(&state->src) >> 16;
> -			intel_plane->update_plane(plane, crtc, fb,
> -						  crtc_x, crtc_y, crtc_w, crtc_h,
> -						  src_x, src_y, src_w, src_h);
> -		} else {
> -			intel_plane->disable_plane(plane, crtc, false);
> -		}
> +	if (state->visible && crtc->state->active) {
> +		crtc_x = state->dst.x1;
> +		crtc_y = state->dst.y1;
> +		crtc_w = drm_rect_width(&state->dst);
> +		crtc_h = drm_rect_height(&state->dst);
> +		src_x = state->src.x1 >> 16;
> +		src_y = state->src.y1 >> 16;
> +		src_w = drm_rect_width(&state->src) >> 16;
> +		src_h = drm_rect_height(&state->src) >> 16;
> +		intel_plane->update_plane(plane, crtc, fb,
> +					  crtc_x, crtc_y, crtc_w, crtc_h,
> +					  src_x, src_y, src_w, src_h);
> +	} else {
> +		intel_plane->disable_plane(plane, crtc, false);
>  	}
>  }

Ok I think overall this patch is too big and needs to be split a bit. The
following should be doable as prep-patches:
- set_base_atomic (if we dare to touch it at all)
- shuffling the crtc modeset check logic around to add plane states as
  needed, making sure we only run that if needs_modeset indicates so.
- Pushing the checks for intel_crtc->active or crtc->state->active out of
  the low-level plane code up into higher level atomic plane code (and the
  few legacy entry points for plane updates that we still have maybe, but
  those should be covered I think with the universal plane + transitional
  helpers).

Then we can put in the meat of this patch, i.e. replacing the helpers with
atomic updates in the modeset code.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 11/42] drm/i915: Update less state during modeset.
  2015-05-11 14:24 ` [PATCH 11/42] drm/i915: Update less state during modeset Maarten Lankhorst
@ 2015-05-12  8:22   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  8:22 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:47PM +0200, Maarten Lankhorst wrote:
> No need to repeatedly call update_watermarks, or update_fbc.
> For update_watermarks once should be enough after disabling crtc's
> and swapping the state.
> 
> Down to a single call to update_watermarks in .crtc_enable
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

In theory we shouldn't even need that one, but only a two-stage wm update
in our ->atomic_begin/->atomic_flush crtc callbacks. But I wonder whether
reducing the amount of wm updates as long as we don't yet have the
two-stage thing will increase our risk for underruns. I guess for now we'd
at least need the call in crtc_enable to reduce that risk.

Imo the fbc changes would look great as it's own patch ;-)
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_display.c | 79 +++++++++++++-----------------------
>  1 file changed, 28 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9610f76a2489..a90ebc8eff6f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4719,10 +4719,6 @@ intel_post_enable_primary(struct drm_crtc *crtc)
>  	 */
>  	hsw_enable_ips(intel_crtc);
>  
> -	mutex_lock(&dev->struct_mutex);
> -	intel_fbc_update(dev);
> -	mutex_unlock(&dev->struct_mutex);
> -
>  	/*
>  	 * Gen2 reports pipe underruns whenever all planes are disabled.
>  	 * So don't enable underrun reporting before at least some planes
> @@ -4777,11 +4773,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
>  	if (HAS_GMCH_DISPLAY(dev))
>  		intel_set_memory_cxsr(dev_priv, false);
>  
> -	mutex_lock(&dev->struct_mutex);
> -	if (dev_priv->fbc.crtc == intel_crtc)
> -		intel_fbc_disable(dev);
> -	mutex_unlock(&dev->struct_mutex);
> -
>  	/*
>  	 * FIXME IPS should be fine as long as one plane is
>  	 * enabled, but in practice it seems to have problems
> @@ -5009,9 +5000,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
>  	int pipe = intel_crtc->pipe;
>  	u32 reg, temp;
>  
> -	if (!intel_crtc->active)
> -		return;
> -
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		encoder->disable(encoder);
>  
> @@ -5049,18 +5037,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
>  			I915_WRITE(PCH_DPLL_SEL, temp);
>  		}
>  
> -		/* disable PCH DPLL */
> -		intel_disable_shared_dpll(intel_crtc);
> -
>  		ironlake_fdi_pll_disable(intel_crtc);
>  	}
> -
> -	intel_crtc->active = false;
> -	intel_update_watermarks(crtc);
> -
> -	mutex_lock(&dev->struct_mutex);
> -	intel_fbc_update(dev);
> -	mutex_unlock(&dev->struct_mutex);
>  }
>  
>  static void haswell_crtc_disable(struct drm_crtc *crtc)
> @@ -5071,9 +5049,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>  	struct intel_encoder *encoder;
>  	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>  
> -	if (!intel_crtc->active)
> -		return;
> -
>  	for_each_encoder_on_crtc(dev, crtc, encoder) {
>  		intel_opregion_notify_encoder(encoder, false);
>  		encoder->disable(encoder);
> @@ -5109,16 +5084,6 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
>  			encoder->post_disable(encoder);
> -
> -	intel_crtc->active = false;
> -	intel_update_watermarks(crtc);
> -
> -	mutex_lock(&dev->struct_mutex);
> -	intel_fbc_update(dev);
> -	mutex_unlock(&dev->struct_mutex);
> -
> -	if (intel_crtc_to_shared_dpll(intel_crtc))
> -		intel_disable_shared_dpll(intel_crtc);
>  }
>  
>  static void i9xx_pfit_enable(struct intel_crtc *crtc)
> @@ -5943,9 +5908,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
>  
> -	if (!intel_crtc->active)
> -		return;
> -
>  	/*
>  	 * On gen2 planes are double buffered but the pipe isn't, so we must
>  	 * wait for planes to fully turn off before disabling the pipe.
> @@ -5979,13 +5941,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  
>  	if (!IS_GEN2(dev))
>  		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
> -
> -	intel_crtc->active = false;
> -	intel_update_watermarks(crtc);
> -
> -	mutex_lock(&dev->struct_mutex);
> -	intel_fbc_update(dev);
> -	mutex_unlock(&dev->struct_mutex);
>  }
>  
>  /* Master function to enable/disable CRTC and corresponding power wells */
> @@ -12347,11 +12302,21 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	__intel_set_mode_update_planes(dev, state);
>  
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
>  		if (!needs_modeset(crtc_state))
>  			continue;
>  
> +		if (!crtc->state->active)
> +			continue;
> +
>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>  		dev_priv->display.crtc_disable(crtc);
> +
> +		intel_crtc->active = false;
> +
> +		if (intel_crtc_to_shared_dpll(intel_crtc))
> +			intel_disable_shared_dpll(intel_crtc);
>  	}
>  
>  	/* Only after disabling all output pipelines that will be changed can we
> @@ -12365,8 +12330,11 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  
>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!crtc->state->active)
> +		if (!crtc->state->active) {
> +			if (needs_modeset(crtc->state))
> +				intel_update_watermarks(crtc);
>  			continue;
> +		}
>  
>  		update_scanline_offset(to_intel_crtc(crtc));
>  
> @@ -13030,6 +12998,7 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
>  
>  	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
>  	intel_crtc->atomic.update_wm = mode_changed;
> +	intel_crtc->atomic.disable_fbc = mode_changed;
>  
>  	idx = crtc->base.id;
>  	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
> @@ -13165,6 +13134,9 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
>  			break;
>  		}
>  	}
> +
> +	if (mode_changed)
> +		intel_crtc->atomic.update_wm = false;
>  	return 0;
>  }
>  
> @@ -13204,8 +13176,13 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
>  	if (intel_crtc->atomic.wait_for_flips)
>  		intel_crtc_wait_for_pending_flips(crtc);
>  
> -	if (intel_crtc->atomic.disable_fbc)
> -		intel_fbc_disable(dev);
> +	if (intel_crtc->atomic.disable_fbc &&
> +	    dev_priv->fbc.crtc == intel_crtc) {
> +		mutex_lock(&dev->struct_mutex);
> +		if (dev_priv->fbc.crtc == intel_crtc)
> +			intel_fbc_disable(dev);
> +		mutex_unlock(&dev->struct_mutex);
> +	}
>  
>  	if (intel_crtc->atomic.pre_disable_primary)
>  		intel_pre_disable_primary(crtc);
> @@ -13244,15 +13221,15 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc)
>  
>  	intel_frontbuffer_flip(dev, intel_crtc->atomic.fb_bits);
>  
> +	if (intel_crtc->atomic.post_enable_primary)
> +		intel_post_enable_primary(crtc);
> +
>  	if (intel_crtc->atomic.update_fbc) {
>  		mutex_lock(&dev->struct_mutex);
>  		intel_fbc_update(dev);
>  		mutex_unlock(&dev->struct_mutex);
>  	}
>  
> -	if (intel_crtc->atomic.post_enable_primary)
> -		intel_post_enable_primary(crtc);
> -
>  	plane_mask = intel_crtc->atomic.update_sprite_watermarks;
>  	drm_for_each_plane_mask(p, dev, plane_mask)
>  		intel_update_sprite_watermarks(p, crtc, 0, 0, 0, false, false);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 12/42] drm/i915: move swap_state to the right place
  2015-05-11 14:24 ` [PATCH 12/42] drm/i915: move swap_state to the right place Maarten Lankhorst
@ 2015-05-12  8:25   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  8:25 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:48PM +0200, Maarten Lankhorst wrote:
> Done as a separate commit to allow better bisecting.

Assuming my comments on patch 10 pan out this would boil down to just
moving the swap_state call up a bit, plus adjusting the loop over the
old_state in the disable loops like this patch does already. Given that
things are still a bit unclear I didn't carefully review whether you've
missed any of those, but makes sense otherwise.
-Daniel

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 50 +++++-------------------------------
>  1 file changed, 7 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a90ebc8eff6f..253d9cd4154a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11437,28 +11437,9 @@ intel_modeset_update_state(struct drm_atomic_state *state)
>  	struct drm_crtc *crtc;
>  	struct drm_crtc_state *crtc_state;
>  	struct drm_connector *connector;
> -	struct drm_connector_state *connector_state;
> -	int i;
>  
>  	intel_shared_dpll_commit(dev_priv);
>  
> -	/*
> -	 * swap crtc and connector state, plane state is already swapped in
> -	 * __intel_set_mode_update_planes. Once .crtc_disable is fixed
> -	 * all state should be swapped before disabling crtc's.
> -	 */
> -	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> -		crtc->state->state = state;
> -		swap(state->crtc_states[i], crtc->state);
> -		crtc->state->state = NULL;
> -	}
> -
> -	for_each_connector_in_state(state, connector, connector_state, i) {
> -		connector->state->state = state;
> -		swap(state->connector_states[i], connector->state);
> -		connector->state->state = NULL;
> -	}
> -
>  	for_each_intel_encoder(dev, intel_encoder) {
>  		if (!intel_encoder->base.crtc)
>  			continue;
> @@ -12183,21 +12164,6 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
>  	struct drm_plane *plane;
>  	struct drm_crtc *crtc;
>  
> -	/*
> -	 * For now only swap plane state, will be replaced with a
> -	 * call to drm_atomic_helper_swap_state
> -	 */
> -	for_each_plane_in_state(state, plane, old_plane_state, i) {
> -		struct drm_plane *plane = state->planes[i];
> -
> -		if (!plane)
> -			continue;
> -
> -		plane->state->state = state;
> -		swap(state->plane_states[i], plane->state);
> -		plane->state->state = NULL;
> -	}
> -
>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>  		const struct drm_crtc_helper_funcs *funcs;
>  
> @@ -12206,10 +12172,6 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
>  		if (!funcs || !funcs->atomic_begin)
>  			continue;
>  
> -		/* XXX: Hack because crtc state is not swapped */
> -		crtc->state->mode_changed = crtc_state->mode_changed;
> -		crtc->state->active_changed = crtc_state->active_changed;
> -
>  		DRM_DEBUG_ATOMIC("Calling atomic_begin on crtc %i\n", i);
>  		funcs->atomic_begin(crtc);
>  	}
> @@ -12287,7 +12249,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_atomic_state *state = pipe_config->base.state;
>  	struct drm_crtc *crtc;
> -	struct drm_crtc_state *crtc_state;
> +	struct drm_crtc_state *old_crtc_state;
>  	int ret;
>  	int i;
>  
> @@ -12299,15 +12261,17 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	if (ret)
>  		return ret;
>  
> +	drm_atomic_helper_swap_state(dev, state);
> +
>  	__intel_set_mode_update_planes(dev, state);
>  
> -	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
> -		if (!needs_modeset(crtc_state))
> +		if (!needs_modeset(crtc->state))
>  			continue;
>  
> -		if (!crtc->state->active)
> +		if (!old_crtc_state->active)
>  			continue;
>  
>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
> @@ -12329,7 +12293,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>  	modeset_update_crtc_power_domains(state);
>  
>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
> -	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
>  		if (!crtc->state->active) {
>  			if (needs_modeset(crtc->state))
>  				intel_update_watermarks(crtc);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c
  2015-05-11 14:24 ` [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c Maarten Lankhorst
@ 2015-05-12  8:51   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  8:51 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:52PM +0200, Maarten Lankhorst wrote:
> Another abuser gone.

Maybe change subject in these to also include crtc->active, just for
correctness. lgtm otherwise.
-Daniel

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 42 ++++++++++++++++++++++++-------------
>  1 file changed, 27 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index acd4d2c7613a..5439ff9f7e6b 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2755,13 +2755,16 @@ static int i915_display_info(struct seq_file *m, void *unused)
>  	seq_printf(m, "---------\n");
>  	for_each_intel_crtc(dev, crtc) {
>  		bool active;
> +		struct intel_crtc_state *pipe_config;
>  		int x, y;
>  
> +		pipe_config = to_intel_crtc_state(crtc->base.state);
> +
>  		seq_printf(m, "CRTC %d: pipe: %c, active=%s (size=%dx%d)\n",
>  			   crtc->base.base.id, pipe_name(crtc->pipe),
> -			   yesno(crtc->active), crtc->config->pipe_src_w,
> -			   crtc->config->pipe_src_h);
> -		if (crtc->active) {
> +			   yesno(pipe_config->base.active),
> +			   pipe_config->pipe_src_w, pipe_config->pipe_src_h);
> +		if (pipe_config->base.active) {
>  			intel_crtc_info(m, crtc);
>  
>  			active = cursor_position(dev, crtc->pipe, &x, &y);
> @@ -3002,7 +3005,7 @@ static void drrs_status_per_crtc(struct seq_file *m,
>  
>  	seq_puts(m, "\n\n");
>  
> -	if (intel_crtc->config->has_drrs) {
> +	if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
>  		struct intel_panel *panel;
>  
>  		mutex_lock(&drrs->mutex);
> @@ -3054,7 +3057,7 @@ static int i915_drrs_status(struct seq_file *m, void *unused)
>  	for_each_intel_crtc(dev, intel_crtc) {
>  		drm_modeset_lock(&intel_crtc->base.mutex, NULL);
>  
> -		if (intel_crtc->active) {
> +		if (intel_crtc->base.state->active) {
>  			active_crtc_cnt++;
>  			seq_printf(m, "\nCRTC %d:  ", active_crtc_cnt);
>  
> @@ -3596,22 +3599,27 @@ static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc =
>  		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
> +	struct intel_crtc_state *pipe_config;
>  
>  	drm_modeset_lock_all(dev);
> +	pipe_config = to_intel_crtc_state(crtc->base.state);
> +
>  	/*
>  	 * If we use the eDP transcoder we need to make sure that we don't
>  	 * bypass the pfit, since otherwise the pipe CRC source won't work. Only
>  	 * relevant on hsw with pipe A when using the always-on power well
>  	 * routing.
>  	 */
> -	if (crtc->config->cpu_transcoder == TRANSCODER_EDP &&
> -	    !crtc->config->pch_pfit.enabled) {
> -		bool active = crtc->active;
> +	if (pipe_config->cpu_transcoder == TRANSCODER_EDP &&
> +	    !pipe_config->pch_pfit.enabled) {
> +		bool active = pipe_config->base.active;
>  
> -		if (active)
> +		if (active) {
>  			intel_crtc_control(&crtc->base, false);
> +			pipe_config = to_intel_crtc_state(crtc->base.state);
> +		}
>  
> -		crtc->config->pch_pfit.force_thru = true;
> +		pipe_config->pch_pfit.force_thru = true;
>  
>  		intel_display_power_get(dev_priv,
>  					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
> @@ -3627,6 +3635,7 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc =
>  		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
> +	struct intel_crtc_state *pipe_config;
>  
>  	drm_modeset_lock_all(dev);
>  	/*
> @@ -3635,13 +3644,16 @@ static void hsw_undo_trans_edp_pipe_A_crc_wa(struct drm_device *dev)
>  	 * relevant on hsw with pipe A when using the always-on power well
>  	 * routing.
>  	 */
> -	if (crtc->config->pch_pfit.force_thru) {
> -		bool active = crtc->active;
> +	pipe_config = to_intel_crtc_state(crtc->base.state);
> +	if (pipe_config->pch_pfit.force_thru) {
> +		bool active = pipe_config->base.active;
>  
> -		if (active)
> +		if (active) {
>  			intel_crtc_control(&crtc->base, false);
> +			pipe_config = to_intel_crtc_state(crtc->base.state);
> +		}
>  
> -		crtc->config->pch_pfit.force_thru = false;
> +		pipe_config->pch_pfit.force_thru = false;
>  
>  		intel_display_power_put(dev_priv,
>  					POWER_DOMAIN_PIPE_PANEL_FITTER(PIPE_A));
> @@ -3763,7 +3775,7 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
>  				 pipe_name(pipe));
>  
>  		drm_modeset_lock(&crtc->base.mutex, NULL);
> -		if (crtc->active)
> +		if (crtc->base.state->active)
>  			intel_wait_for_vblank(dev, pipe);
>  		drm_modeset_unlock(&crtc->base.mutex);
>  
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c
  2015-05-11 14:24 ` [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c Maarten Lankhorst
@ 2015-05-12  8:54   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  8:54 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:53PM +0200, Maarten Lankhorst wrote:

A comment here stating that the wm code doesn't check/precompute anything
yet, hence we always need to look at the current config would be good.

/me on a crusade against terse commit messages

Cheers, Daniel

> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 96 ++++++++++++++++++++---------------------
>  1 file changed, 46 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index a70b2d1fc844..869b587f463d 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -678,7 +678,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
>  		int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
>  		int clock;
>  
> -		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +		adjusted_mode = &crtc->state->adjusted_mode;
>  		clock = adjusted_mode->crtc_clock;
>  
>  		/* Display SR */
> @@ -747,10 +747,10 @@ static bool g4x_compute_wm0(struct drm_device *dev,
>  		return false;
>  	}
>  
> -	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +	adjusted_mode = &crtc->state->adjusted_mode;
>  	clock = adjusted_mode->crtc_clock;
>  	htotal = adjusted_mode->crtc_htotal;
> -	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
> +	hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
>  	pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
>  
>  	/* Use the small buffer method to calculate plane watermark */
> @@ -834,10 +834,10 @@ static bool g4x_compute_srwm(struct drm_device *dev,
>  	}
>  
>  	crtc = intel_get_crtc_for_plane(dev, plane);
> -	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +	adjusted_mode = &crtc->state->adjusted_mode;
>  	clock = adjusted_mode->crtc_clock;
>  	htotal = adjusted_mode->crtc_htotal;
> -	hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
> +	hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
>  	pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
>  
>  	line_time_us = max(htotal * 1000 / clock, 1);
> @@ -934,16 +934,11 @@ static uint8_t vlv_compute_drain_latency(struct drm_crtc *crtc,
>  					 struct drm_plane *plane)
>  {
>  	struct drm_device *dev = crtc->dev;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	int entries, prec_mult, drain_latency, pixel_size;
> -	int clock = intel_crtc->config->base.adjusted_mode.crtc_clock;
> +	int clock = crtc->state->adjusted_mode.crtc_clock;
>  	const int high_precision = IS_CHERRYVIEW(dev) ? 16 : 64;
>  
> -	/*
> -	 * FIXME the plane might have an fb
> -	 * but be invisible (eg. due to clipping)
> -	 */
> -	if (!intel_crtc->active || !plane->state->fb)
> +	if (!crtc->state->active || !to_intel_plane_state(plane->state)->visible)
>  		return 0;
>  
>  	if (WARN(clock == 0, "Pixel clock is zero!\n"))
> @@ -981,11 +976,11 @@ static int vlv_compute_wm(struct intel_crtc *crtc,
>  	 * FIXME the plane might have an fb
>  	 * but be invisible (eg. due to clipping)
>  	 */
> -	if (!crtc->active || !plane->base.state->fb)
> +	if (!crtc->base.state->active || !plane->base.state->fb)
>  		return 0;
>  
>  	pixel_size = drm_format_plane_cpp(plane->base.state->fb->pixel_format, 0);
> -	clock = crtc->config->base.adjusted_mode.crtc_clock;
> +	clock = crtc->base.state->adjusted_mode.crtc_clock;
>  
>  	entries = DIV_ROUND_UP(clock, 1000) * pixel_size;
>  
> @@ -1217,10 +1212,10 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
>  		/* self-refresh has much higher latency */
>  		static const int sr_latency_ns = 12000;
>  		const struct drm_display_mode *adjusted_mode =
> -			&to_intel_crtc(crtc)->config->base.adjusted_mode;
> +			&crtc->state->adjusted_mode;
>  		int clock = adjusted_mode->crtc_clock;
>  		int htotal = adjusted_mode->crtc_htotal;
> -		int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
> +		int hdisplay = to_intel_crtc_state(crtc->state)->pipe_src_w;
>  		int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
>  		unsigned long line_time_us;
>  		int entries;
> @@ -1304,7 +1299,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
>  		if (IS_GEN2(dev))
>  			cpp = 4;
>  
> -		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +		adjusted_mode = &crtc->state->adjusted_mode;
>  		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
>  					       wm_info, fifo_size, cpp,
>  					       pessimal_latency_ns);
> @@ -1326,7 +1321,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
>  		if (IS_GEN2(dev))
>  			cpp = 4;
>  
> -		adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +		adjusted_mode = &crtc->state->adjusted_mode;
>  		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
>  					       wm_info, fifo_size, cpp,
>  					       pessimal_latency_ns);
> @@ -1365,10 +1360,10 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
>  		/* self-refresh has much higher latency */
>  		static const int sr_latency_ns = 6000;
>  		const struct drm_display_mode *adjusted_mode =
> -			&to_intel_crtc(enabled)->config->base.adjusted_mode;
> +			&enabled->state->adjusted_mode;
>  		int clock = adjusted_mode->crtc_clock;
>  		int htotal = adjusted_mode->crtc_htotal;
> -		int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w;
> +		int hdisplay = to_intel_crtc_state(enabled->state)->pipe_src_w;
>  		int pixel_size = enabled->primary->state->fb->bits_per_pixel / 8;
>  		unsigned long line_time_us;
>  		int entries;
> @@ -1421,7 +1416,7 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
>  	if (crtc == NULL)
>  		return;
>  
> -	adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
> +	adjusted_mode = &crtc->state->adjusted_mode;
>  	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
>  				       &i845_wm_info,
>  				       dev_priv->display.get_fifo_size(dev, 0),
> @@ -1437,20 +1432,20 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
>  static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
>  				    struct drm_crtc *crtc)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	uint32_t pixel_rate;
> -
> -	pixel_rate = intel_crtc->config->base.adjusted_mode.crtc_clock;
> +	uint32_t pixel_rate =
> +		crtc->state->adjusted_mode.crtc_clock;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  
>  	/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
>  	 * adjust the pixel_rate here. */
>  
> -	if (intel_crtc->config->pch_pfit.enabled) {
> +	if (pipe_config->pch_pfit.enabled) {
>  		uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
> -		uint32_t pfit_size = intel_crtc->config->pch_pfit.size;
> +		uint32_t pfit_size = pipe_config->pch_pfit.size;
>  
> -		pipe_w = intel_crtc->config->pipe_src_w;
> -		pipe_h = intel_crtc->config->pipe_src_h;
> +		pipe_w = pipe_config->pipe_src_w;
> +		pipe_h = pipe_config->pipe_src_h;
>  		pfit_w = (pfit_size >> 16) & 0xFFFF;
>  		pfit_h = pfit_size & 0xFFFF;
>  		if (pipe_w < pfit_w)
> @@ -1802,11 +1797,10 @@ static uint32_t
>  hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
> +	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
>  	u32 linetime, ips_linetime;
>  
> -	if (!intel_crtc->active)
> +	if (!crtc->state->active)
>  		return 0;
>  
>  	/* The WM are computed with base on how long it takes to fill a single
> @@ -2061,11 +2055,11 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct drm_plane *plane;
>  
> -	if (!intel_crtc->active)
> +	if (!crtc->state->active)
>  		return;
>  
>  	p->active = true;
> -	p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> +	p->pipe_htotal = crtc->state->adjusted_mode.crtc_htotal;
>  	p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
>  
>  	if (crtc->primary->state->fb) {
> @@ -2084,8 +2078,8 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
>  		p->cur.enabled = false;
>  		p->cur.bytes_per_pixel = 0;
>  	}
> -	p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
> -	p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
> +	p->pri.horiz_pixels = to_intel_crtc_state(crtc->state)->pipe_src_w;
> +	p->cur.horiz_pixels = crtc->cursor->state->crtc_w;
>  
>  	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
>  		struct intel_plane *intel_plane = to_intel_plane(plane);
> @@ -2589,7 +2583,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
>  
>  	nth_active_pipe = 0;
>  	for_each_crtc(dev, crtc) {
> -		if (!to_intel_crtc(crtc)->active)
> +		if (!crtc->state->active)
>  			continue;
>  
>  		if (crtc == for_crtc)
> @@ -2862,7 +2856,7 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
>  	struct drm_plane *plane;
>  
>  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> -		config->num_pipes_active += to_intel_crtc(crtc)->active;
> +		config->num_pipes_active += crtc->state->active;
>  
>  	/* FIXME: I don't think we need those two global parameters on SKL */
>  	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> @@ -2881,12 +2875,14 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
>  	enum pipe pipe = intel_crtc->pipe;
>  	struct drm_plane *plane;
>  	struct drm_framebuffer *fb;
> +	struct intel_crtc_state *pipe_config;
>  	int i = 1; /* Index for sprite planes start */
>  
> -	p->active = intel_crtc->active;
> +	pipe_config = to_intel_crtc_state(crtc->state);
> +	p->active = crtc->state->active;
>  	if (p->active) {
> -		p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
> -		p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
> +		p->pipe_htotal = pipe_config->base.adjusted_mode.crtc_htotal;
> +		p->pixel_rate = skl_pipe_pixel_rate(pipe_config);
>  
>  		fb = crtc->primary->state->fb;
>  		/* For planar: Bpp is for uv plane, y_Bpp is for y plane */
> @@ -2903,8 +2899,8 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
>  			p->plane[0].y_bytes_per_pixel = 0;
>  			p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
>  		}
> -		p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
> -		p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
> +		p->plane[0].horiz_pixels = pipe_config->pipe_src_w;
> +		p->plane[0].vert_pixels = pipe_config->pipe_src_h;
>  		p->plane[0].rotation = crtc->primary->state->rotation;
>  
>  		fb = crtc->cursor->state->fb;
> @@ -3042,7 +3038,7 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>  static uint32_t
>  skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
>  {
> -	if (!to_intel_crtc(crtc)->active)
> +	if (!crtc->state->active)
>  		return 0;
>  
>  	return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
> @@ -3266,7 +3262,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
>  	 * re-allocate the freed space without this pipe fetching from it.
>  	 */
>  	for_each_intel_crtc(dev, crtc) {
> -		if (!crtc->active)
> +		if (!crtc->base.state->active)
>  			continue;
>  
>  		pipe = crtc->pipe;
> @@ -3289,7 +3285,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
>  	 * space is not used anymore.
>  	 */
>  	for_each_intel_crtc(dev, crtc) {
> -		if (!crtc->active)
> +		if (!crtc->base.state->active)
>  			continue;
>  
>  		pipe = crtc->pipe;
> @@ -3312,7 +3308,7 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
>  	 * will just get more DDB space with the correct WM values.
>  	 */
>  	for_each_intel_crtc(dev, crtc) {
> -		if (!crtc->active)
> +		if (!crtc->base.state->active)
>  			continue;
>  
>  		pipe = crtc->pipe;
> @@ -3378,7 +3374,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
>  		if (this_crtc->pipe == intel_crtc->pipe)
>  			continue;
>  
> -		if (!intel_crtc->active)
> +		if (!intel_crtc->base.state->active)
>  			continue;
>  
>  		wm_changed = skl_update_pipe_wm(&intel_crtc->base,
> @@ -3603,7 +3599,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  		hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
>  	hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
>  
> -	if (!intel_crtc->active)
> +	if (!crtc->state->active)
>  		return;
>  
>  	hw->dirty[pipe] = true;
> @@ -3658,7 +3654,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
>  
> -	active->pipe_enabled = intel_crtc->active;
> +	active->pipe_enabled = crtc->state->active;
>  
>  	if (active->pipe_enabled) {
>  		u32 tmp = hw->wm_pipe[pipe];
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c
  2015-05-11 14:24 ` [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c Maarten Lankhorst
@ 2015-05-12  9:03   ` Daniel Vetter
  2015-05-12 13:36     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:56PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c | 10 +++-------
>  drivers/gpu/drm/i915/intel_sprite.c |  4 ++--
>  2 files changed, 5 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 7ed8033aae60..ace6aeeb1359 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -176,7 +176,7 @@ int intel_atomic_commit(struct drm_device *dev,
>  			continue;
>  		}
>  
> -		to_intel_crtc(crtc)->config->scaler_state =
> +		to_intel_crtc_state(crtc->state)->scaler_state =
>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
>  
>  		if (INTEL_INFO(dev)->gen >= 9)
> @@ -241,14 +241,10 @@ intel_connector_atomic_get_property(struct drm_connector *connector,
>  struct drm_crtc_state *
>  intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_crtc_state *crtc_state;
>  
> -	if (WARN_ON(!intel_crtc->config))
> -		crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
> -	else
> -		crtc_state = kmemdup(intel_crtc->config,
> -				     sizeof(*intel_crtc->config), GFP_KERNEL);
> +	crtc_state = kmemdup(crtc->state,
> +			     sizeof(*crtc_state), GFP_KERNEL);

Separate patch for this hunk please.
-Daniel

>  
>  	if (!crtc_state)
>  		return NULL;
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 28291ab0993f..dfb6656ef544 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -81,7 +81,7 @@ static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
>  bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
>  {
>  	struct drm_device *dev = crtc->base.dev;
> -	const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
> +	const struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
>  	enum pipe pipe = crtc->pipe;
>  	long timeout = msecs_to_jiffies_timeout(1);
>  	int scanline, min, max, vblank_start;
> @@ -187,7 +187,7 @@ skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
>  	u32 tile_height, plane_offset, plane_size;
>  	unsigned int rotation;
>  	int x_offset, y_offset;
> -	struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config;
> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->state);
>  	int scaler_id;
>  
>  	plane_ctl = PLANE_CTL_ENABLE |
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c
  2015-05-11 14:24 ` [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c Maarten Lankhorst
@ 2015-05-12  9:06   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:06 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:57PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

General comment: Imo the commit message should have a short explanation
for why it's ok to use the the current or new state respectively in any
given conversion. Can be super-repetive ;-) E.g. here this is about the
legacy overlay code which locks out any other updates unconditionally,
hence the atomic state can't change and we want the current one.

This is somewhat important as soon as we start to queue multiple updates
and commit them asynchronously, there crtc->config and crtc->state can end
up being different ...
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_overlay.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 5fd2d5ac02e2..fa0ff6974dcc 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -857,13 +857,13 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
>  }
>  
>  static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
> -					  struct intel_crtc *crtc)
> +					  struct drm_crtc *crtc)
>  {
> -	if (!crtc->active)
> +	if (!crtc->state->active)
>  		return -EINVAL;
>  
>  	/* can't use the overlay with double wide pipe */
> -	if (crtc->config->double_wide)
> +	if (to_intel_crtc_state(crtc->state)->double_wide)
>  		return -EINVAL;
>  
>  	return 0;
> @@ -1127,7 +1127,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
>  		if (ret != 0)
>  			goto out_unlock;
>  
> -		ret = check_overlay_possible_on_crtc(overlay, crtc);
> +		ret = check_overlay_possible_on_crtc(overlay, &crtc->base);
>  		if (ret != 0)
>  			goto out_unlock;
>  
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it.
  2015-05-11 14:24 ` [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it Maarten Lankhorst
@ 2015-05-12  9:13   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:13 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:58PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Why? Please not quite so terse commit messages ...

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   3 +-
>  drivers/gpu/drm/i915/intel_display.c | 207 ++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_dp.c      |   2 +
>  drivers/gpu/drm/i915/intel_drv.h     |  10 +-
>  drivers/gpu/drm/i915/intel_panel.c   |   3 +-
>  drivers/gpu/drm/i915/intel_tv.c      |   2 +-
>  6 files changed, 120 insertions(+), 107 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a6d3ab94ec15..3ba15df4c93a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -573,7 +573,8 @@ struct drm_i915_display_funcs {
>  	int (*crtc_compute_clock)(struct intel_crtc *crtc,
>  				  struct intel_crtc_state *crtc_state);
>  	void (*crtc_enable)(struct drm_crtc *crtc);
> -	void (*crtc_disable)(struct drm_crtc *crtc);
> +	void (*crtc_disable)(struct drm_crtc *crtc,
> +			     struct intel_crtc_state *old_state);
>  	void (*audio_codec_enable)(struct drm_connector *connector,
>  				   struct intel_encoder *encoder,
>  				   struct drm_display_mode *mode);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9bf31371ed49..311a4b44bebe 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -982,8 +982,6 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
>  
>  bool intel_crtc_active(struct drm_crtc *crtc)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
>  	/* Be paranoid as we can arrive here with only partial
>  	 * state retrieved from the hardware during setup.
>  	 *
> @@ -997,17 +995,8 @@ bool intel_crtc_active(struct drm_crtc *crtc)
>  	 * crtc->state->active once we have proper CRTC states wired up
>  	 * for atomic.
>  	 */
> -	return intel_crtc->active && crtc->primary->state->fb &&
> -		intel_crtc->config->base.adjusted_mode.crtc_clock;
> -}
> -
> -enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
> -					     enum pipe pipe)
> -{
> -	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	return intel_crtc->config->cpu_transcoder;
> +	return crtc->state->active && crtc->primary->state->fb &&
> +		crtc->state->adjusted_mode.crtc_clock;
>  }

Separate commit imo.

>  
>  static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
> @@ -1029,9 +1018,10 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
>  	return line1 == line2;
>  }
>  
> -/*
> +/**
>   * intel_wait_for_pipe_off - wait for pipe to turn off
>   * @crtc: crtc whose pipe to wait for
> + * @old_state: currently applied config
>   *
>   * 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
> @@ -1045,11 +1035,12 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
>   *   ends up stopping at the start of the next frame).
>   *
>   */
> -static void intel_wait_for_pipe_off(struct intel_crtc *crtc)
> +static void intel_wait_for_pipe_off(struct intel_crtc *crtc,
> +				    struct intel_crtc_state *old_state)
>  {
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
>  
>  	if (INTEL_INFO(dev)->gen >= 4) {
> @@ -1180,13 +1171,12 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>  }
>  
>  static void assert_fdi_tx(struct drm_i915_private *dev_priv,
> +			  enum transcoder cpu_transcoder,
>  			  enum pipe pipe, bool state)
>  {
>  	int reg;
>  	u32 val;
>  	bool cur_state;
> -	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
> -								      pipe);
>  
>  	if (HAS_DDI(dev_priv->dev)) {
>  		/* DDI does not have a specific FDI_TX register */
> @@ -1202,8 +1192,8 @@ static void assert_fdi_tx(struct drm_i915_private *dev_priv,
>  	     "FDI TX state assertion failure (expected %s, current %s)\n",
>  	     state_string(state), state_string(cur_state));
>  }
> -#define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true)
> -#define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false)
> +#define assert_fdi_tx_enabled(d, c, p) assert_fdi_tx(d, c, p, true)
> +#define assert_fdi_tx_disabled(d, c, p) assert_fdi_tx(d, c, p, false)
>  
>  static void assert_fdi_rx(struct drm_i915_private *dev_priv,
>  			  enum pipe pipe, bool state)
> @@ -1317,13 +1307,12 @@ static void assert_cursor(struct drm_i915_private *dev_priv,
>  #define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
>  
>  void assert_pipe(struct drm_i915_private *dev_priv,
> +		 enum transcoder cpu_transcoder,
>  		 enum pipe pipe, bool state)
>  {
>  	int reg;
>  	u32 val;
>  	bool cur_state;
> -	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
> -								      pipe);
>  
>  	/* if we need the pipe quirk it must be always on */
>  	if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
> @@ -1615,7 +1604,7 @@ static void vlv_enable_pll(struct intel_crtc *crtc,
>  	int reg = DPLL(crtc->pipe);
>  	u32 dpll = pipe_config->dpll_hw_state.dpll;
>  
> -	assert_pipe_disabled(dev_priv, crtc->pipe);
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>  
>  	/* No really, not for ILK+ */
>  	BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
> @@ -1655,7 +1644,7 @@ static void chv_enable_pll(struct intel_crtc *crtc,
>  	enum dpio_channel port = vlv_pipe_to_channel(pipe);
>  	u32 tmp;
>  
> -	assert_pipe_disabled(dev_priv, crtc->pipe);
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>  
>  	BUG_ON(!IS_CHERRYVIEW(dev_priv->dev));
>  
> @@ -1697,14 +1686,14 @@ static int intel_num_dvo_pipes(struct drm_device *dev)
>  	return count;
>  }
>  
> -static void i9xx_enable_pll(struct intel_crtc *crtc)
> +static void i9xx_enable_pll(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;
>  	int reg = DPLL(crtc->pipe);
>  	u32 dpll = crtc->config->dpll_hw_state.dpll;
>  
> -	assert_pipe_disabled(dev_priv, crtc->pipe);
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>  
>  	/* No really, not for ILK+ */
>  	BUG_ON(INTEL_INFO(dev)->gen >= 5);
> @@ -1757,13 +1746,14 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
>  /**
>   * i9xx_disable_pll - disable a PLL
>   * @dev_priv: i915 private structure
> - * @pipe: pipe PLL to disable
> + * @pipe_config: currently applied config
>   *
>   * Disable the PLL for @pipe, making sure the pipe is off first.
>   *
>   * Note!  This is for pre-ILK only.
>   */
> -static void i9xx_disable_pll(struct intel_crtc *crtc)
> +static void i9xx_disable_pll(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;
> @@ -1785,7 +1775,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc)
>  		return;
>  
>  	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, pipe);
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, pipe);
>  
>  	I915_WRITE(DPLL(pipe), 0);
>  	POSTING_READ(DPLL(pipe));
> @@ -1795,9 +1785,6 @@ static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
>  {
>  	u32 val = 0;
>  
> -	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, pipe);
> -
>  	/*
>  	 * Leave integrated clock source and reference clock enabled for pipe B.
>  	 * The latter is needed for VGA hotplug / manual detection.
> @@ -1814,9 +1801,6 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
>  	enum dpio_channel port = vlv_pipe_to_channel(pipe);
>  	u32 val;
>  
> -	/* Make sure the pipe isn't still relying on us */
> -	assert_pipe_disabled(dev_priv, pipe);
> -
>  	/* Set PLL en = 0 */
>  	val = DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV;
>  	if (pipe != PIPE_A)
> @@ -1968,7 +1952,8 @@ static void intel_disable_shared_dpll(struct intel_crtc *crtc)
>  }
>  
>  static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
> -					   enum pipe pipe)
> +					   enum pipe pipe,
> +					   struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = dev_priv->dev;
>  	struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> @@ -1983,7 +1968,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
>  				   intel_crtc_to_shared_dpll(intel_crtc));
>  
>  	/* FDI must be feeding us bits for PCH ports */
> -	assert_fdi_tx_enabled(dev_priv, pipe);
> +	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
>  	assert_fdi_rx_enabled(dev_priv, pipe);
>  
>  	if (HAS_PCH_CPT(dev)) {
> @@ -2032,7 +2017,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
>  	BUG_ON(!HAS_PCH_SPLIT(dev_priv->dev));
>  
>  	/* FDI must be feeding us bits for PCH ports */
> -	assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
> +	assert_fdi_tx_enabled(dev_priv, cpu_transcoder, (enum pipe) cpu_transcoder);
>  	assert_fdi_rx_enabled(dev_priv, TRANSCODER_A);

I think the assert changes would also look good in a separate commit.

>  
>  	/* Workaround: set timing override bit. */
> @@ -2055,13 +2040,14 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
>  }
>  
>  static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv,
> +					    enum transcoder cpu_transcoder,
>  					    enum pipe pipe)
>  {
>  	struct drm_device *dev = dev_priv->dev;
>  	uint32_t reg, val;
>  
>  	/* FDI relies on the transcoder */
> -	assert_fdi_tx_disabled(dev_priv, pipe);
> +	assert_fdi_tx_disabled(dev_priv, cpu_transcoder, pipe);
>  	assert_fdi_rx_disabled(dev_priv, pipe);
>  
>  	/* Ports must be off as well */
> @@ -2113,8 +2099,9 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum pipe pipe = crtc->pipe;
> -	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
> -								      pipe);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	enum pipe pch_transcoder;
>  	int reg;
>  	u32 val;
> @@ -2163,6 +2150,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
>  /**
>   * intel_disable_pipe - disable a pipe, asserting requirements
>   * @crtc: crtc whose pipes is to be disabled
> + * @old_state: currently applied config
>   *
>   * Disable the pipe of @crtc, making sure that various hardware
>   * specific requirements are met, if applicable, e.g. plane
> @@ -2170,10 +2158,11 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
>   *
>   * Will wait until the pipe has shut down before returning.
>   */
> -static void intel_disable_pipe(struct intel_crtc *crtc)
> +static void intel_disable_pipe(struct intel_crtc *crtc,
> +			       struct intel_crtc_state *old_state)
>  {
>  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
>  	int reg;
>  	u32 val;
> @@ -2195,7 +2184,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
>  	 * Double wide has implications for planes
>  	 * so best keep it disabled when not needed.
>  	 */
> -	if (crtc->config->double_wide)
> +	if (old_state->double_wide)
>  		val &= ~PIPECONF_DOUBLE_WIDE;
>  
>  	/* Don't disable pipe or pipe PLLs if needed */
> @@ -2205,7 +2194,7 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
>  
>  	I915_WRITE(reg, val);
>  	if ((val & PIPECONF_ENABLE) == 0)
> -		intel_wait_for_pipe_off(crtc);
> +		intel_wait_for_pipe_off(crtc, old_state);
>  }
>  
>  /*
> @@ -3395,9 +3384,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
>  	int pipe = intel_crtc->pipe;
>  	u32 reg, temp, tries;
>  
> -	/* FDI needs bits from pipe first */
> -	assert_pipe_enabled(dev_priv, pipe);
> -
>  	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
>  	   for train result */
>  	reg = FDI_RX_IMR(pipe);
> @@ -3737,7 +3723,8 @@ train_done:
>  	DRM_DEBUG_KMS("FDI train done.\n");
>  }
>  
> -static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
> +static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc,
> +				    struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -3749,7 +3736,7 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc)
>  	reg = FDI_RX_CTL(pipe);
>  	temp = I915_READ(reg);
>  	temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>  	temp |= (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
>  	I915_WRITE(reg, temp | FDI_RX_PLL_ENABLE);
>  
> @@ -4093,7 +4080,7 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
>   *   - DP transcoding bits
>   *   - transcoder
>   */
> -static void ironlake_pch_enable(struct drm_crtc *crtc)
> +static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -4122,7 +4109,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
>  		temp = I915_READ(PCH_DPLL_SEL);
>  		temp |= TRANS_DPLL_ENABLE(pipe);
>  		sel = TRANS_DPLLB_SEL(pipe);
> -		if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
> +		if (pipe_config->shared_dpll == DPLL_ID_PCH_PLL_B)
>  			temp |= sel;
>  		else
>  			temp &= ~sel;
> @@ -4145,7 +4132,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
>  	intel_fdi_normal_train(crtc);
>  
>  	/* For PCH DP, enable TRANS_DP_CTL */
> -	if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) {
> +	if (HAS_PCH_CPT(dev) && pipe_config->has_dp_encoder) {
>  		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
>  		reg = TRANS_DP_CTL(pipe);
>  		temp = I915_READ(reg);
> @@ -4178,7 +4165,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
>  		I915_WRITE(reg, temp);
>  	}
>  
> -	ironlake_enable_pch_transcoder(dev_priv, pipe);
> +	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
>  }
>  
>  static void lpt_pch_enable(struct drm_crtc *crtc)
> @@ -4789,23 +4776,25 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
> +	struct intel_crtc_state *pipe_config;
>  
>  	WARN_ON(!crtc->state->enable);
>  
> -	if (intel_crtc->active)
> +	if (WARN_ON(intel_crtc->active))
>  		return;
> +	pipe_config = to_intel_crtc_state(crtc->state);
>  
> -	if (intel_crtc->config->has_pch_encoder)
> +	if (pipe_config->has_pch_encoder)
>  		intel_prepare_shared_dpll(intel_crtc);
>  
> -	if (intel_crtc->config->has_dp_encoder)
> +	if (pipe_config->has_dp_encoder)
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>  
>  	intel_set_pipe_timings(intel_crtc);
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (pipe_config->has_pch_encoder) {
>  		intel_cpu_transcoder_set_m_n(intel_crtc,
> -				     &intel_crtc->config->fdi_m_n, NULL);
> +				     &pipe_config->fdi_m_n, NULL);
>  	}
>  
>  	ironlake_set_pipeconf(crtc);
> @@ -4823,9 +4812,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  		/* Note: FDI PLL enabling _must_ be done before we enable the
>  		 * cpu pipes, hence this is separate from all the other fdi/pch
>  		 * enabling. */
> -		ironlake_fdi_pll_enable(intel_crtc);
> +		ironlake_fdi_pll_enable(intel_crtc, pipe_config);

Tons of changes in _enable code which really shouldn't be part of this
patch here.

>  	} else {
> -		assert_fdi_tx_disabled(dev_priv, pipe);
> +		assert_fdi_tx_disabled(dev_priv, pipe_config->cpu_transcoder, pipe);
>  		assert_fdi_rx_disabled(dev_priv, pipe);
>  	}
>  
> @@ -4841,7 +4830,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  	intel_enable_pipe(intel_crtc);
>  
>  	if (intel_crtc->config->has_pch_encoder)
> -		ironlake_pch_enable(crtc);
> +		ironlake_pch_enable(crtc, pipe_config);
>  
>  	assert_vblank_disabled(crtc);
>  	drm_crtc_vblank_on(crtc);
> @@ -4893,30 +4882,32 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config;
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
>  
>  	WARN_ON(!crtc->state->enable);
>  
> -	if (intel_crtc->active)
> +	if (WARN_ON(intel_crtc->active))
>  		return;
>  
> +	pipe_config = to_intel_crtc_state(crtc->state);
>  	if (intel_crtc_to_shared_dpll(intel_crtc))
>  		intel_enable_shared_dpll(intel_crtc);
>  
> -	if (intel_crtc->config->has_dp_encoder)
> +	if (pipe_config->has_dp_encoder)
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>  
>  	intel_set_pipe_timings(intel_crtc);
>  
> -	if (intel_crtc->config->cpu_transcoder != TRANSCODER_EDP) {
> -		I915_WRITE(PIPE_MULT(intel_crtc->config->cpu_transcoder),
> -			   intel_crtc->config->pixel_multiplier - 1);
> +	if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
> +		I915_WRITE(PIPE_MULT(pipe_config->cpu_transcoder),
> +			   pipe_config->pixel_multiplier - 1);
>  	}
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (pipe_config->has_pch_encoder) {
>  		intel_cpu_transcoder_set_m_n(intel_crtc,
> -				     &intel_crtc->config->fdi_m_n, NULL);
> +				     &pipe_config->fdi_m_n, NULL);
>  	}
>  
>  	haswell_set_pipeconf(crtc);
> @@ -4930,9 +4921,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  		if (encoder->pre_enable)
>  			encoder->pre_enable(encoder);
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (pipe_config->has_pch_encoder) {
>  		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
>  						      true);
> +
>  		dev_priv->display.fdi_link_train(crtc);
>  	}
>  
> @@ -4991,7 +4983,8 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
>  	}
>  }
>  
> -static void ironlake_crtc_disable(struct drm_crtc *crtc)
> +static void ironlake_crtc_disable(struct drm_crtc *crtc,
> +				  struct intel_crtc_state *old_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -5006,10 +4999,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
>  	drm_crtc_vblank_off(crtc);
>  	assert_vblank_disabled(crtc);
>  
> -	if (intel_crtc->config->has_pch_encoder)
> +	if (old_state->has_pch_encoder)
>  		intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, false);
>  
> -	intel_disable_pipe(intel_crtc);
> +	intel_disable_pipe(intel_crtc, old_state);
>  
>  	ironlake_pfit_disable(intel_crtc);
>  
> @@ -5017,10 +5010,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
>  		if (encoder->post_disable)
>  			encoder->post_disable(encoder);
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (old_state->has_pch_encoder) {
>  		ironlake_fdi_disable(crtc);
>  
> -		ironlake_disable_pch_transcoder(dev_priv, pipe);
> +		ironlake_disable_pch_transcoder(dev_priv, old_state->cpu_transcoder, pipe);
>  
>  		if (HAS_PCH_CPT(dev)) {
>  			/* disable TRANS_DP_CTL */
> @@ -5041,7 +5034,8 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
>  	}
>  }
>  
> -static void haswell_crtc_disable(struct drm_crtc *crtc)
> +static void haswell_crtc_disable(struct drm_crtc *crtc,
> +				 struct intel_crtc_state *old_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -5060,7 +5054,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>  	if (intel_crtc->config->has_pch_encoder)
>  		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
>  						      false);
> -	intel_disable_pipe(intel_crtc);
> +	intel_disable_pipe(intel_crtc, old_state);
>  
>  	if (intel_crtc->config->dp_encoder_is_mst)
>  		intel_ddi_set_vc_payload_alloc(crtc, false);
> @@ -5086,11 +5080,11 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
>  			encoder->post_disable(encoder);
>  }
>  
> -static void i9xx_pfit_enable(struct intel_crtc *crtc)
> +static void i9xx_pfit_enable(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;
> -	struct intel_crtc_state *pipe_config = crtc->config;
>  
>  	if (!pipe_config->gmch_pfit.control)
>  		return;
> @@ -5100,7 +5094,7 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
>  	 * according to register description and PRM.
>  	 */
>  	WARN_ON(I915_READ(PFIT_CONTROL) & PFIT_ENABLE);
> -	assert_pipe_disabled(dev_priv, crtc->pipe);
> +	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>  
>  	I915_WRITE(PFIT_PGM_RATIOS, pipe_config->gmch_pfit.pgm_ratios);
>  	I915_WRITE(PFIT_CONTROL, pipe_config->gmch_pfit.control);
> @@ -5167,7 +5161,7 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
>  	unsigned long mask;
>  	enum transcoder transcoder;
>  
> -	transcoder = intel_pipe_to_cpu_transcoder(dev->dev_private, pipe);
> +	transcoder = to_intel_crtc_state(crtc->state)->cpu_transcoder;
>  
>  	mask = BIT(POWER_DOMAIN_PIPE(pipe));
>  	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
> @@ -5767,22 +5761,24 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  	struct intel_encoder *encoder;
>  	int pipe = intel_crtc->pipe;
>  	bool is_dsi;
> +	struct intel_crtc_state *pipe_config;
>  
>  	WARN_ON(!crtc->state->active);
>  
> -	if (intel_crtc->active)
> +	if (WARN_ON(intel_crtc->active))
>  		return;
> +	pipe_config = to_intel_crtc_state(crtc->state);
>  
>  	is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
>  
>  	if (!is_dsi) {
>  		if (IS_CHERRYVIEW(dev))
> -			chv_prepare_pll(intel_crtc, intel_crtc->config);
> +			chv_prepare_pll(intel_crtc, pipe_config);
>  		else
> -			vlv_prepare_pll(intel_crtc, intel_crtc->config);
> +			vlv_prepare_pll(intel_crtc, pipe_config);
>  	}
>  
> -	if (intel_crtc->config->has_dp_encoder)
> +	if (pipe_config->has_dp_encoder)
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>  
>  	intel_set_pipe_timings(intel_crtc);
> @@ -5806,16 +5802,16 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  
>  	if (!is_dsi) {
>  		if (IS_CHERRYVIEW(dev))
> -			chv_enable_pll(intel_crtc, intel_crtc->config);
> +			chv_enable_pll(intel_crtc, pipe_config);
>  		else
> -			vlv_enable_pll(intel_crtc, intel_crtc->config);
> +			vlv_enable_pll(intel_crtc, pipe_config);
>  	}
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->pre_enable)
>  			encoder->pre_enable(encoder);
>  
> -	i9xx_pfit_enable(intel_crtc);
> +	i9xx_pfit_enable(intel_crtc, pipe_config);
>  
>  	intel_crtc_load_lut(crtc);
>  
> @@ -5844,11 +5840,13 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_encoder *encoder;
> +	struct intel_crtc_state *pipe_config;
>  	int pipe = intel_crtc->pipe;
>  
> -	WARN_ON(!crtc->state->active);
> +	pipe_config = to_intel_crtc_state(crtc->state);
> +	WARN_ON(!pipe_config->base.active);
>  
> -	if (intel_crtc->active)
> +	if (WARN_ON(intel_crtc->active))
>  		return;
>  
>  	i9xx_set_pll_dividers(intel_crtc);
> @@ -5869,9 +5867,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  		if (encoder->pre_enable)
>  			encoder->pre_enable(encoder);
>  
> -	i9xx_enable_pll(intel_crtc);
> +	i9xx_enable_pll(intel_crtc, pipe_config);
>  
> -	i9xx_pfit_enable(intel_crtc);
> +	i9xx_pfit_enable(intel_crtc, pipe_config);
>  
>  	intel_crtc_load_lut(crtc);
>  
> @@ -5893,14 +5891,13 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc)
>  	if (!crtc->config->gmch_pfit.control)
>  		return;
>  
> -	assert_pipe_disabled(dev_priv, crtc->pipe);
> -
>  	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
>  			 I915_READ(PFIT_CONTROL));
>  	I915_WRITE(PFIT_CONTROL, 0);
>  }
>  
> -static void i9xx_crtc_disable(struct drm_crtc *crtc)
> +static void i9xx_crtc_disable(struct drm_crtc *crtc,
> +			      struct intel_crtc_state *old_state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -5922,7 +5919,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  	drm_crtc_vblank_off(crtc);
>  	assert_vblank_disabled(crtc);
>  
> -	intel_disable_pipe(intel_crtc);
> +	intel_disable_pipe(intel_crtc, old_state);
>  
>  	i9xx_pfit_disable(intel_crtc);
>  
> @@ -5936,7 +5933,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>  		else if (IS_VALLEYVIEW(dev))
>  			vlv_disable_pll(dev_priv, pipe);
>  		else
> -			i9xx_disable_pll(intel_crtc);
> +			i9xx_disable_pll(intel_crtc, old_state);
>  	}
>  
>  	if (!IS_GEN2(dev))
> @@ -6989,10 +6986,12 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
>  {
>  	struct intel_crtc *crtc =
>  		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> +	struct intel_crtc_state *state = to_intel_crtc_state(crtc->base.state);
>  	struct intel_crtc_state pipe_config = {
>  		.base.crtc = &crtc->base,
>  		.pixel_multiplier = 1,
>  		.dpll = *dpll,
> +		.cpu_transcoder = state->cpu_transcoder,
>  	};
>  
>  	if (IS_CHERRYVIEW(dev)) {
> @@ -7016,6 +7015,16 @@ void vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
>   */
>  void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
>  {
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
> +	struct intel_crtc_state *state = to_intel_crtc_state(crtc->state);
> +
> +	/* Is state->cpu_transcoder correct to use? */
> +	WARN_ON(crtc->state != &to_intel_crtc(crtc)->config->base);
> +
> +	/* Make sure the pipe isn't still relying on us */
> +	assert_pipe_disabled(dev_priv, state->cpu_transcoder, pipe);
> +
>  	if (IS_CHERRYVIEW(dev))
>  		chv_disable_pll(to_i915(dev), pipe);
>  	else
> @@ -12275,6 +12284,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  
>  	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +		struct intel_crtc_state *pipe_config;
>  
>  		if (!needs_modeset(crtc->state))
>  			continue;
> @@ -12282,8 +12292,9 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  		if (!old_crtc_state->active)
>  			continue;
>  
> +		pipe_config = to_intel_crtc_state(old_crtc_state);
>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
> -		dev_priv->display.crtc_disable(crtc);
> +		dev_priv->display.crtc_disable(crtc, pipe_config);
>  
>  		intel_crtc->active = false;
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 82dcc6ed8b1d..83de36bfddc1 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2090,6 +2090,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
>  	u32 dpa_ctl;
>  
>  	assert_pipe_disabled(dev_priv,
> +			     to_intel_crtc_state(crtc->state)->cpu_transcoder,
>  			     to_intel_crtc(crtc)->pipe);
>  
>  	DRM_DEBUG_KMS("\n");
> @@ -2116,6 +2117,7 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
>  	u32 dpa_ctl;
>  
>  	assert_pipe_disabled(dev_priv,
> +			     to_intel_crtc(crtc)->config->cpu_transcoder,
>  			     to_intel_crtc(crtc)->pipe);
>  
>  	dpa_ctl = I915_READ(DP_A);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 9ef89c91aa5c..58240e63630c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -998,8 +998,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
>  int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
>  				struct drm_file *file_priv);
> -enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
> -					     enum pipe pipe);
>  bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type);
>  static inline void
>  intel_wait_for_vblank(struct drm_device *dev, int pipe)
> @@ -1085,9 +1083,11 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
>  		       enum pipe pipe, bool state);
>  #define assert_fdi_rx_pll_enabled(d, p) assert_fdi_rx_pll(d, p, true)
>  #define assert_fdi_rx_pll_disabled(d, p) assert_fdi_rx_pll(d, p, false)
> -void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, bool state);
> -#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
> -#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
> +void assert_pipe(struct drm_i915_private *dev_priv,
> +		 enum transcoder cpu_transcoder,
> +		 enum pipe pipe, bool state);
> +#define assert_pipe_enabled(d, c, p) assert_pipe(d, c, p, true)
> +#define assert_pipe_disabled(d, c, p) assert_pipe(d, c, p, false)
>  unsigned long intel_gen4_compute_page_offset(int *x, int *y,
>  					     unsigned int tiling_mode,
>  					     unsigned int bpp,
> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> index 7d83527f95f7..67eafa27400b 100644
> --- a/drivers/gpu/drm/i915/intel_panel.c
> +++ b/drivers/gpu/drm/i915/intel_panel.c
> @@ -837,9 +837,8 @@ static void pch_enable_backlight(struct intel_connector *connector)
>  	struct drm_device *dev = connector->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = intel_get_pipe_from_connector(connector);
>  	enum transcoder cpu_transcoder =
> -		intel_pipe_to_cpu_transcoder(dev_priv, pipe);
> +		to_intel_crtc_state(connector->encoder->base.crtc->state)->cpu_transcoder;
>  	u32 cpu_ctl2, pch_ctl1, pch_ctl2;
>  
>  	cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> index 8b9d325bda3c..b4aeb256128f 100644
> --- a/drivers/gpu/drm/i915/intel_tv.c
> +++ b/drivers/gpu/drm/i915/intel_tv.c
> @@ -1117,7 +1117,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder)
>  			   ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
>  			    (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
>  
> -	assert_pipe_disabled(dev_priv, intel_crtc->pipe);
> +	assert_pipe_disabled(dev_priv, to_intel_crtc_state(intel_crtc->base.state)->cpu_transcoder, intel_crtc->pipe);

These two hunks look misplaced, should be in a different patch. I didn't
comment about all of them, but imo the patch to roll out the old state for
crtc_disable shouldn't mix hunks with _enabl code, since then checking for
whether we need the old or new state gets really quickly confusing.
-Daniel


>  
>  	/* Filter ctl must be set before TV_WIN_SIZE */
>  	I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable.
  2015-05-11 14:24 ` [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable Maarten Lankhorst
@ 2015-05-12  9:16   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:16 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:24:59PM +0200, Maarten Lankhorst wrote:
> This removes a lot of users for crtc->config.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Changing connector->set_dpms should be a separate patch. Otherwise same
comment as with the previous patch about touching _enable functions.
-Daniel


> ---
>  drivers/gpu/drm/i915/intel_crt.c     | 21 ++++++----
>  drivers/gpu/drm/i915/intel_ddi.c     | 78 +++++++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++-------
>  drivers/gpu/drm/i915/intel_dp.c      | 49 +++++++++-------------
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  9 +++--
>  drivers/gpu/drm/i915/intel_drv.h     | 13 +++---
>  drivers/gpu/drm/i915/intel_dsi.c     | 11 +++--
>  drivers/gpu/drm/i915/intel_dvo.c     | 15 ++++---
>  drivers/gpu/drm/i915/intel_hdmi.c    | 20 +++++----
>  drivers/gpu/drm/i915/intel_lvds.c    | 11 +++--
>  drivers/gpu/drm/i915/intel_sdvo.c    |  3 +-
>  drivers/gpu/drm/i915/intel_tv.c      |  3 +-
>  12 files changed, 150 insertions(+), 119 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 93bb5159d093..d94f6cb91d42 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -152,13 +152,13 @@ static void hsw_crt_pre_enable(struct intel_encoder *encoder)
>  
>  /* Note: The caller is required to filter out dpms modes not supported by the
>   * platform. */
> -static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
> +static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode,
> +			       struct drm_display_mode *adjusted_mode)
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crt *crt = intel_encoder_to_crt(encoder);
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> -	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
>  	u32 adpa;
>  
>  	if (INTEL_INFO(dev)->gen >= 5)
> @@ -202,13 +202,16 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode)
>  	I915_WRITE(crt->adpa_reg, adpa);
>  }
>  
> -static void intel_disable_crt(struct intel_encoder *encoder)
> +static void intel_disable_crt(struct intel_encoder *encoder,
> +			      struct intel_crtc_state *pipe_config)
>  {
> -	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);
> +	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF,
> +			   &pipe_config->base.adjusted_mode);
>  }
>  
>  
> -static void hsw_crt_post_disable(struct intel_encoder *encoder)
> +static void hsw_crt_post_disable(struct intel_encoder *encoder,
> +				 struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -224,8 +227,10 @@ static void hsw_crt_post_disable(struct intel_encoder *encoder)
>  static void intel_enable_crt(struct intel_encoder *encoder)
>  {
>  	struct intel_crt *crt = intel_encoder_to_crt(encoder);
> +	struct drm_crtc *crtc = encoder->base.crtc;
>  
> -	intel_crt_set_dpms(encoder, crt->connector->base.dpms);
> +	intel_crt_set_dpms(encoder, crt->connector->base.dpms,
> +			   &crtc->state->adjusted_mode);
>  }
>  
>  /* Special dpms function to support cloning between dvo/sdvo/crt. */
> @@ -265,9 +270,9 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
>  		/* From off to on, enable the pipe first. */
>  		intel_crtc_update_dpms(crtc);
>  
> -		intel_crt_set_dpms(encoder, mode);
> +		intel_crt_set_dpms(encoder, mode, &crtc->state->adjusted_mode);
>  	} else {
> -		intel_crt_set_dpms(encoder, mode);
> +		intel_crt_set_dpms(encoder, mode, &crtc->state->adjusted_mode);
>  
>  		intel_crtc_update_dpms(crtc);
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 807e15d41a1b..c5a9e36d6a0e 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -430,7 +430,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	u32 temp, i, rx_ctl_val;
>  
>  	/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
> @@ -447,7 +448,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  	/* Enable the PCH Receiver FDI PLL */
>  	rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
>  		     FDI_RX_PLL_ENABLE |
> -		     FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> +		     FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>  	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
>  	POSTING_READ(_FDI_RXA_CTL);
>  	udelay(220);
> @@ -457,8 +458,8 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  	I915_WRITE(_FDI_RXA_CTL, rx_ctl_val);
>  
>  	/* Configure Port Clock Select */
> -	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
> -	WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
> +	I915_WRITE(PORT_CLK_SEL(PORT_E), pipe_config->ddi_pll_sel);
> +	WARN_ON(pipe_config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
>  
>  	/* Start the training iterating through available voltages and emphasis,
>  	 * testing each value twice. */
> @@ -476,7 +477,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
>  		 * port reversal bit */
>  		I915_WRITE(DDI_BUF_CTL(PORT_E),
>  			   DDI_BUF_CTL_ENABLE |
> -			   ((intel_crtc->config->fdi_lanes - 1) << 1) |
> +			   ((pipe_config->fdi_lanes - 1) << 1) |
>  			   DDI_BUF_TRANS_SELECT(i / 2));
>  		POSTING_READ(DDI_BUF_CTL(PORT_E));
>  
> @@ -1481,15 +1482,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
>  void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
>  {
>  	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	int type = intel_encoder->type;
>  	uint32_t temp;
>  
>  	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
>  		temp = TRANS_MSA_SYNC_CLK;
> -		switch (intel_crtc->config->pipe_bpp) {
> +		switch (pipe_config->pipe_bpp) {
>  		case 18:
>  			temp |= TRANS_MSA_6_BPC;
>  			break;
> @@ -1509,12 +1511,12 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
>  	}
>  }
>  
> -void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
> +void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc,
> +				    enum transcoder cpu_transcoder,
> +				    bool state)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>  	uint32_t temp;
>  	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (state == true)
> @@ -1532,7 +1534,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum pipe pipe = intel_crtc->pipe;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
>  	int type = intel_encoder->type;
>  	uint32_t temp;
> @@ -1541,7 +1544,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  	temp = TRANS_DDI_FUNC_ENABLE;
>  	temp |= TRANS_DDI_SELECT_PORT(port);
>  
> -	switch (intel_crtc->config->pipe_bpp) {
> +	switch (pipe_config->pipe_bpp) {
>  	case 18:
>  		temp |= TRANS_DDI_BPC_6;
>  		break;
> @@ -1558,9 +1561,9 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  		BUG();
>  	}
>  
> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
> +	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
>  		temp |= TRANS_DDI_PVSYNC;
> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
> +	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
>  		temp |= TRANS_DDI_PHSYNC;
>  
>  	if (cpu_transcoder == TRANSCODER_EDP) {
> @@ -1571,8 +1574,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  			 * using motion blur mitigation (which we don't
>  			 * support). */
>  			if (IS_HASWELL(dev) &&
> -			    (intel_crtc->config->pch_pfit.enabled ||
> -			     intel_crtc->config->pch_pfit.force_thru))
> +			    (pipe_config->pch_pfit.enabled ||
> +			     pipe_config->pch_pfit.force_thru))
>  				temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
>  			else
>  				temp |= TRANS_DDI_EDP_INPUT_A_ON;
> @@ -1590,14 +1593,14 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
>  	}
>  
>  	if (type == INTEL_OUTPUT_HDMI) {
> -		if (intel_crtc->config->has_hdmi_sink)
> +		if (pipe_config->has_hdmi_sink)
>  			temp |= TRANS_DDI_MODE_SELECT_HDMI;
>  		else
>  			temp |= TRANS_DDI_MODE_SELECT_DVI;
>  
>  	} else if (type == INTEL_OUTPUT_ANALOG) {
>  		temp |= TRANS_DDI_MODE_SELECT_FDI;
> -		temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
> +		temp |= (pipe_config->fdi_lanes - 1) << 1;
>  
>  	} else if (type == INTEL_OUTPUT_DISPLAYPORT ||
>  		   type == INTEL_OUTPUT_EDP) {
> @@ -1747,17 +1750,19 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
>  	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
>  	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  
>  	if (cpu_transcoder != TRANSCODER_EDP)
>  		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
>  			   TRANS_CLK_SEL_PORT(port));
>  }
>  
> -void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
> +void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc,
> +				  enum transcoder cpu_transcoder)
>  {
>  	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>  
>  	if (cpu_transcoder != TRANSCODER_EDP)
>  		I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
> @@ -1902,7 +1907,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
>  	}
>  }
>  
> -static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
> +static void intel_ddi_post_disable(struct intel_encoder *intel_encoder,
> +				   struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_device *dev = encoder->dev;
> @@ -1945,10 +1951,11 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_crtc *crtc = encoder->crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum port port = intel_ddi_get_encoder_port(intel_encoder);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	int type = intel_encoder->type;
>  
>  	if (type == INTEL_OUTPUT_HDMI) {
> @@ -1970,25 +1977,28 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
>  
>  		intel_edp_backlight_on(intel_dp);
>  		intel_psr_enable(intel_dp);
> -		intel_edp_drrs_enable(intel_dp);
> +
> +		if (pipe_config->has_drrs)
> +			intel_edp_drrs_enable(intel_dp);
> +		else
> +			DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
>  	}
>  
> -	if (intel_crtc->config->has_audio) {
> +	if (pipe_config->has_audio) {
>  		intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
>  		intel_audio_codec_enable(intel_encoder);
>  	}
>  }
>  
> -static void intel_disable_ddi(struct intel_encoder *intel_encoder)
> +static void intel_disable_ddi(struct intel_encoder *intel_encoder,
> +			      struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_encoder *encoder = &intel_encoder->base;
> -	struct drm_crtc *crtc = encoder->crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	int type = intel_encoder->type;
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  
> -	if (intel_crtc->config->has_audio) {
> +	if (pipe_config->has_audio) {
>  		intel_audio_codec_disable(intel_encoder);
>  		intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
>  	}
> @@ -1996,7 +2006,8 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
>  	if (type == INTEL_OUTPUT_EDP) {
>  		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  
> -		intel_edp_drrs_disable(intel_dp);
> +		if (pipe_config->has_drrs)
> +			intel_edp_drrs_disable(intel_dp);
>  		intel_psr_disable(intel_dp);
>  		intel_edp_backlight_off(intel_dp);
>  	}
> @@ -2546,13 +2557,14 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
>  	udelay(600);
>  }
>  
> -void intel_ddi_fdi_disable(struct drm_crtc *crtc)
> +void intel_ddi_fdi_disable(struct drm_crtc *crtc,
> +			   struct intel_crtc_state *old_state)
>  {
>  	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
>  	struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
>  	uint32_t val;
>  
> -	intel_ddi_post_disable(intel_encoder);
> +	intel_ddi_post_disable(intel_encoder, old_state);
>  
>  	val = I915_READ(_FDI_RXA_CTL);
>  	val &= ~FDI_RX_ENABLE;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 311a4b44bebe..7bc78b49f9f4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4953,7 +4953,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  		lpt_pch_enable(crtc);
>  
>  	if (intel_crtc->config->dp_encoder_is_mst)
> -		intel_ddi_set_vc_payload_alloc(crtc, true);
> +		intel_ddi_set_vc_payload_alloc(crtc,
> +					       pipe_config->cpu_transcoder,
> +					       true);
>  
>  	assert_vblank_disabled(crtc);
>  	drm_crtc_vblank_on(crtc);
> @@ -4994,7 +4996,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
>  	u32 reg, temp;
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
> -		encoder->disable(encoder);
> +		encoder->disable(encoder, old_state);
>  
>  	drm_crtc_vblank_off(crtc);
>  	assert_vblank_disabled(crtc);
> @@ -5008,7 +5010,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
> -			encoder->post_disable(encoder);
> +			encoder->post_disable(encoder, old_state);
>  
>  	if (old_state->has_pch_encoder) {
>  		ironlake_fdi_disable(crtc);
> @@ -5045,7 +5047,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder) {
>  		intel_opregion_notify_encoder(encoder, false);
> -		encoder->disable(encoder);
> +		encoder->disable(encoder, old_state);
>  	}
>  
>  	drm_crtc_vblank_off(crtc);
> @@ -5057,7 +5059,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  	intel_disable_pipe(intel_crtc, old_state);
>  
>  	if (intel_crtc->config->dp_encoder_is_mst)
> -		intel_ddi_set_vc_payload_alloc(crtc, false);
> +		intel_ddi_set_vc_payload_alloc(crtc,
> +					       old_state->cpu_transcoder,
> +					       false);
>  
>  	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
>  
> @@ -5068,16 +5072,16 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  	else
>  		MISSING_CASE(INTEL_INFO(dev)->gen);
>  
> -	intel_ddi_disable_pipe_clock(intel_crtc);
> +	intel_ddi_disable_pipe_clock(intel_crtc, old_state->cpu_transcoder);
>  
>  	if (intel_crtc->config->has_pch_encoder) {
>  		lpt_disable_pch_transcoder(dev_priv);
> -		intel_ddi_fdi_disable(crtc);
> +		intel_ddi_fdi_disable(crtc, old_state);
>  	}
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
> -			encoder->post_disable(encoder);
> +			encoder->post_disable(encoder, old_state);
>  }
>  
>  static void i9xx_pfit_enable(struct intel_crtc *crtc,
> @@ -5914,7 +5918,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
>  	intel_wait_for_vblank(dev, pipe);
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
> -		encoder->disable(encoder);
> +		encoder->disable(encoder, old_state);
>  
>  	drm_crtc_vblank_off(crtc);
>  	assert_vblank_disabled(crtc);
> @@ -5925,7 +5929,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
> -			encoder->post_disable(encoder);
> +			encoder->post_disable(encoder, old_state);
>  
>  	if (!intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI)) {
>  		if (IS_CHERRYVIEW(dev))
> @@ -14672,12 +14676,12 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
>  {
>  	struct intel_connector *connector;
>  	struct drm_device *dev = encoder->base.dev;
> +	struct drm_crtc *crtc = encoder->base.crtc;
>  
>  	/* We need to check both for a crtc link (meaning that the
>  	 * encoder is active and trying to read from a pipe) and the
>  	 * pipe itself being active. */
> -	bool has_active_crtc = encoder->base.crtc &&
> -		to_intel_crtc(encoder->base.crtc)->active;
> +	bool has_active_crtc = crtc && to_intel_crtc(crtc)->active;
>  
>  	if (encoder->connectors_active && !has_active_crtc) {
>  		DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
> @@ -14687,13 +14691,15 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
>  		/* Connector is active, but has no active pipe. This is
>  		 * fallout from our resume register restoring. Disable
>  		 * the encoder manually again. */
> -		if (encoder->base.crtc) {
> +		if (crtc) {
> +			struct intel_crtc_state *pipe_config =
> +				to_intel_crtc_state(crtc->state);
>  			DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n",
>  				      encoder->base.base.id,
>  				      encoder->base.name);
> -			encoder->disable(encoder);
> +			encoder->disable(encoder, pipe_config);
>  			if (encoder->post_disable)
> -				encoder->post_disable(encoder);
> +				encoder->post_disable(encoder, pipe_config);
>  		}
>  		encoder->base.crtc = NULL;
>  		encoder->connectors_active = false;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 83de36bfddc1..eda1b22c3111 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1499,17 +1499,19 @@ found:
>  static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_crtc *crtc = dig_port->base.base.crtc;
> +	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	u32 dpa_ctl;
>  
>  	DRM_DEBUG_KMS("eDP PLL enable for clock %d\n",
> -		      crtc->config->port_clock);
> +		      pipe_config->port_clock);
>  	dpa_ctl = I915_READ(DP_A);
>  	dpa_ctl &= ~DP_PLL_FREQ_MASK;
>  
> -	if (crtc->config->port_clock == 162000) {
> +	if (pipe_config->port_clock == 162000) {
>  		/* For a long time we've carried around a ILK-DevA w/a for the
>  		 * 160MHz clock. If we're really unlucky, it's still required.
>  		 */
> @@ -2108,7 +2110,8 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
>  	udelay(200);
>  }
>  
> -static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
> +static void ironlake_edp_pll_off(struct intel_dp *intel_dp,
> +				 struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
> @@ -2117,7 +2120,7 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
>  	u32 dpa_ctl;
>  
>  	assert_pipe_disabled(dev_priv,
> -			     to_intel_crtc(crtc)->config->cpu_transcoder,
> +			     pipe_config->cpu_transcoder,
>  			     to_intel_crtc(crtc)->pipe);
>  
>  	dpa_ctl = I915_READ(DP_A);
> @@ -2308,13 +2311,13 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>  	}
>  }
>  
> -static void intel_disable_dp(struct intel_encoder *encoder)
> +static void intel_disable_dp(struct intel_encoder *encoder,
> +			     struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct drm_device *dev = encoder->base.dev;
> -	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
>  
> -	if (crtc->config->has_audio)
> +	if (pipe_config->has_audio)
>  		intel_audio_codec_disable(encoder);
>  
>  	if (HAS_PSR(dev) && !HAS_DDI(dev))
> @@ -2332,24 +2335,27 @@ static void intel_disable_dp(struct intel_encoder *encoder)
>  		intel_dp_link_down(intel_dp);
>  }
>  
> -static void ilk_post_disable_dp(struct intel_encoder *encoder)
> +static void ilk_post_disable_dp(struct intel_encoder *encoder,
> +				struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	enum port port = dp_to_dig_port(intel_dp)->port;
>  
>  	intel_dp_link_down(intel_dp);
>  	if (port == PORT_A)
> -		ironlake_edp_pll_off(intel_dp);
> +		ironlake_edp_pll_off(intel_dp, pipe_config);
>  }
>  
> -static void vlv_post_disable_dp(struct intel_encoder *encoder)
> +static void vlv_post_disable_dp(struct intel_encoder *encoder,
> +				struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  
>  	intel_dp_link_down(intel_dp);
>  }
>  
> -static void chv_post_disable_dp(struct intel_encoder *encoder)
> +static void chv_post_disable_dp(struct intel_encoder *encoder,
> +				struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
> @@ -5249,7 +5255,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  	struct intel_encoder *encoder;
>  	struct intel_digital_port *dig_port = NULL;
>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> -	struct intel_crtc_state *config = NULL;
>  	struct intel_crtc *intel_crtc = NULL;
>  	u32 reg, val;
>  	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
> @@ -5278,8 +5283,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  		return;
>  	}
>  
> -	config = intel_crtc->config;
> -
>  	if (dev_priv->drrs.type < SEAMLESS_DRRS_SUPPORT) {
>  		DRM_DEBUG_KMS("Only Seamless DRRS supported.\n");
>  		return;
> @@ -5345,14 +5348,6 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_crtc *crtc = dig_port->base.base.crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	if (!intel_crtc->config->has_drrs) {
> -		DRM_DEBUG_KMS("Panel doesn't support DRRS\n");
> -		return;
> -	}
>  
>  	mutex_lock(&dev_priv->drrs.mutex);
>  	if (WARN_ON(dev_priv->drrs.dp)) {
> @@ -5377,12 +5372,6 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp)
>  {
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_crtc *crtc = dig_port->base.base.crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> -	if (!intel_crtc->config->has_drrs)
> -		return;
>  
>  	mutex_lock(&dev_priv->drrs.mutex);
>  	if (!dev_priv->drrs.dp) {
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 6e4cc5334f47..4992c8025520 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -101,7 +101,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  
>  }
>  
> -static void intel_mst_disable_dp(struct intel_encoder *encoder)
> +static void intel_mst_disable_dp(struct intel_encoder *encoder,
> +				 struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
> @@ -118,7 +119,8 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder)
>  	}
>  }
>  
> -static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
> +static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
> +				      struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>  	struct intel_digital_port *intel_dig_port = intel_mst->primary;
> @@ -136,7 +138,8 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
>  	intel_dp->active_mst_links--;
>  	intel_mst->port = NULL;
>  	if (intel_dp->active_mst_links == 0) {
> -		intel_dig_port->base.post_disable(&intel_dig_port->base);
> +		intel_dig_port->base.post_disable(&intel_dig_port->base,
> +						  pipe_config);
>  		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 58240e63630c..eb87f82b5aff 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -141,8 +141,9 @@ struct intel_encoder {
>  	void (*pre_enable)(struct intel_encoder *);
>  	void (*enable)(struct intel_encoder *);
>  	void (*mode_set)(struct intel_encoder *intel_encoder);
> -	void (*disable)(struct intel_encoder *);
> -	void (*post_disable)(struct intel_encoder *);
> +	void (*disable)(struct intel_encoder *, struct intel_crtc_state *);
> +	void (*post_disable)(struct intel_encoder *,
> +			     struct intel_crtc_state *);
>  	/* Read out the current hw state of this connector, returning true if
>  	 * the encoder is active. If the encoder is enabled it also set the pipe
>  	 * it is connected to in the pipe parameter. */
> @@ -910,13 +911,14 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
>  void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
>  				       enum transcoder cpu_transcoder);
>  void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
> -void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
> +void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc,
> +				  enum transcoder cpu_transcoder);
>  bool intel_ddi_pll_select(struct intel_crtc *crtc,
>  			  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);
>  bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
> -void intel_ddi_fdi_disable(struct drm_crtc *crtc);
> +void intel_ddi_fdi_disable(struct drm_crtc *crtc, struct intel_crtc_state *);
>  void intel_ddi_get_config(struct intel_encoder *encoder,
>  			  struct intel_crtc_state *pipe_config);
>  struct intel_encoder *
> @@ -925,7 +927,8 @@ intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state);
>  void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
>  void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
> -void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
> +void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc,
> +				    enum transcoder, bool state);
>  void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
>  				enum port port, int type);
>  
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index 51966426addf..3f28b046751b 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -409,6 +409,9 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
> +	
>  	enum pipe pipe = intel_crtc->pipe;
>  	enum port port;
>  	u32 tmp;
> @@ -422,7 +425,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder)
>  	I915_WRITE(DPLL(pipe), tmp);
>  
>  	/* update the hw state for DPLL */
> -	intel_crtc->config->dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
> +	pipe_config->dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV |
>  		DPLL_REFA_CLK_ENABLE_VLV;
>  
>  	tmp = I915_READ(DSPCLK_GATE_D);
> @@ -454,7 +457,8 @@ static void intel_dsi_enable_nop(struct intel_encoder *encoder)
>  	 */
>  }
>  
> -static void intel_dsi_pre_disable(struct intel_encoder *encoder)
> +static void intel_dsi_pre_disable(struct intel_encoder *encoder,
> +				  struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	enum port port;
> @@ -556,7 +560,8 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
>  	vlv_disable_dsi_pll(encoder);
>  }
>  
> -static void intel_dsi_post_disable(struct intel_encoder *encoder)
> +static void intel_dsi_post_disable(struct intel_encoder *encoder,
> +				   struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
> diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
> index ece5bd754f85..4dac4ce5963a 100644
> --- a/drivers/gpu/drm/i915/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/intel_dvo.c
> @@ -166,7 +166,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
>  	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
>  }
>  
> -static void intel_disable_dvo(struct intel_encoder *encoder)
> +static void intel_disable_dvo(struct intel_encoder *encoder,
> +			      struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
> @@ -182,13 +183,14 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
>  {
>  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
> -	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	struct drm_crtc *crtc = encoder->base.crtc;
> +	struct drm_crtc_state *pipe_config = crtc->state;
>  	u32 dvo_reg = intel_dvo->dev.dvo_reg;
>  	u32 temp = I915_READ(dvo_reg);
>  
>  	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
> -					 &crtc->config->base.mode,
> -					 &crtc->config->base.adjusted_mode);
> +					 &pipe_config->mode,
> +					 &pipe_config->adjusted_mode);
>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
>  	I915_READ(dvo_reg);
> @@ -201,7 +203,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
>  {
>  	struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
>  	struct drm_crtc *crtc;
> -	struct intel_crtc_state *config;
>  
>  	/* dvo supports only 2 dpms states. */
>  	if (mode != DRM_MODE_DPMS_ON)
> @@ -222,8 +223,6 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
>  	/* We call connector dpms manually below in case pipe dpms doesn't
>  	 * change due to cloning. */
>  	if (mode == DRM_MODE_DPMS_ON) {
> -		config = to_intel_crtc(crtc)->config;
> -
>  		intel_dvo->base.connectors_active = true;
>  
>  		intel_crtc_update_dpms(crtc);
> @@ -296,7 +295,7 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder)
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> -	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &crtc->base.state->adjusted_mode;
>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
>  	int pipe = crtc->pipe;
>  	u32 dvo_val;
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index d04e6dc97fe5..76994dc033a3 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -866,7 +866,8 @@ static void vlv_enable_hdmi(struct intel_encoder *encoder)
>  {
>  }
>  
> -static void intel_disable_hdmi(struct intel_encoder *encoder)
> +static void intel_disable_hdmi(struct intel_encoder *encoder,
> +			       struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -875,7 +876,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
>  	u32 temp;
>  	u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
>  
> -	if (crtc->config->has_audio)
> +	if (pipe_config->has_audio)
>  		intel_audio_codec_disable(encoder);
>  
>  	temp = I915_READ(intel_hdmi->hdmi_reg);
> @@ -883,8 +884,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
>  	/* HW workaround for IBX, we need to move the port to transcoder A
>  	 * before disabling it. */
>  	if (HAS_PCH_IBX(dev)) {
> -		struct drm_crtc *crtc = encoder->base.crtc;
> -		int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
> +		int pipe = crtc ? crtc->pipe : -1;
>  
>  		if (temp & SDVO_PIPE_B_SELECT) {
>  			temp &= ~SDVO_PIPE_B_SELECT;
> @@ -1426,7 +1426,8 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
>  	mutex_unlock(&dev_priv->dpio_lock);
>  }
>  
> -static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
> +static void vlv_hdmi_post_disable(struct intel_encoder *encoder,
> +				  struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> @@ -1442,7 +1443,8 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder)
>  	mutex_unlock(&dev_priv->dpio_lock);
>  }
>  
> -static void chv_hdmi_post_disable(struct intel_encoder *encoder)
> +static void chv_hdmi_post_disable(struct intel_encoder *encoder,
> +				  struct intel_crtc_state *pipe_config)
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_device *dev = encoder->base.dev;
> @@ -1483,8 +1485,10 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc =
>  		to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
>  	struct drm_display_mode *adjusted_mode =
> -		&intel_crtc->config->base.adjusted_mode;
> +		&pipe_config->base.adjusted_mode;
>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>  	int pipe = intel_crtc->pipe;
>  	int data, i, stagger;
> @@ -1636,7 +1640,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	mutex_unlock(&dev_priv->dpio_lock);
>  
>  	intel_hdmi->set_infoframes(&encoder->base,
> -				   intel_crtc->config->has_hdmi_sink,
> +				   pipe_config->has_hdmi_sink,
>  				   adjusted_mode);
>  
>  	intel_enable_hdmi(encoder);
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 9a9df0fa67f9..8aaaa24144f0 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -139,8 +139,10 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc->config->base.adjusted_mode;
> +		&pipe_config->base.adjusted_mode;
>  	int pipe = crtc->pipe;
>  	u32 temp;
>  
> @@ -168,7 +170,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
>  
>  	/* set the corresponsding LVDS_BORDER bit */
>  	temp &= ~LVDS_BORDER_ENABLE;
> -	temp |= crtc->config->gmch_pfit.lvds_border_bits;
> +	temp |= pipe_config->gmch_pfit.lvds_border_bits;
>  	/* Set the B0-B3 data pairs corresponding to whether we're going to
>  	 * set the DPLLs for dual-channel mode or not.
>  	 */
> @@ -191,7 +193,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
>  	if (INTEL_INFO(dev)->gen == 4) {
>  		/* Bspec wording suggests that LVDS port dithering only exists
>  		 * for 18bpp panels. */
> -		if (crtc->config->dither && crtc->config->pipe_bpp == 18)
> +		if (pipe_config->dither && pipe_config->pipe_bpp == 18)
>  			temp |= LVDS_ENABLE_DITHER;
>  		else
>  			temp &= ~LVDS_ENABLE_DITHER;
> @@ -235,7 +237,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
>  	intel_panel_enable_backlight(intel_connector);
>  }
>  
> -static void intel_disable_lvds(struct intel_encoder *encoder)
> +static void intel_disable_lvds(struct intel_encoder *encoder,
> +			       struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 0a0625761f42..6a68098f8b08 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -1425,7 +1425,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>  	     pipe_config->pixel_multiplier, encoder_pixel_multiplier);
>  }
>  
> -static void intel_disable_sdvo(struct intel_encoder *encoder)
> +static void intel_disable_sdvo(struct intel_encoder *encoder,
> +			       struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> index b4aeb256128f..9816a9f88ff5 100644
> --- a/drivers/gpu/drm/i915/intel_tv.c
> +++ b/drivers/gpu/drm/i915/intel_tv.c
> @@ -863,7 +863,8 @@ intel_enable_tv(struct intel_encoder *encoder)
>  }
>  
>  static void
> -intel_disable_tv(struct intel_encoder *encoder)
> +intel_disable_tv(struct intel_encoder *encoder,
> +		 struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c
  2015-05-11 14:25 ` [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c Maarten Lankhorst
@ 2015-05-12  9:20   ` Daniel Vetter
  2015-05-12 13:41     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:20 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:01PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_psr.c | 25 ++++++++++++++-----------
>  1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
> index 5ee0fa57ed19..868817402c11 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -73,14 +73,15 @@ static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
>  }
>  
>  static void intel_psr_write_vsc(struct intel_dp *intel_dp,
> -				    struct edp_vsc_psr *vsc_psr)
> +				struct edp_vsc_psr *vsc_psr)
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = dig_port->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
> -	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder);
> -	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config->cpu_transcoder);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(dig_port->base.base.crtc->state);
> +	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
> +	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(pipe_config->cpu_transcoder);
>  	uint32_t *data = (uint32_t *) vsc_psr;
>  	unsigned int i;
>  
> @@ -282,13 +283,13 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
>  				EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
>  }
>  
> -static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
> +static bool intel_psr_match_conditions(struct intel_dp *intel_dp,
> +				       struct intel_crtc_state *pipe_config)

I spotted this pattern in a few other places as well already, where you
add a local variable to avoid the dereference dance again. But this is
called from a pre_enable hook, i.e. we can just directly access
crtc->state to get at the right pipe config. If you instead pass it as a
parameter I have to hunt around to make sure it's the right one.

Imo passing pipe_config should only be done if the code can be called in
the compute_config/check phase or in the disable phase. That then gives
reviewers a nice heads-up about the potential trickiness.
-Daniel

>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_device *dev = dig_port->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_crtc *crtc = dig_port->base.base.crtc;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
>  	lockdep_assert_held(&dev_priv->psr.lock);
>  	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> @@ -307,14 +308,14 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
>  	}
>  
>  	if (IS_HASWELL(dev) &&
> -	    I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config->cpu_transcoder)) &
> +	    I915_READ(HSW_STEREO_3D_CTL(pipe_config->cpu_transcoder)) &
>  		      S3D_ENABLE) {
>  		DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
>  		return false;
>  	}
>  
>  	if (IS_HASWELL(dev) &&
> -	    intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> +	    pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
>  		DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
>  		return false;
>  	}
> @@ -364,6 +365,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  	struct drm_device *dev = intel_dig_port->base.base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
>  
>  	if (!HAS_PSR(dev)) {
>  		DRM_DEBUG_KMS("PSR not supported on this platform\n");
> @@ -381,7 +384,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  		goto unlock;
>  	}
>  
> -	if (!intel_psr_match_conditions(intel_dp))
> +	if (!intel_psr_match_conditions(intel_dp, pipe_config))
>  		goto unlock;
>  
>  	dev_priv->psr.busy_frontbuffer_bits = 0;
> @@ -391,8 +394,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
>  
>  		if (dev_priv->psr.psr2_support) {
>  			/* PSR2 is restricted to work with panel resolutions upto 3200x2000 */
> -			if (crtc->config->pipe_src_w > 3200 ||
> -				crtc->config->pipe_src_h > 2000)
> +			if (pipe_config->pipe_src_w > 3200 ||
> +				pipe_config->pipe_src_h > 2000)
>  				dev_priv->psr.psr2_support = false;
>  			else
>  				skl_psr_setup_su_vsc(intel_dp);
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c
  2015-05-11 14:25 ` [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c Maarten Lankhorst
@ 2015-05-12  9:22   ` Daniel Vetter
  2015-05-12 13:43     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:22 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:03PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++---------------
>  1 file changed, 18 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index eda1b22c3111..e6876faca7f0 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1536,7 +1536,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	enum port port = dp_to_dig_port(intel_dp)->port;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> -	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
> +	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>  
>  	/*
>  	 * There are four kinds of DP registers:
> @@ -1564,7 +1566,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
>  	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
>  	intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
>  
> -	if (crtc->config->has_audio)
> +	if (pipe_config->has_audio)
>  		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
>  
>  	/* Split out the IBX/CPU vs CPT settings */
> @@ -2504,6 +2506,8 @@ static void intel_enable_dp(struct intel_encoder *encoder)
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
>  	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
>  	unsigned int lane_mask = 0x0;
>  
> @@ -2532,7 +2536,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
>  	intel_dp_complete_link_train(intel_dp);
>  	intel_dp_stop_link_train(intel_dp);
>  
> -	if (crtc->config->has_audio) {
> +	if (pipe_config->has_audio) {
>  		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
>  				 pipe_name(crtc->pipe));
>  		intel_audio_codec_enable(encoder);
> @@ -2741,6 +2745,8 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>  	struct intel_crtc *intel_crtc =
>  		to_intel_crtc(encoder->base.crtc);
>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
>  	int pipe = intel_crtc->pipe;
>  	int data, i, stagger;
>  	u32 val;
> @@ -2782,13 +2788,13 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>  	}
>  
>  	/* Data lane stagger programming */
> -	if (intel_crtc->config->port_clock > 270000)
> +	if (pipe_config->port_clock > 270000)
>  		stagger = 0x18;
> -	else if (intel_crtc->config->port_clock > 135000)
> +	else if (pipe_config->port_clock > 135000)
>  		stagger = 0xd;
> -	else if (intel_crtc->config->port_clock > 67500)
> +	else if (pipe_config->port_clock > 67500)
>  		stagger = 0x7;
> -	else if (intel_crtc->config->port_clock > 33750)
> +	else if (pipe_config->port_clock > 33750)
>  		stagger = 0x4;
>  	else
>  		stagger = 0x2;
> @@ -4302,7 +4308,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
>  	if (WARN_ON(!intel_encoder->base.crtc))
>  		return;
>  
> -	if (!to_intel_crtc(intel_encoder->base.crtc)->active)
> +	if (!intel_encoder->base.crtc->state->active)
>  		return;
>  
>  	/* Try to read receiver status if the link appears to be up */
> @@ -5255,7 +5261,8 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  	struct intel_encoder *encoder;
>  	struct intel_digital_port *dig_port = NULL;
>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> -	struct intel_crtc *intel_crtc = NULL;
> +	struct intel_crtc *intel_crtc;
> +	struct intel_crtc_state *pipe_config;
>  	u32 reg, val;
>  	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
>  
> @@ -5277,6 +5284,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)

set_drrs_state is also called from _disable hooks, which means you need to
pass the right pipe_config explicitly.
-Daniel

>  	dig_port = dp_to_dig_port(intel_dp);
>  	encoder = &dig_port->base;
>  	intel_crtc = to_intel_crtc(encoder->base.crtc);
> +	pipe_config = to_intel_crtc_state(intel_crtc->base.state);
>  
>  	if (!intel_crtc) {
>  		DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
> @@ -5298,11 +5306,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  		return;
>  	}
>  
> -	if (!intel_crtc->active) {
> -		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
> -		return;
> -	}
> -
>  	if (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev)) {
>  		switch (index) {
>  		case DRRS_HIGH_RR:
> @@ -5316,7 +5319,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  			DRM_ERROR("Unsupported refreshrate type\n");
>  		}
>  	} else if (INTEL_INFO(dev)->gen > 6) {
> -		reg = PIPECONF(intel_crtc->config->cpu_transcoder);
> +		reg = PIPECONF(pipe_config->cpu_transcoder);
>  		val = I915_READ(reg);
>  
>  		if (index > DRRS_HIGH_RR) {
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c
  2015-05-11 14:25 ` [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c Maarten Lankhorst
@ 2015-05-12  9:26   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:26 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:06PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hdmi.c | 58 +++++++++++++++++++++++----------------
>  1 file changed, 35 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 76994dc033a3..9efc3dd62a00 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -345,14 +345,15 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
>  	const uint32_t *data = frame;
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> -	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(encoder->crtc->state);
> +	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
>  	u32 data_reg;
>  	int i;
>  	u32 val = I915_READ(ctl_reg);
>  
>  	data_reg = hsw_infoframe_data_reg(type,
> -					  intel_crtc->config->cpu_transcoder,
> +					  pipe_config->cpu_transcoder,
>  					  dev_priv);
>  	if (data_reg == 0)
>  		return;
> @@ -380,7 +381,9 @@ static bool hsw_infoframe_enabled(struct drm_encoder *encoder)

infoframe_enabled functions are called from get_config, which has a
passed-in pipe_config. You need to pass this one down.

That's a good example for why I think the commit message should summarize
why each change was ok and in what calling context it's done (since they
all require different conversions). And perhaps also split up patches not
along source-files only but also along stages and calling contexts.

Yep even more patches but this stuff is really tricky imo.
-Daniel

>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> -	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
> +	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
>  	u32 val = I915_READ(ctl_reg);
>  
>  	return val & (VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_SPD_HSW |
> @@ -430,7 +433,8 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
>  					 struct drm_display_mode *adjusted_mode)
>  {
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(encoder->crtc->state);
>  	union hdmi_infoframe frame;
>  	int ret;
>  
> @@ -445,7 +449,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
>  	}
>  
>  	if (intel_hdmi->rgb_quant_range_selectable) {
> -		if (intel_crtc->config->limited_color_range)
> +		if (pipe_config->limited_color_range)
>  			frame.avi.quantization_range =
>  				HDMI_QUANTIZATION_RANGE_LIMITED;
>  		else
> @@ -679,9 +683,10 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
>  			       struct drm_display_mode *adjusted_mode)
>  {
>  	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(encoder->crtc->state);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> -	u32 reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder);
> +	u32 reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
>  	u32 val = I915_READ(reg);
>  
>  	assert_hdmi_port_disabled(intel_hdmi);
> @@ -709,7 +714,9 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> -	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
> +	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>  	u32 hdmi_val;
>  
>  	hdmi_val = SDVO_ENCODING_HDMI;
> @@ -720,12 +727,12 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
>  		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
>  
> -	if (crtc->config->pipe_bpp > 24)
> +	if (pipe_config->pipe_bpp > 24)
>  		hdmi_val |= HDMI_COLOR_FORMAT_12bpc;
>  	else
>  		hdmi_val |= SDVO_COLOR_FORMAT_8bpc;
>  
> -	if (crtc->config->has_hdmi_sink)
> +	if (pipe_config->has_hdmi_sink)
>  		hdmi_val |= HDMI_MODE_SELECT_HDMI;
>  
>  	if (HAS_PCH_CPT(dev))
> @@ -819,11 +826,13 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	u32 temp;
>  	u32 enable_bits = SDVO_ENABLE;
>  
> -	if (intel_crtc->config->has_audio)
> +	if (pipe_config->has_audio)
>  		enable_bits |= SDVO_AUDIO_ENABLE;
>  
>  	temp = I915_READ(intel_hdmi->hdmi_reg);
> @@ -854,8 +863,8 @@ static void intel_enable_hdmi(struct intel_encoder *encoder)
>  		POSTING_READ(intel_hdmi->hdmi_reg);
>  	}
>  
> -	if (intel_crtc->config->has_audio) {
> -		WARN_ON(!intel_crtc->config->has_hdmi_sink);
> +	if (pipe_config->has_audio) {
> +		WARN_ON(!pipe_config->has_hdmi_sink);
>  		DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
>  				 pipe_name(intel_crtc->pipe));
>  		intel_audio_codec_enable(encoder);
> @@ -1267,14 +1276,15 @@ done:
>  static void intel_hdmi_pre_enable(struct intel_encoder *encoder)
>  {
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(encoder->base.crtc->state);
>  	struct drm_display_mode *adjusted_mode =
> -		&intel_crtc->config->base.adjusted_mode;
> +		&pipe_config->base.adjusted_mode;
>  
>  	intel_hdmi_prepare(encoder);
>  
>  	intel_hdmi->set_infoframes(&encoder->base,
> -				   intel_crtc->config->has_hdmi_sink,
> +				   pipe_config->has_hdmi_sink,
>  				   adjusted_mode);
>  }
>  
> @@ -1286,8 +1296,10 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc =
>  		to_intel_crtc(encoder->base.crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(intel_crtc->base.state);
>  	struct drm_display_mode *adjusted_mode =
> -		&intel_crtc->config->base.adjusted_mode;
> +		&pipe_config->base.adjusted_mode;
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	int pipe = intel_crtc->pipe;
>  	u32 val;
> @@ -1319,7 +1331,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	mutex_unlock(&dev_priv->dpio_lock);
>  
>  	intel_hdmi->set_infoframes(&encoder->base,
> -				   intel_crtc->config->has_hdmi_sink,
> +				   pipe_config->has_hdmi_sink,
>  				   adjusted_mode);
>  
>  	intel_enable_hdmi(encoder);
> @@ -1531,13 +1543,13 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
>  	}
>  
>  	/* Data lane stagger programming */
> -	if (intel_crtc->config->port_clock > 270000)
> +	if (pipe_config->port_clock > 270000)
>  		stagger = 0x18;
> -	else if (intel_crtc->config->port_clock > 135000)
> +	else if (pipe_config->port_clock > 135000)
>  		stagger = 0xd;
> -	else if (intel_crtc->config->port_clock > 67500)
> +	else if (pipe_config->port_clock > 67500)
>  		stagger = 0x7;
> -	else if (intel_crtc->config->port_clock > 33750)
> +	else if (pipe_config->port_clock > 33750)
>  		stagger = 0x4;
>  	else
>  		stagger = 0x2;
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 32/42] drm/i915: Calculate haswell plane workaround.
  2015-05-11 14:25 ` [PATCH 32/42] drm/i915: Calculate haswell plane workaround Maarten Lankhorst
@ 2015-05-12  9:43   ` Daniel Vetter
  2015-05-12 14:05     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:08PM +0200, Maarten Lankhorst wrote:
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 109 +++++++++++++++++++++++++----------
>  drivers/gpu/drm/i915/intel_drv.h     |   2 +
>  2 files changed, 81 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 7bc78b49f9f4..7a79659dca00 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4848,35 +4848,6 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
>  	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
>  }
>  
> -/*
> - * This implements the workaround described in the "notes" section of the mode
> - * set sequence documentation. When going from no pipes or single pipe to
> - * multiple pipes, and planes are enabled after the pipe, we need to wait at
> - * least 2 vblanks on the first pipe before enabling planes on the second pipe.
> - */
> -static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->base.dev;
> -	struct intel_crtc *crtc_it, *other_active_crtc = NULL;
> -
> -	/* We want to get the other_active_crtc only if there's only 1 other
> -	 * active crtc. */
> -	for_each_intel_crtc(dev, crtc_it) {
> -		if (!crtc_it->active || crtc_it == crtc)
> -			continue;
> -
> -		if (other_active_crtc)
> -			return;
> -
> -		other_active_crtc = crtc_it;
> -	}
> -	if (!other_active_crtc)
> -		return;
> -
> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
> -}
> -
>  static void haswell_crtc_enable(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -4967,7 +4938,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  
>  	/* If we change the relative order between pipe/planes enabling, we need
>  	 * to change the workaround. */
> -	haswell_mode_set_planes_workaround(intel_crtc);
> +	if (pipe_config->hsw_workaround_pipe != INVALID_PIPE) {
> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
> +	}
>  }
>  
>  static void ironlake_pfit_disable(struct intel_crtc *crtc)
> @@ -12147,6 +12121,74 @@ done:
>  	return ret;
>  }
>  
> +/*
> + * This implements the workaround described in the "notes" section of the mode
> + * set sequence documentation. When going from no pipes or single pipe to
> + * multiple pipes, and planes are enabled after the pipe, we need to wait at
> + * least 2 vblanks on the first pipe before enabling planes on the second pipe.
> + */
> +static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
> +{
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	struct intel_crtc_state *first_crtc_state = NULL, *other_crtc_state = NULL;
> +	struct intel_crtc *intel_crtc, *first_crtc = NULL, *enabled_crtc;
> +	int enabled_crtcs = 0, ret, i;
> +
> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> +		struct intel_crtc_state *pipe_config =
> +			to_intel_crtc_state(crtc_state);
> +
> +		pipe_config->hsw_workaround_pipe = INVALID_PIPE;

This kind of state resetting should be done in duplicate_state.

> +
> +		if (!crtc_state->active)
> +			continue;
> +
> +		if (!needs_modeset(crtc_state)) {
> +			enabled_crtcs++;
> +			enabled_crtc = to_intel_crtc(crtc);
> +			continue;
> +		}
> +
> +		if (first_crtc) {
> +			other_crtc_state = pipe_config;
> +			break;
> +		}
> +		first_crtc = to_intel_crtc(crtc);
> +		first_crtc_state = pipe_config;
> +	}
> +
> +	/* No workaround needed? */
> +	if (!first_crtc || enabled_crtcs > 1)
> +		return 0;
> +
> +	for_each_intel_crtc(state->dev, intel_crtc) {
> +		if (state->crtcs[drm_crtc_index(&intel_crtc->base)])
> +			continue;
> +
> +		ret = drm_modeset_lock(&intel_crtc->base.mutex,
> +				       state->acquire_ctx);
> +		if (ret)
> +			return ret;
> +
> +		if (!intel_crtc->base.state->active)
> +			continue;

Imo just unconditionally acquire the crtc state, there' shouldn't be any
harm in that (as long as we leave mode/active/planes_changed untouched).

> +
> +		/* 2 enabled crtcs means no need for w/a */
> +		if (++enabled_crtcs >= 2)
> +			return 0;
> +
> +		enabled_crtc = intel_crtc;
> +	}
> +
> +	if (enabled_crtcs == 1)
> +		first_crtc_state->hsw_workaround_pipe = enabled_crtc->pipe;

first_crtc_state could be miscomputed if 1 crtc is already on and you add
another one. Then first_crtc will point at the other crtc since that's the
only one at first in the atomic set. Imo a simpler algo would be:

1. Check whether your activating any crtc at all.
2. If so add all crtc states.
3. Same loop as the old one, just using for_each_crtc_in_state.

There's other cases with shared resources where we need to grab all crtc
locks already anyway (shared dpll), trying to be clever doesn't seem
beneficial. And if this indeed becomes a problem then we need a global
state ww mutex and use that (instead of crtc locks) for this book-keeping:
First enable crtc would set global_state->hsw_wa_pipe, 2nd and later would
clear it. We might need this eventually (I've heard rumours about people
not liking stalls when unplugging external screens that much), but let's
not overcomplicate things while we do this conversion.
-Daniel

> +	else if (other_crtc_state)
> +		other_crtc_state->hsw_workaround_pipe = first_crtc->pipe;
> +
> +	return 0;
> +}
> +
>  /* Code that should eventually be part of atomic_check() */
>  static int __intel_set_mode_checks(struct drm_atomic_state *state)
>  {
> @@ -12158,6 +12200,13 @@ static int __intel_set_mode_checks(struct drm_atomic_state *state)
>  		return -EINVAL;
>  	}
>  
> +	if (IS_HASWELL(state->dev)) {
> +		ret = haswell_mode_set_planes_workaround(state);
> +
> +		if (ret)
> +			return ret;
> +	}
> +
>  	/*
>  	 * See if the config requires any additional preparation, e.g.
>  	 * to adjust global state with pipes off.  We need to do this
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index eb87f82b5aff..6c2ba5dbcd79 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -437,6 +437,8 @@ struct intel_crtc_state {
>  	int pbn;
>  
>  	struct intel_crtc_scaler_state scaler_state;
> +
> +	enum pipe hsw_workaround_pipe;
>  };
>  
>  struct intel_pipe_wm {
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-11 14:25 ` [PATCH 33/42] drm/i915: remove crtc->active tracking completely Maarten Lankhorst
@ 2015-05-12  9:55   ` Daniel Vetter
  2015-05-12 10:03   ` Daniel Vetter
  1 sibling, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12  9:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:09PM +0200, Maarten Lankhorst wrote:
> Small behavioral change: DPLL_DVO_2X_MODE may stay enabled during modeset
> for I830 if new state requires it, instead of being disabled and enabled
> again.

Imo this should be split in the remaing changes to get rid of ->active and
then the actual removal.

> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 140 ++++++++++-------------------------
>  drivers/gpu/drm/i915/intel_drv.h     |   6 --
>  2 files changed, 40 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 7a79659dca00..004067bd0b6c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1680,7 +1680,7 @@ static int intel_num_dvo_pipes(struct drm_device *dev)
>  	int count = 0;
>  
>  	for_each_intel_crtc(dev, crtc)
> -		count += crtc->active &&
> +		count += crtc->base.state->active &&
>  			intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO);
>  
>  	return count;
> @@ -1703,7 +1703,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
>  		assert_panel_unlocked(dev_priv, crtc->pipe);
>  
>  	/* Enable DVO 2x clock on both PLLs if necessary */
> -	if (IS_I830(dev) && intel_num_dvo_pipes(dev) > 0) {
> +	if (IS_I830(dev) && intel_num_dvo_pipes(dev)) {
>  		/*
>  		 * It appears to be important that we don't enable this
>  		 * for the current pipe before otherwise configuring the
> @@ -1762,7 +1762,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc,
>  	/* Disable DVO 2x clock on both PLLs if necessary */
>  	if (IS_I830(dev) &&
>  	    intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) &&
> -	    intel_num_dvo_pipes(dev) == 1) {
> +	    !intel_num_dvo_pipes(dev)) {

The super-correct fix would be to pass the old_state around and use those
connectors. Probably not worth the trouble.

>  		I915_WRITE(DPLL(PIPE_B),
>  			   I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE);
>  		I915_WRITE(DPLL(PIPE_A),
> @@ -2583,7 +2583,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  		if (c == &intel_crtc->base)
>  			continue;
>  
> -		if (!i->active)
> +		if (!c->state->active)
>  			continue;
>  
>  		fb = c->primary->fb;
> @@ -3167,11 +3167,9 @@ static void intel_update_primary_planes(struct drm_device *dev)
>  	struct drm_crtc *crtc;
>  
>  	for_each_crtc(dev, crtc) {
> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
>  		drm_modeset_lock(&crtc->mutex, NULL);
>  
> -		if (intel_crtc->active) {
> +		if (crtc->state->active) {
>  			const struct intel_plane_state *state =
>  				to_intel_plane_state(crtc->primary->state);
>  
> @@ -4619,7 +4617,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
>  	bool reenable_ips = false;
>  
>  	/* The clocks have to be on to load the palette. */
> -	if (!crtc->state->active || !intel_crtc->active)
> +	if (!crtc->state->active)
>  		return;
>  
>  	if (HAS_GMCH_DISPLAY(dev_priv->dev)) {
> @@ -4778,10 +4776,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  	int pipe = intel_crtc->pipe;
>  	struct intel_crtc_state *pipe_config;
>  
> -	WARN_ON(!crtc->state->enable);
> +	WARN_ON(!crtc->state->active);
>  
> -	if (WARN_ON(intel_crtc->active))
> -		return;
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  
>  	if (pipe_config->has_pch_encoder)
> @@ -4799,8 +4795,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  
>  	ironlake_set_pipeconf(crtc);
>  
> -	intel_crtc->active = true;
> -
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
>  
> @@ -4808,7 +4802,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  		if (encoder->pre_enable)
>  			encoder->pre_enable(encoder);
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (pipe_config->has_pch_encoder) {

Misplace hunk?

>  		/* Note: FDI PLL enabling _must_ be done before we enable the
>  		 * cpu pipes, hence this is separate from all the other fdi/pch
>  		 * enabling. */
> @@ -4859,9 +4853,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  
>  	WARN_ON(!crtc->state->enable);
>  
> -	if (WARN_ON(intel_crtc->active))
> -		return;
> -
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  	if (intel_crtc_to_shared_dpll(intel_crtc))
>  		intel_enable_shared_dpll(intel_crtc);
> @@ -4885,8 +4876,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  
>  	intel_set_pipe_csc(crtc);
>  
> -	intel_crtc->active = true;
> -
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->pre_enable)
> @@ -5743,8 +5732,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  
>  	WARN_ON(!crtc->state->active);
>  
> -	if (WARN_ON(intel_crtc->active))
> -		return;
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  
>  	is_dsi = intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DSI);
> @@ -5770,8 +5757,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  
>  	i9xx_set_pipeconf(intel_crtc);
>  
> -	intel_crtc->active = true;
> -
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
> @@ -5824,9 +5809,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  	WARN_ON(!pipe_config->base.active);
>  
> -	if (WARN_ON(intel_crtc->active))
> -		return;
> -
>  	i9xx_set_pll_dividers(intel_crtc);
>  
>  	if (intel_crtc->config->has_dp_encoder)
> @@ -5836,8 +5818,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  
>  	i9xx_set_pipeconf(intel_crtc);
>  
> -	intel_crtc->active = true;
> -
>  	if (!IS_GEN2(dev))
>  		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  
> @@ -5930,7 +5910,7 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  	struct drm_atomic_state *state;
>  	int ret;
>  
> -	if (enable == intel_crtc->active)
> +	if (enable == crtc->state->active)
>  		return;
>  
>  	if (enable && !crtc->state->enable)
> @@ -6045,9 +6025,9 @@ static void intel_connector_check_state(struct intel_connector *connector)
>  
>  			crtc = encoder->base.crtc;
>  
> -			I915_STATE_WARN(!crtc->state->active,
> +			I915_STATE_WARN(!crtc->state->enable,
>  					"crtc not enabled\n");
> -			I915_STATE_WARN(!to_intel_crtc(crtc)->active, "crtc not active\n");
> +			I915_STATE_WARN(!crtc->state->active, "crtc not active\n");
>  			I915_STATE_WARN(pipe != to_intel_crtc(crtc)->pipe,
>  			     "encoder active on the wrong pipe\n");
>  		}
> @@ -8798,7 +8778,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
>  	struct intel_crtc *crtc;
>  
>  	for_each_intel_crtc(dev, crtc)
> -		I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
> +		I915_STATE_WARN(crtc->base.state->active, "CRTC for pipe %c enabled\n",
>  		     pipe_name(crtc->pipe));
>  
>  	I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n");
> @@ -11738,7 +11718,7 @@ static void check_wm_state(struct drm_device *dev)
>  		struct skl_ddb_entry *hw_entry, *sw_entry;
>  		const enum pipe pipe = intel_crtc->pipe;
>  
> -		if (!intel_crtc->active)
> +		if (!intel_crtc->base.state->active)
>  			continue;
>  
>  		/* planes */
> @@ -11871,9 +11851,6 @@ check_crtc_state(struct drm_device *dev)
>  		DRM_DEBUG_KMS("[CRTC:%d]\n",
>  			      crtc->base.base.id);
>  
> -		I915_STATE_WARN(crtc->active && !crtc->base.state->enable,
> -		     "active crtc, but not enabled in sw tracking\n");
> -
>  		for_each_intel_encoder(dev, encoder) {
>  			if (encoder->base.crtc != &crtc->base)
>  				continue;
> @@ -11882,9 +11859,9 @@ check_crtc_state(struct drm_device *dev)
>  				active = true;
>  		}
>  
> -		I915_STATE_WARN(active != crtc->active,
> +		I915_STATE_WARN(active != crtc->base.state->active,
>  		     "crtc's computed active state doesn't match tracked active state "
> -		     "(expected %i, found %i)\n", active, crtc->active);
> +		     "(expected %i, found %i)\n", active, crtc->base.state->active);
>  		I915_STATE_WARN(enabled != crtc->base.state->enable,
>  		     "crtc's computed enabled state doesn't match tracked enabled state "
>  		     "(expected %i, found %i)\n", enabled,
> @@ -11896,7 +11873,7 @@ check_crtc_state(struct drm_device *dev)
>  		/* hw state is inconsistent with the pipe quirk */
>  		if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
>  		    (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
> -			active = crtc->active;
> +			active = crtc->base.state->active;
>  
>  		for_each_intel_encoder(dev, encoder) {
>  			enum pipe pipe;
> @@ -11906,9 +11883,9 @@ check_crtc_state(struct drm_device *dev)
>  				encoder->get_config(encoder, &pipe_config);
>  		}
>  
> -		I915_STATE_WARN(crtc->active != active,
> +		I915_STATE_WARN(crtc->base.state->active != active,
>  		     "crtc active state doesn't match with hw state "
> -		     "(expected %i, found %i)\n", crtc->active, active);
> +		     "(expected %i, found %i)\n", crtc->base.state->active, active);
>  
>  		if (active &&
>  		    !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
> @@ -11931,7 +11908,7 @@ check_shared_dpll_state(struct drm_device *dev)
>  
>  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> -		int enabled_crtcs = 0, active_crtcs = 0;
> +		int active_crtcs = 0;
>  		bool active;
>  
>  		memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
>  
>  		for_each_intel_crtc(dev, crtc) {
>  			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> -				enabled_crtcs++;
> -			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
>  				active_crtcs++;
>  		}
>  		I915_STATE_WARN(pll->active != active_crtcs,
>  		     "pll active crtcs mismatch (expected %i, found %i)\n",
>  		     pll->active, active_crtcs);
> -		I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
> +		I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
>  		     "pll enabled crtcs mismatch (expected %i, found %i)\n",
> -		     hweight32(pll->config.crtc_mask), enabled_crtcs);
> +		     hweight32(pll->config.crtc_mask), active_crtcs);
>  
>  		I915_STATE_WARN(pll->on && memcmp(&pll->config.hw_state, &dpll_hw_state,
>  				       sizeof(dpll_hw_state)),
> @@ -12264,10 +12239,10 @@ static void __intel_set_mode_update_planes(struct drm_device *dev,
>  		to_intel_plane_state(plane->state)->hw_enabled = false;
>  		DRM_DEBUG_ATOMIC("Plane %i is visible: %i\n", i, visible);
>  
> -		if (!visible)
> +		if (crtc && needs_modeset(crtc->state))
> +			intel_plane->disable_plane(plane, crtc, !visible);
> +		else if (!visible)
>  			funcs->atomic_update(plane, old_plane_state);
> -		else if (needs_modeset(crtc->state))
> -			intel_plane->disable_plane(plane, crtc, true);
>  	}
>  }
>  
> @@ -12349,8 +12324,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>  		dev_priv->display.crtc_disable(crtc, pipe_config);
>  
> -		intel_crtc->active = false;
> -
>  		if (intel_crtc_to_shared_dpll(intel_crtc))
>  			intel_disable_shared_dpll(intel_crtc);
>  	}
> @@ -13035,11 +13008,9 @@ static int intel_atomic_check_crtc(struct drm_crtc *crtc,
>  	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
>  	intel_crtc->atomic.update_wm = mode_changed;
>  	intel_crtc->atomic.disable_fbc = mode_changed;
> +	intel_crtc->atomic.evade = !mode_changed && was_crtc_enabled;
>  
>  	idx = crtc->base.id;
> -	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
> -		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
> -		idx, crtc->state->active, intel_crtc->active);
>  
>  	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
>  			 idx, was_crtc_enabled, is_crtc_enabled);
> @@ -13229,7 +13200,7 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
>  	intel_runtime_pm_get(dev_priv);
>  
>  	/* Perform vblank evasion around commit operation */
> -	if (intel_crtc->active && !needs_modeset(crtc->state) &&
> +	if (intel_crtc->atomic.evade &&
>  	    !dev_priv->power_domains.init_power_on)
>  		intel_crtc->atomic.evade =
>  			intel_pipe_update_start(intel_crtc,
> @@ -14537,7 +14508,7 @@ void intel_modeset_init(struct drm_device *dev)
>  	drm_modeset_unlock_all(dev);
>  
>  	for_each_intel_crtc(dev, crtc) {
> -		if (!crtc->active)
> +		if (!crtc->base.state->active)
>  			continue;
>  
>  		/*
> @@ -14615,7 +14586,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  
>  	/* restore vblank interrupts to correct state */
>  	drm_crtc_vblank_reset(&crtc->base);
> -	if (crtc->active) {
> +	if (crtc->base.state->active) {
>  		update_scanline_offset(crtc);
>  		drm_crtc_vblank_on(&crtc->base);
>  	}
> @@ -14655,14 +14626,14 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  				connector->encoder->connectors_active = false;
>  			}
>  
> -		WARN_ON(crtc->active);
> +		WARN_ON(crtc->base.state->active);
>  		crtc->base.state->enable = false;
>  		crtc->base.state->active = false;
>  		crtc->base.enabled = false;
>  	}
>  
>  	if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
> -	    crtc->pipe == PIPE_A && !crtc->active) {
> +	    crtc->pipe == PIPE_A && !crtc->base.state->active) {
>  		/* BIOS forgot to enable pipe A, this mostly happens after
>  		 * resume. Force-enable the pipe to fix this, the update_dpms
>  		 * call below we restore the pipe to the right state, but leave
> @@ -14674,35 +14645,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  	 * have active connectors/encoders. */
>  	intel_crtc_update_dpms(&crtc->base);
>  
> -	if (crtc->active != crtc->base.state->active) {
> -		struct intel_encoder *encoder;
> -
> -		/* This can happen either due to bugs in the get_hw_state
> -		 * functions or because the pipe is force-enabled due to the
> -		 * pipe A quirk. */
> -		DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n",
> -			      crtc->base.base.id,
> -			      crtc->base.state->enable ? "enabled" : "disabled",
> -			      crtc->active ? "enabled" : "disabled");
> -
> -		crtc->base.state->enable = crtc->active;
> -		crtc->base.state->active = crtc->active;
> -		crtc->base.enabled = crtc->active;
> -
> -		/* Because we only establish the connector -> encoder ->
> -		 * crtc links if something is active, this means the
> -		 * crtc is now deactivated. Break the links. connector
> -		 * -> encoder links are only establish when things are
> -		 *  actually up, hence no need to break them. */
> -		WARN_ON(crtc->active);
> -
> -		for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
> -			WARN_ON(encoder->connectors_active);
> -			encoder->base.crtc = NULL;
> -		}
> -	}

I don't think you can nuke this. Essentially we have two bits here:
- is the pipe enabled (bit31 in pipeconf)?
- is any encoder using this pipe and enabled?

The later is computed/updated in intel_crtc_update_dpms. I'm not sure
where exactly, but something in these pile of changes might have broken
this.

If not I think it should be extracted into a separate patch together with
the other changes (to intel_crtc_control maybe?) to make it easier to
follow why this code isn't needed any more. At least silently removing
code with scary comments without explaining why it's dead now (and without
moving the comments to the new places) isn't good.
-Daniel

> -
> -	if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
> +	if (crtc->base.state->active || HAS_GMCH_DISPLAY(dev)) {
>  		/*
>  		 * We start out with underrun reporting disabled to avoid races.
>  		 * For correct bookkeeping mark this on active crtcs.
> @@ -14730,7 +14673,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
>  	/* We need to check both for a crtc link (meaning that the
>  	 * encoder is active and trying to read from a pipe) and the
>  	 * pipe itself being active. */
> -	bool has_active_crtc = crtc && to_intel_crtc(crtc)->active;
> +	bool has_active_crtc = crtc && crtc->state->active;
>  
>  	if (encoder->connectors_active && !has_active_crtc) {
>  		DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n",
> @@ -14800,7 +14743,7 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
>  {
>  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>  
> -	if (!crtc->active)
> +	if (!crtc->base.state->active)
>  		return false;
>  
>  	return I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE;
> @@ -14828,12 +14771,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  		if (crtc->base.state->active)
>  			*crtc_mask |= drm_crtc_index(&crtc->base);
>  
> -		crtc->active = dev_priv->display.get_pipe_config(crtc,
> -								 crtc->config);
> -
> -		crtc->base.state->enable = crtc->active;
> -		crtc->base.state->active = crtc->active;
> -		crtc->base.enabled = crtc->active;
> +		crtc->base.enabled = crtc->base.state->enable =
> +		crtc->base.state->active =
> +			dev_priv->display.get_pipe_config(crtc, crtc->config);
>  
>  		plane_state = to_intel_plane_state(primary->state);
>  		plane_state->hw_enabled = plane_state->visible =
> @@ -14847,7 +14787,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  
>  		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
>  			      crtc->base.base.id,
> -			      crtc->active ? "enabled" : "disabled");
> +			      crtc->base.state->active ? "enabled" : "disabled");
>  	}
>  
>  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> @@ -14858,7 +14798,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  		pll->active = 0;
>  		pll->config.crtc_mask = 0;
>  		for_each_intel_crtc(dev, crtc) {
> -			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) {
> +			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll) {
>  				pll->active++;
>  				pll->config.crtc_mask |= 1 << crtc->pipe;
>  			}
> @@ -14927,9 +14867,9 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>  	 * checking everywhere.
>  	 */
>  	for_each_intel_crtc(dev, crtc) {
> -		if (crtc->active && i915.fastboot) {
> +		if (crtc->base.state->active && i915.fastboot) {
>  			intel_mode_from_pipe_config(&crtc->base.mode,
> -						    crtc->config);
> +				to_intel_crtc_state(crtc->base.state));
>  			DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
>  				      crtc->base.base.id);
>  			drm_mode_debug_printmodeline(&crtc->base.mode);
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 6c2ba5dbcd79..1a0b0cd857c3 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -492,12 +492,6 @@ struct intel_crtc {
>  	enum pipe pipe;
>  	enum plane plane;
>  	u8 lut_r[256], lut_g[256], lut_b[256];
> -	/*
> -	 * Whether the crtc and the connected output pipeline is active. Implies
> -	 * that crtc->enabled is set, i.e. the current mode configuration has
> -	 * some outputs connected to this crtc.
> -	 */
> -	bool active;
>  	unsigned long enabled_power_domains;
>  	bool lowfreq_avail;
>  	struct intel_overlay *overlay;
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-11 14:25 ` [PATCH 33/42] drm/i915: remove crtc->active tracking completely Maarten Lankhorst
  2015-05-12  9:55   ` Daniel Vetter
@ 2015-05-12 10:03   ` Daniel Vetter
  2015-05-12 14:07     ` Maarten Lankhorst
  1 sibling, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 10:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 4:25 PM, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
>
>                 for_each_intel_crtc(dev, crtc) {
>                         if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> -                               enabled_crtcs++;
> -                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
>                                 active_crtcs++;
>                 }
>                 I915_STATE_WARN(pll->active != active_crtcs,
>                      "pll active crtcs mismatch (expected %i, found %i)\n",
>                      pll->active, active_crtcs);
> -               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
> +               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
>                      "pll enabled crtcs mismatch (expected %i, found %i)\n",
> -                    hweight32(pll->config.crtc_mask), enabled_crtcs);
> +                    hweight32(pll->config.crtc_mask), active_crtcs);


Missed one: Why do you remove this? Imo that's a fairly crucial
consistency check.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1
  2015-05-11 14:25 ` [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1 Maarten Lankhorst
@ 2015-05-12 10:11   ` Daniel Vetter
  2015-05-12 14:13     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 10:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:10PM +0200, Maarten Lankhorst wrote:
> Removed some occurences, roughly based on where the errors of
> removing crtc->config occured. Because it's used a lot in this
> file the changes are done in passes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 205 ++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_drv.h     |   4 +-
>  drivers/gpu/drm/i915/intel_lvds.c    |   2 +-
>  3 files changed, 105 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 004067bd0b6c..fb2ecb65aaaa 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -1141,29 +1141,20 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
>  #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
>  #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
>  
> -struct intel_shared_dpll *
> -intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
> -{
> -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> -
> -	if (crtc->config->shared_dpll < 0)
> -		return NULL;
> -
> -	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
> -}
> -
>  /* For ILK+ */
>  void assert_shared_dpll(struct drm_i915_private *dev_priv,
> -			struct intel_shared_dpll *pll,
> +			enum intel_dpll_id shared_dpll,
>  			bool state)
>  {
> -	bool cur_state;
>  	struct intel_dpll_hw_state hw_state;
> +	struct intel_shared_dpll *pll;
> +	bool cur_state;
>  
> -	if (WARN (!pll,
> +	if (WARN(shared_dpll < 0,
>  		  "asserting DPLL %s with no DPLL\n", state_string(state)))
>  		return;
>  
> +	pll = &dev_priv->shared_dplls[shared_dpll];
>  	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
>  	I915_STATE_WARN(cur_state != state,
>  	     "%s assertion failure (expected %s, current %s)\n",
> @@ -1691,7 +1682,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	int reg = DPLL(crtc->pipe);
> -	u32 dpll = crtc->config->dpll_hw_state.dpll;
> +	u32 dpll = pipe_config->dpll_hw_state.dpll;

Lots of your patches are sprinkled with unrelated crtc->config ->
pipe_config conversions. Or just plain rolling out of a local variable
instead of accessing some other pointer. That makes it fairly hard to
review them for a given topic (like shared dpll here) since it's never
clear whether it really includes everything, and what's the reason for all
the other hunks.

>  
>  	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>  
> @@ -1721,7 +1712,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
>  
>  	if (INTEL_INFO(dev)->gen >= 4) {
>  		I915_WRITE(DPLL_MD(crtc->pipe),
> -			   crtc->config->dpll_hw_state.dpll_md);
> +			   pipe_config->dpll_hw_state.dpll_md);
>  	} else {
>  		/* The pixel multiplier can only be updated once the
>  		 * DPLL is enabled and the clocks are stable.
> @@ -1859,20 +1850,19 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
>  		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
>  }
>  
> -static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
> +static void intel_prepare_shared_dpll(struct drm_i915_private *dev_priv,
> +				      enum intel_dpll_id shared_dpll)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];

Why change anything here? This is called from enable hooks, so can keep on
accessing intel_crtc->state ... or not?
>  
> -	if (WARN_ON(pll == NULL))
> +	if (WARN_ON(shared_dpll < 0))
>  		return;
>  
>  	WARN_ON(!pll->config.crtc_mask);
>  	if (pll->active == 0) {
>  		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
>  		WARN_ON(pll->on);
> -		assert_shared_dpll_disabled(dev_priv, pll);
> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
>  
>  		pll->mode_set(dev_priv, pll);
>  	}
> @@ -1886,25 +1876,23 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
>   * The PCH PLL needs to be enabled before the PCH transcoder, since it
>   * drives the transcoder clock.
>   */
> -static void intel_enable_shared_dpll(struct intel_crtc *crtc)
> +static void intel_enable_shared_dpll(struct drm_i915_private *dev_priv,
> +				     enum intel_dpll_id shared_dpll)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
>  
> -	if (WARN_ON(pll == NULL))
> +	if (WARN_ON(shared_dpll < 0))
>  		return;
>  
>  	if (WARN_ON(pll->config.crtc_mask == 0))
>  		return;
>  
> -	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
> -		      pll->name, pll->active, pll->on,
> -		      crtc->base.base.id);
> +	DRM_DEBUG_KMS("enable %s (active %d, on? %d)\n",
> +		      pll->name, pll->active, pll->on);
>  
>  	if (pll->active++) {
>  		WARN_ON(!pll->on);
> -		assert_shared_dpll_enabled(dev_priv, pll);
> +		assert_shared_dpll_enabled(dev_priv, shared_dpll);
>  		return;
>  	}
>  	WARN_ON(pll->on);
> @@ -1916,30 +1904,29 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
>  	pll->on = true;
>  }
>  
> -static void intel_disable_shared_dpll(struct intel_crtc *crtc)
> +static void intel_disable_shared_dpll(struct drm_i915_private *dev_priv,
> +				      enum intel_dpll_id shared_dpll)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
> +
> +	if (shared_dpll < 0)
> +		return;
>  
>  	/* PCH only available on ILK+ */
> -	BUG_ON(INTEL_INFO(dev)->gen < 5);
> -	if (WARN_ON(pll == NULL))
> -	       return;
> +	BUG_ON(dev_priv->info.gen < 5);
>  
>  	if (WARN_ON(pll->config.crtc_mask == 0))
>  		return;
>  
> -	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
> -		      pll->name, pll->active, pll->on,
> -		      crtc->base.base.id);
> +	DRM_DEBUG_KMS("disable %s (active %d, on? %d)\n",
> +		      pll->name, pll->active, pll->on);
>  
>  	if (WARN_ON(pll->active == 0)) {
> -		assert_shared_dpll_disabled(dev_priv, pll);
> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
>  		return;
>  	}
>  
> -	assert_shared_dpll_enabled(dev_priv, pll);
> +	assert_shared_dpll_enabled(dev_priv, shared_dpll);
>  	WARN_ON(!pll->on);
>  	if (--pll->active)
>  		return;
> @@ -1964,8 +1951,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
>  	BUG_ON(!HAS_PCH_SPLIT(dev));
>  
>  	/* Make sure PCH DPLL is enabled */
> -	assert_shared_dpll_enabled(dev_priv,
> -				   intel_crtc_to_shared_dpll(intel_crtc));
> +	assert_shared_dpll_enabled(dev_priv, pipe_config->shared_dpll);
>  
>  	/* FDI must be feeding us bits for PCH ports */
>  	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
> @@ -2126,7 +2112,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
>  		else
>  			assert_pll_enabled(dev_priv, pipe);
>  	else {
> -		if (crtc->config->has_pch_encoder) {
> +		if (pipe_config->has_pch_encoder) {
>  			/* if driving the PCH, we need FDI enabled */
>  			assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
>  			assert_fdi_tx_pll_enabled(dev_priv,
> @@ -2622,6 +2608,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  	bool visible = to_intel_plane_state(primary->state)->visible;
>  	struct drm_i915_gem_object *obj;
>  	int plane = intel_crtc->plane;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> @@ -2655,13 +2643,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  		 * which should always be the user's requested size.
>  		 */
>  		I915_WRITE(DSPSIZE(plane),
> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
> -			   (intel_crtc->config->pipe_src_w - 1));
> +			   ((pipe_config->pipe_src_h - 1) << 16) |
> +			   (pipe_config->pipe_src_w - 1));
>  		I915_WRITE(DSPPOS(plane), 0);
>  	} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
>  		I915_WRITE(PRIMSIZE(plane),
> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
> -			   (intel_crtc->config->pipe_src_w - 1));
> +			   ((pipe_config->pipe_src_h - 1) << 16) |
> +			   (pipe_config->pipe_src_w - 1));
>  		I915_WRITE(PRIMPOS(plane), 0);
>  		I915_WRITE(PRIMCNSTALPHA(plane), 0);
>  	}
> @@ -2719,14 +2707,14 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
>  		dspcntr |= DISPPLANE_ROTATE_180;
>  
> -		x += (intel_crtc->config->pipe_src_w - 1);
> -		y += (intel_crtc->config->pipe_src_h - 1);
> +		x += (pipe_config->pipe_src_w - 1);
> +		y += (pipe_config->pipe_src_h - 1);
>  
>  		/* Finding the last pixel of the last line of the display
>  		data and adding to linear_offset*/
>  		linear_offset +=
> -			(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
> -			(intel_crtc->config->pipe_src_w - 1) * pixel_size;
> +			(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
> +			(pipe_config->pipe_src_w - 1) * pixel_size;

Unrelated changes above, or do I miss something?

>  	}
>  
>  	I915_WRITE(reg, dspcntr);
> @@ -2818,17 +2806,20 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  					       fb->pitches[0]);
>  	linear_offset -= intel_crtc->dspaddr_offset;
>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
> +		struct intel_crtc_state *pipe_config =
> +			to_intel_crtc_state(crtc->state);
> +
>  		dspcntr |= DISPPLANE_ROTATE_180;
>  
>  		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
> -			x += (intel_crtc->config->pipe_src_w - 1);
> -			y += (intel_crtc->config->pipe_src_h - 1);
> +			x += (pipe_config->pipe_src_w - 1);
> +			y += (pipe_config->pipe_src_h - 1);
>  
>  			/* Finding the last pixel of the last line of the display
>  			data and adding to linear_offset*/
>  			linear_offset +=
> -				(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
> -				(intel_crtc->config->pipe_src_w - 1) * pixel_size;
> +				(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
> +				(pipe_config->pipe_src_w - 1) * pixel_size;
>  		}
>  	}
>  
> @@ -2901,12 +2892,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>  	struct intel_crtc_scaler_state *scaler_state;
>  	int i;
>  
> -	if (!intel_crtc || !intel_crtc->config)
> +	if (!intel_crtc)
>  		return;
>  
>  	dev = intel_crtc->base.dev;
>  	dev_priv = dev->dev_private;
> -	scaler_state = &intel_crtc->config->scaler_state;
> +	scaler_state =
> +		&to_intel_crtc_state(intel_crtc->base.state)->scaler_state;
>  
>  	/* loop through and disable scalers that aren't in use */
>  	for (i = 0; i < intel_crtc->num_scalers; i++) {
> @@ -3298,6 +3290,8 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	const struct drm_display_mode *adjusted_mode;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->base.state);
>  
>  	if (!i915.fastboot)
>  		return;
> @@ -3316,20 +3310,20 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
>  	 * then update the pipesrc and pfit state, even on the flip path.
>  	 */
>  
> -	adjusted_mode = &crtc->config->base.adjusted_mode;
> +	adjusted_mode = &pipe_config->base.adjusted_mode;
>  
>  	I915_WRITE(PIPESRC(crtc->pipe),
>  		   ((adjusted_mode->crtc_hdisplay - 1) << 16) |
>  		   (adjusted_mode->crtc_vdisplay - 1));
> -	if (!crtc->config->pch_pfit.enabled &&
> +	if (!pipe_config->pch_pfit.enabled &&
>  	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
>  	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
>  		I915_WRITE(PF_CTL(crtc->pipe), 0);
>  		I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
>  		I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
>  	}
> -	crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
> -	crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
> +	pipe_config->pipe_src_w = adjusted_mode->crtc_hdisplay;
> +	pipe_config->pipe_src_h = adjusted_mode->crtc_vdisplay;
>  }
>  
>  static void intel_fdi_normal_train(struct drm_crtc *crtc)
> @@ -3379,6 +3373,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	int pipe = intel_crtc->pipe;
>  	u32 reg, temp, tries;
>  
> @@ -3396,7 +3392,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
>  	reg = FDI_TX_CTL(pipe);
>  	temp = I915_READ(reg);
>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>  	temp &= ~FDI_LINK_TRAIN_NONE;
>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
>  	I915_WRITE(reg, temp | FDI_TX_ENABLE);
> @@ -3476,6 +3472,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	int pipe = intel_crtc->pipe;
>  	u32 reg, temp, i, retry;
>  
> @@ -3494,7 +3492,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
>  	reg = FDI_TX_CTL(pipe);
>  	temp = I915_READ(reg);
>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>  	temp &= ~FDI_LINK_TRAIN_NONE;
>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
>  	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> @@ -3608,6 +3606,8 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	int pipe = intel_crtc->pipe;
>  	u32 reg, temp, i, j;
>  
> @@ -3645,7 +3645,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
>  		reg = FDI_TX_CTL(pipe);
>  		temp = I915_READ(reg);
>  		temp &= ~FDI_DP_PORT_WIDTH_MASK;
> -		temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> +		temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>  		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
>  		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
>  		temp |= snb_b_fdi_train_param[j/2];
> @@ -3914,11 +3914,10 @@ void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
>  }
>  
>  /* Program iCLKIP clock to the desired frequency */
> -static void lpt_program_iclkip(struct drm_crtc *crtc)
> +static void lpt_program_iclkip(struct drm_i915_private *dev_priv,
> +			       struct intel_crtc_state *pipe_config)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
> +	int clock = pipe_config->base.adjusted_mode.crtc_clock;
>  	u32 divsel, phaseinc, auxdiv, phasedir = 0;
>  	u32 temp;
>  
> @@ -4002,13 +4001,10 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
>  	mutex_unlock(&dev_priv->dpio_lock);
>  }
>  
> -static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
> +static void ironlake_pch_transcoder_set_timings(struct drm_i915_private *dev_priv,
> +						enum transcoder cpu_transcoder,
>  						enum pipe pch_transcoder)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
> -
>  	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
>  		   I915_READ(HTOTAL(cpu_transcoder)));
>  	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
> @@ -4026,7 +4022,8 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
>  		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
>  }
>  
> -static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
> +static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev,
> +				       bool enable)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	uint32_t temp;
> @@ -4047,15 +4044,15 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
>  	POSTING_READ(SOUTH_CHICKEN1);
>  }
>  
> -static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
> +static void ivybridge_update_fdi_bc_bifurcation(struct drm_device *dev,
> +					struct intel_crtc *intel_crtc,
> +					struct intel_crtc_state *pipe_config)
>  {
> -	struct drm_device *dev = intel_crtc->base.dev;
> -
>  	switch (intel_crtc->pipe) {
>  	case PIPE_A:
>  		break;
>  	case PIPE_B:
> -		if (intel_crtc->config->fdi_lanes > 2)
> +		if (pipe_config->fdi_lanes > 2)
>  			cpt_set_fdi_bc_bifurcation(dev, false);
>  		else
>  			cpt_set_fdi_bc_bifurcation(dev, true);
> @@ -4078,7 +4075,8 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
>   *   - DP transcoding bits
>   *   - transcoder
>   */
> -static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
> +static void ironlake_pch_enable(struct drm_crtc *crtc,
> +				struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -4089,7 +4087,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>  	assert_pch_transcoder_disabled(dev_priv, pipe);
>  
>  	if (IS_IVYBRIDGE(dev))
> -		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
> +		ivybridge_update_fdi_bc_bifurcation(dev, intel_crtc,
> +						    pipe_config);
>  
>  	/* Write the TU size bits before fdi link training, so that error
>  	 * detection works. */
> @@ -4121,11 +4120,12 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>  	 * Note that enable_shared_dpll tries to do the right thing, but
>  	 * get_shared_dpll unconditionally resets the pll - we need that to have
>  	 * the right LVDS enable sequence. */
> -	intel_enable_shared_dpll(intel_crtc);
> +	intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>  
>  	/* set transcoder timing, panel must allow it */
>  	assert_panel_unlocked(dev_priv, pipe);
> -	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
> +	ironlake_pch_transcoder_set_timings(dev_priv,
> +					    pipe_config->cpu_transcoder, pipe);
>  
>  	intel_fdi_normal_train(crtc);
>  
> @@ -4166,19 +4166,17 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>  	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
>  }
>  
> -static void lpt_pch_enable(struct drm_crtc *crtc)
> +static void lpt_pch_enable(struct drm_i915_private *dev_priv,
> +			   struct intel_crtc_state *pipe_config)
>  {
> -	struct drm_device *dev = crtc->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  
>  	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
>  
> -	lpt_program_iclkip(crtc);
> +	lpt_program_iclkip(dev_priv, pipe_config);
>  
>  	/* Set transcoder timing. */
> -	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
> +	ironlake_pch_transcoder_set_timings(dev_priv, cpu_transcoder, PIPE_A);
>  
>  	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
>  }
> @@ -4781,7 +4779,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  
>  	if (pipe_config->has_pch_encoder)
> -		intel_prepare_shared_dpll(intel_crtc);
> +		intel_prepare_shared_dpll(dev_priv,
> +					  pipe_config->shared_dpll);
>  
>  	if (pipe_config->has_dp_encoder)
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
> @@ -4854,8 +4853,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	WARN_ON(!crtc->state->enable);
>  
>  	pipe_config = to_intel_crtc_state(crtc->state);
> -	if (intel_crtc_to_shared_dpll(intel_crtc))
> -		intel_enable_shared_dpll(intel_crtc);
> +	if (pipe_config->shared_dpll >= 0)
> +		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>  
>  	if (pipe_config->has_dp_encoder)
>  		intel_dp_set_m_n(intel_crtc, M1_N1);
> @@ -4910,7 +4909,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	intel_enable_pipe(intel_crtc);
>  
>  	if (intel_crtc->config->has_pch_encoder)
> -		lpt_pch_enable(crtc);
> +		lpt_pch_enable(dev_priv, pipe_config);
>  
>  	if (intel_crtc->config->dp_encoder_is_mst)
>  		intel_ddi_set_vc_payload_alloc(crtc,
> @@ -11929,7 +11928,8 @@ check_shared_dpll_state(struct drm_device *dev)
>  		     pll->on, active);
>  
>  		for_each_intel_crtc(dev, crtc) {
> -			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> +			if (crtc->base.state->active &&
> +			    to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
>  				active_crtcs++;
>  		}
>  		I915_STATE_WARN(pll->active != active_crtcs,
> @@ -12311,7 +12311,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  	__intel_set_mode_update_planes(dev, state);
>  
>  	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  		struct intel_crtc_state *pipe_config;
>  
>  		if (!needs_modeset(crtc->state))
> @@ -12324,8 +12323,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>  		dev_priv->display.crtc_disable(crtc, pipe_config);
>  
> -		if (intel_crtc_to_shared_dpll(intel_crtc))
> -			intel_disable_shared_dpll(intel_crtc);
> +		intel_disable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>  	}
>  
>  	/* Only after disabling all output pipelines that will be changed can we
> @@ -12719,7 +12717,9 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
>  
>  	/* Make sure no transcoder isn't still depending on us. */
>  	for_each_intel_crtc(dev, crtc) {
> -		if (intel_crtc_to_shared_dpll(crtc) == pll)
> +		int i = pll - dev_priv->shared_dplls;
> +
> +		if (to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
>  			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
>  	}

This is called with the with the new config already put in place, but it
should check whether any of the _old_ pipe configs that used the dpll are
really all shut down. This won't misfire since if we shut it down to use
it in some other configuration then those pipes should be ofc off too.
Otoh we do check before enabling the pipe that the dpll is running, hence
I think this is redundant and maybe we could remove
it right away?
-Daniel

>  
> @@ -14798,7 +14798,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  		pll->active = 0;
>  		pll->config.crtc_mask = 0;
>  		for_each_intel_crtc(dev, crtc) {
> -			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll) {
> +			if (crtc->base.state->active &&
> +			    i == to_intel_crtc_state(crtc->base.state)->shared_dpll) {
>  				pll->active++;
>  				pll->config.crtc_mask |= 1 << crtc->pipe;
>  			}
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 1a0b0cd857c3..7979a2f6838c 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1058,10 +1058,8 @@ bool intel_wm_need_update(struct drm_plane *plane,
>  			  struct drm_plane_state *state);
>  
>  /* shared dpll functions */
> -struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
>  void assert_shared_dpll(struct drm_i915_private *dev_priv,
> -			struct intel_shared_dpll *pll,
> -			bool state);
> +			enum intel_dpll_id, bool state);
>  #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,
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 8aaaa24144f0..52788ed6f775 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -149,7 +149,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
>  	if (HAS_PCH_SPLIT(dev)) {
>  		assert_fdi_rx_pll_disabled(dev_priv, pipe);
>  		assert_shared_dpll_disabled(dev_priv,
> -					    intel_crtc_to_shared_dpll(crtc));
> +					    pipe_config->shared_dpll);
>  	} else {
>  		assert_pll_disabled(dev_priv, pipe);
>  	}
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2
  2015-05-11 14:25 ` [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2 Maarten Lankhorst
@ 2015-05-12 10:17   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 10:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:11PM +0200, Maarten Lankhorst wrote:
> Convert the rest of the file, but remove crtc->config in a separate
> commit to hopefully allow easier bisecting.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 351 ++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_dp.c      |   4 +-
>  drivers/gpu/drm/i915/intel_drv.h     |   4 +-
>  3 files changed, 186 insertions(+), 173 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index fb2ecb65aaaa..2c467cda74a4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -88,14 +88,20 @@ static int intel_framebuffer_init(struct drm_device *dev,
>  				  struct intel_framebuffer *ifb,
>  				  struct drm_mode_fb_cmd2 *mode_cmd,
>  				  struct drm_i915_gem_object *obj);
> -static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc);
> -static void intel_set_pipe_timings(struct intel_crtc *intel_crtc);
> +static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc,
> +			      struct intel_crtc_state *pipe_config);
> +static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
> +				   struct intel_crtc_state *pipe_config);
>  static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
> +					 struct intel_crtc_state *pipe_config,
>  					 struct intel_link_m_n *m_n,
>  					 struct intel_link_m_n *m2_n2);
> -static void ironlake_set_pipeconf(struct drm_crtc *crtc);
> -static void haswell_set_pipeconf(struct drm_crtc *crtc);
> -static void intel_set_pipe_csc(struct drm_crtc *crtc);
> +static void ironlake_set_pipeconf(struct drm_crtc *crtc,
> +				  struct intel_crtc_state *pipe_config);
> +static void haswell_set_pipeconf(struct drm_crtc *crtc,
> +				 struct intel_crtc_state *pipe_config);
> +static void intel_set_pipe_csc(struct drm_crtc *crtc,
> +			       struct intel_crtc_state *pipe_config);
>  static void vlv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
> @@ -3021,7 +3027,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned int rotation;
>  	int x_offset, y_offset;
>  	unsigned long surf_addr;
> -	struct intel_crtc_state *crtc_state = intel_crtc->config;
> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->state);
>  	struct intel_plane_state *plane_state;
>  	int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
>  	int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
> @@ -3052,27 +3058,17 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc,
>  					       fb->pixel_format);
>  	surf_addr = intel_plane_obj_offset(to_intel_plane(plane), obj);
>  
> -	/*
> -	 * FIXME: intel_plane_state->src, dst aren't set when transitional
> -	 * update_plane helpers are called from legacy paths.
> -	 * Once full atomic crtc is available, below check can be avoided.
> -	 */
> -	if (drm_rect_width(&plane_state->src)) {
> -		scaler_id = plane_state->scaler_id;
> -		src_x = plane_state->src.x1 >> 16;
> -		src_y = plane_state->src.y1 >> 16;
> -		src_w = drm_rect_width(&plane_state->src) >> 16;
> -		src_h = drm_rect_height(&plane_state->src) >> 16;
> -		dst_x = plane_state->dst.x1;
> -		dst_y = plane_state->dst.y1;
> -		dst_w = drm_rect_width(&plane_state->dst);
> -		dst_h = drm_rect_height(&plane_state->dst);
> +	scaler_id = plane_state->scaler_id;
> +	src_x = plane_state->src.x1 >> 16;
> +	src_y = plane_state->src.y1 >> 16;
> +	src_w = drm_rect_width(&plane_state->src) >> 16;
> +	src_h = drm_rect_height(&plane_state->src) >> 16;
> +	dst_x = plane_state->dst.x1;
> +	dst_y = plane_state->dst.y1;
> +	dst_w = drm_rect_width(&plane_state->dst);
> +	dst_h = drm_rect_height(&plane_state->dst);
>  
> -		WARN_ON(x != src_x || y != src_y);
> -	} else {
> -		src_w = intel_crtc->config->pipe_src_w;
> -		src_h = intel_crtc->config->pipe_src_h;
> -	}
> +	WARN_ON(x != src_x || y != src_y);

This needs to be a separate commit with some justification for why we now
always have an updated rect ...

>  
>  	if (intel_rotation_90_or_270(rotation)) {
>  		/* stride = Surface height in tiles */
> @@ -4489,27 +4485,29 @@ skl_update_scaler_users(
>  	return 0;
>  }
>  
> -static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
> +static void skylake_pfit_update(struct intel_crtc *crtc,

Random bikeshed while reading code: For consistency this should be called
skylake_pfit_enable.

> +				struct intel_crtc_state *pipe_config,
> +				int enable)
>  {
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	int pipe = crtc->pipe;
>  	struct intel_crtc_scaler_state *scaler_state =
> -		&crtc->config->scaler_state;
> +		&pipe_config->scaler_state;
>  
> -	DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config);
> +	DRM_DEBUG_KMS("for crtc_state = %p\n", pipe_config);
>  
>  	/* To update pfit, first update scaler state */
> -	skl_update_scaler_users(crtc, crtc->config, NULL, NULL, !enable);
> -	intel_atomic_setup_scalers(crtc->base.dev, crtc, crtc->config);
> +	skl_update_scaler_users(crtc, pipe_config, NULL, NULL, !enable);
> +	intel_atomic_setup_scalers(crtc->base.dev, crtc, pipe_config);
>  	skl_detach_scalers(crtc);
>  	if (!enable)
>  		return;
>  
> -	if (crtc->config->pch_pfit.enabled) {
> +	if (pipe_config->pch_pfit.enabled) {
>  		int id;
>  
> -		if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) {
> +		if (WARN_ON(pipe_config->scaler_state.scaler_id < 0)) {
>  			DRM_ERROR("Requesting pfit without getting a scaler first\n");
>  			return;
>  		}
> @@ -4517,20 +4515,21 @@ static void skylake_pfit_update(struct intel_crtc *crtc, int enable)
>  		id = scaler_state->scaler_id;
>  		I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN |
>  			PS_FILTER_MEDIUM | scaler_state->scalers[id].mode);
> -		I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos);
> -		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size);
> +		I915_WRITE(SKL_PS_WIN_POS(pipe, id), pipe_config->pch_pfit.pos);
> +		I915_WRITE(SKL_PS_WIN_SZ(pipe, id), pipe_config->pch_pfit.size);
>  
> -		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id);
> +		DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", pipe_config, id);
>  	}
>  }
>  
> -static void ironlake_pfit_enable(struct intel_crtc *crtc)
> +static void ironlake_pfit_enable(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;
>  	int pipe = crtc->pipe;
>  
> -	if (crtc->config->pch_pfit.enabled) {
> +	if (pipe_config->pch_pfit.enabled) {
>  		/* Force use of hard-coded filter coefficients
>  		 * as some pre-programmed values are broken,
>  		 * e.g. x201.
> @@ -4540,8 +4539,8 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
>  						 PF_PIPE_SEL_IVB(pipe));
>  		else
>  			I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
> -		I915_WRITE(PF_WIN_POS(pipe), crtc->config->pch_pfit.pos);
> -		I915_WRITE(PF_WIN_SZ(pipe), crtc->config->pch_pfit.size);
> +		I915_WRITE(PF_WIN_POS(pipe), pipe_config->pch_pfit.pos);
> +		I915_WRITE(PF_WIN_SZ(pipe), pipe_config->pch_pfit.size);
>  	}
>  }
>  
> @@ -4550,7 +4549,7 @@ 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_enabled)
> +	if (!to_intel_crtc_state(crtc->base.state)->ips_enabled)
>  		return;
>  
>  	/* We can only enable IPS after we enable a plane and wait for a vblank */
> @@ -4583,7 +4582,7 @@ 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_enabled)
> +	if (!to_intel_crtc_state(crtc->base.state)->ips_enabled)
>  		return;
>  
>  	assert_plane_enabled(dev_priv, crtc->plane);
> @@ -4632,7 +4631,7 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
>  	/* Workaround : Do not read or write the pipe palette/gamma data while
>  	 * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
>  	 */
> -	if (IS_HASWELL(dev) && intel_crtc->config->ips_enabled &&
> +	if (IS_HASWELL(dev) && to_intel_crtc_state(crtc->state)->ips_enabled &&
>  	    ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
>  	     GAMMA_MODE_MODE_SPLIT)) {
>  		hsw_disable_ips(intel_crtc);
> @@ -4783,16 +4782,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  					  pipe_config->shared_dpll);
>  
>  	if (pipe_config->has_dp_encoder)
> -		intel_dp_set_m_n(intel_crtc, M1_N1);
> +		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
>  
> -	intel_set_pipe_timings(intel_crtc);
> +	intel_set_pipe_timings(intel_crtc, pipe_config);
>  
>  	if (pipe_config->has_pch_encoder) {
> -		intel_cpu_transcoder_set_m_n(intel_crtc,
> +		intel_cpu_transcoder_set_m_n(intel_crtc, pipe_config,
>  				     &pipe_config->fdi_m_n, NULL);
>  	}
>  
> -	ironlake_set_pipeconf(crtc);
> +	ironlake_set_pipeconf(crtc, pipe_config);
>  
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  	intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true);
> @@ -4811,7 +4810,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  		assert_fdi_rx_disabled(dev_priv, pipe);
>  	}
>  
> -	ironlake_pfit_enable(intel_crtc);
> +	ironlake_pfit_enable(intel_crtc, pipe_config);
>  
>  	/*
>  	 * On ILK+ LUT must be loaded before the pipe is running but with
> @@ -4822,7 +4821,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>  	intel_update_watermarks(crtc);
>  	intel_enable_pipe(intel_crtc);
>  
> -	if (intel_crtc->config->has_pch_encoder)
> +	if (pipe_config->has_pch_encoder)
>  		ironlake_pch_enable(crtc, pipe_config);
>  
>  	assert_vblank_disabled(crtc);
> @@ -4857,9 +4856,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>  
>  	if (pipe_config->has_dp_encoder)
> -		intel_dp_set_m_n(intel_crtc, M1_N1);
> +		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
>  
> -	intel_set_pipe_timings(intel_crtc);
> +	intel_set_pipe_timings(intel_crtc, pipe_config);
>  
>  	if (pipe_config->cpu_transcoder != TRANSCODER_EDP) {
>  		I915_WRITE(PIPE_MULT(pipe_config->cpu_transcoder),
> @@ -4867,13 +4866,13 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	}
>  
>  	if (pipe_config->has_pch_encoder) {
> -		intel_cpu_transcoder_set_m_n(intel_crtc,
> +		intel_cpu_transcoder_set_m_n(intel_crtc, pipe_config,
>  				     &pipe_config->fdi_m_n, NULL);
>  	}
>  
> -	haswell_set_pipeconf(crtc);
> +	haswell_set_pipeconf(crtc, pipe_config);
>  
> -	intel_set_pipe_csc(crtc);
> +	intel_set_pipe_csc(crtc, pipe_config);
>  
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
> @@ -4890,9 +4889,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	intel_ddi_enable_pipe_clock(intel_crtc);
>  
>  	if (INTEL_INFO(dev)->gen == 9)
> -		skylake_pfit_update(intel_crtc, 1);
> +		skylake_pfit_update(intel_crtc, pipe_config, 1);
>  	else if (INTEL_INFO(dev)->gen < 9)
> -		ironlake_pfit_enable(intel_crtc);
> +		ironlake_pfit_enable(intel_crtc, pipe_config);
>  	else
>  		MISSING_CASE(INTEL_INFO(dev)->gen);
>  
> @@ -4908,10 +4907,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	intel_update_watermarks(crtc);
>  	intel_enable_pipe(intel_crtc);
>  
> -	if (intel_crtc->config->has_pch_encoder)
> +	if (pipe_config->has_pch_encoder)
>  		lpt_pch_enable(dev_priv, pipe_config);
>  
> -	if (intel_crtc->config->dp_encoder_is_mst)
> +	if (pipe_config->dp_encoder_is_mst)
>  		intel_ddi_set_vc_payload_alloc(crtc,
>  					       pipe_config->cpu_transcoder,
>  					       true);
> @@ -4932,7 +4931,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>  	}
>  }
>  
> -static void ironlake_pfit_disable(struct intel_crtc *crtc)
> +static void ironlake_pfit_disable(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;
> @@ -4940,7 +4940,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc)
>  
>  	/* To avoid upsetting the power well on haswell only disable the pfit if
>  	 * it's in use. The hw state code will make sure we get this right. */
> -	if (crtc->config->pch_pfit.enabled) {
> +	if (pipe_config->pch_pfit.enabled) {
>  		I915_WRITE(PF_CTL(pipe), 0);
>  		I915_WRITE(PF_WIN_POS(pipe), 0);
>  		I915_WRITE(PF_WIN_SZ(pipe), 0);
> @@ -4968,7 +4968,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc,
>  
>  	intel_disable_pipe(intel_crtc, old_state);
>  
> -	ironlake_pfit_disable(intel_crtc);
> +	ironlake_pfit_disable(intel_crtc, old_state);
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
> @@ -5005,7 +5005,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct intel_encoder *encoder;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = old_state->cpu_transcoder;
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder) {
>  		intel_opregion_notify_encoder(encoder, false);
> @@ -5015,12 +5015,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  	drm_crtc_vblank_off(crtc);
>  	assert_vblank_disabled(crtc);
>  
> -	if (intel_crtc->config->has_pch_encoder)
> +	if (old_state->has_pch_encoder)
>  		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
>  						      false);
>  	intel_disable_pipe(intel_crtc, old_state);
>  
> -	if (intel_crtc->config->dp_encoder_is_mst)
> +	if (old_state->dp_encoder_is_mst)
>  		intel_ddi_set_vc_payload_alloc(crtc,
>  					       old_state->cpu_transcoder,
>  					       false);
> @@ -5028,15 +5028,15 @@ static void haswell_crtc_disable(struct drm_crtc *crtc,
>  	intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
>  
>  	if (INTEL_INFO(dev)->gen == 9)
> -		skylake_pfit_update(intel_crtc, 0);
> +		skylake_pfit_update(intel_crtc, old_state, 0);
>  	else if (INTEL_INFO(dev)->gen < 9)
> -		ironlake_pfit_disable(intel_crtc);
> +		ironlake_pfit_disable(intel_crtc, old_state);
>  	else
>  		MISSING_CASE(INTEL_INFO(dev)->gen);
>  
>  	intel_ddi_disable_pipe_clock(intel_crtc, old_state->cpu_transcoder);
>  
> -	if (intel_crtc->config->has_pch_encoder) {
> +	if (old_state->has_pch_encoder) {
>  		lpt_disable_pch_transcoder(dev_priv);
>  		intel_ddi_fdi_disable(crtc, old_state);
>  	}
> @@ -5126,13 +5126,15 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
>  	enum pipe pipe = intel_crtc->pipe;
>  	unsigned long mask;
>  	enum transcoder transcoder;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  
> -	transcoder = to_intel_crtc_state(crtc->state)->cpu_transcoder;
> +	transcoder = pipe_config->cpu_transcoder;
>  
>  	mask = BIT(POWER_DOMAIN_PIPE(pipe));
>  	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
> -	if (intel_crtc->config->pch_pfit.enabled ||
> -	    intel_crtc->config->pch_pfit.force_thru)
> +	if (pipe_config->pch_pfit.enabled ||
> +	    pipe_config->pch_pfit.force_thru)
>  		mask |= BIT(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
>  
>  	for_each_encoder_on_crtc(dev, crtc, intel_encoder)
> @@ -5595,7 +5597,8 @@ static int intel_mode_max_pixclk(struct drm_device *dev,
>  			crtc_state =
>  				intel_atomic_get_crtc_state(state, intel_crtc);
>  		else
> -			crtc_state = intel_crtc->config;
> +			crtc_state = to_intel_crtc_state(intel_crtc->base.state);
> +
>  		if (IS_ERR(crtc_state))
>  			return PTR_ERR(crtc_state);
>  
> @@ -5743,9 +5746,9 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  	}
>  
>  	if (pipe_config->has_dp_encoder)
> -		intel_dp_set_m_n(intel_crtc, M1_N1);
> +		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
>  
> -	intel_set_pipe_timings(intel_crtc);
> +	intel_set_pipe_timings(intel_crtc, pipe_config);
>  
>  	if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
>  		struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -5754,7 +5757,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  		I915_WRITE(CHV_CANVAS(pipe), 0);
>  	}
>  
> -	i9xx_set_pipeconf(intel_crtc);
> +	i9xx_set_pipeconf(intel_crtc, pipe_config);
>  
>  	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
>  
> @@ -5787,15 +5790,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
>  		encoder->enable(encoder);
>  }
>  
> -static void i9xx_set_pll_dividers(struct intel_crtc *crtc)
> -{
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0);
> -	I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1);
> -}
> -
>  static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  {
>  	struct drm_device *dev = crtc->dev;
> @@ -5808,14 +5802,15 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  	pipe_config = to_intel_crtc_state(crtc->state);
>  	WARN_ON(!pipe_config->base.active);
>  
> -	i9xx_set_pll_dividers(intel_crtc);
> +	I915_WRITE(FP0(pipe), pipe_config->dpll_hw_state.fp0);
> +	I915_WRITE(FP1(pipe), pipe_config->dpll_hw_state.fp1);
>  
> -	if (intel_crtc->config->has_dp_encoder)
> -		intel_dp_set_m_n(intel_crtc, M1_N1);
> +	if (pipe_config->has_dp_encoder)
> +		intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
>  
> -	intel_set_pipe_timings(intel_crtc);
> +	intel_set_pipe_timings(intel_crtc, pipe_config);
>  
> -	i9xx_set_pipeconf(intel_crtc);
> +	i9xx_set_pipeconf(intel_crtc, pipe_config);
>  
>  	if (!IS_GEN2(dev))
>  		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
> @@ -5840,14 +5835,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
>  		encoder->enable(encoder);
>  }
>  
> -static void i9xx_pfit_disable(struct intel_crtc *crtc)
> +static void i9xx_pfit_disable(struct drm_i915_private *dev_priv)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	if (!crtc->config->gmch_pfit.control)
> -		return;
> -
>  	DRM_DEBUG_DRIVER("disabling pfit, current: 0x%08x\n",
>  			 I915_READ(PFIT_CONTROL));
>  	I915_WRITE(PFIT_CONTROL, 0);
> @@ -5878,7 +5867,8 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc,
>  
>  	intel_disable_pipe(intel_crtc, old_state);
>  
> -	i9xx_pfit_disable(intel_crtc);
> +	if (old_state->gmch_pfit.control)
> +		i9xx_pfit_disable(dev_priv);
>  
>  	for_each_encoder_on_crtc(dev, crtc, encoder)
>  		if (encoder->post_disable)
> @@ -6638,13 +6628,14 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
>  }
>  
>  static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
> +					 struct intel_crtc_state *pipe_config,
>  					 struct intel_link_m_n *m_n,
>  					 struct intel_link_m_n *m2_n2)
>  {
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	int pipe = crtc->pipe;
> -	enum transcoder transcoder = crtc->config->cpu_transcoder;
> +	enum transcoder transcoder = pipe_config->cpu_transcoder;
>  
>  	if (INTEL_INFO(dev)->gen >= 5) {
>  		I915_WRITE(PIPE_DATA_M1(transcoder), TU_SIZE(m_n->tu) | m_n->gmch_m);
> @@ -6656,7 +6647,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
>  		 * registers are not unnecessarily accessed).
>  		 */
>  		if (m2_n2 && (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen < 8) &&
> -			crtc->config->has_drrs) {
> +			pipe_config->has_drrs) {
>  			I915_WRITE(PIPE_DATA_M2(transcoder),
>  					TU_SIZE(m2_n2->tu) | m2_n2->gmch_m);
>  			I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n);
> @@ -6671,29 +6662,31 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
>  	}
>  }
>  
> -void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n)
> +void intel_dp_set_m_n(struct intel_crtc *crtc,
> +		      struct intel_crtc_state *pipe_config,
> +		      enum link_m_n_set m_n)
>  {
>  	struct intel_link_m_n *dp_m_n, *dp_m2_n2 = NULL;
>  
>  	if (m_n == M1_N1) {
> -		dp_m_n = &crtc->config->dp_m_n;
> -		dp_m2_n2 = &crtc->config->dp_m2_n2;
> +		dp_m_n = &pipe_config->dp_m_n;
> +		dp_m2_n2 = &pipe_config->dp_m2_n2;
>  	} else if (m_n == M2_N2) {
>  
>  		/*
>  		 * M2_N2 registers are not supported. Hence m2_n2 divider value
>  		 * needs to be programmed into M1_N1.
>  		 */
> -		dp_m_n = &crtc->config->dp_m2_n2;
> +		dp_m_n = &pipe_config->dp_m2_n2;
>  	} else {
>  		DRM_ERROR("Unsupported divider value\n");
>  		return;
>  	}
>  
> -	if (crtc->config->has_pch_encoder)
> -		intel_pch_transcoder_set_m_n(crtc, &crtc->config->dp_m_n);
> +	if (pipe_config->has_pch_encoder)
> +		intel_pch_transcoder_set_m_n(crtc, &pipe_config->dp_m_n);
>  	else
> -		intel_cpu_transcoder_set_m_n(crtc, dp_m_n, dp_m2_n2);
> +		intel_cpu_transcoder_set_m_n(crtc, pipe_config, dp_m_n, dp_m2_n2);
>  }
>  
>  static void vlv_update_pll(struct intel_crtc *crtc,
> @@ -6976,9 +6969,6 @@ void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe)
>  	struct drm_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
>  	struct intel_crtc_state *state = to_intel_crtc_state(crtc->state);
>  
> -	/* Is state->cpu_transcoder correct to use? */
> -	WARN_ON(crtc->state != &to_intel_crtc(crtc)->config->base);
> -
>  	/* Make sure the pipe isn't still relying on us */
>  	assert_pipe_disabled(dev_priv, state->cpu_transcoder, pipe);
>  
> @@ -7103,14 +7093,15 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
>  	crtc_state->dpll_hw_state.dpll = dpll;
>  }
>  
> -static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
> +static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
> +				   struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	enum pipe pipe = intel_crtc->pipe;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	struct drm_display_mode *adjusted_mode =
> -		&intel_crtc->config->base.adjusted_mode;
> +		&pipe_config->base.adjusted_mode;
>  	uint32_t crtc_vtotal, crtc_vblank_end;
>  	int vsyncshift = 0;
>  
> @@ -7168,8 +7159,8 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
>  	 * always be the user's requested size.
>  	 */
>  	I915_WRITE(PIPESRC(pipe),
> -		   ((intel_crtc->config->pipe_src_w - 1) << 16) |
> -		   (intel_crtc->config->pipe_src_h - 1));
> +		   ((pipe_config->pipe_src_w - 1) << 16) |
> +		    (pipe_config->pipe_src_h - 1));
>  }
>  
>  static void intel_get_pipe_timings(struct intel_crtc *crtc,
> @@ -7233,7 +7224,8 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>  	mode->flags |= pipe_config->base.adjusted_mode.flags;
>  }
>  
> -static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
> +static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc,
> +			      struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -7245,17 +7237,17 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
>  	    (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
>  		pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
>  
> -	if (intel_crtc->config->double_wide)
> +	if (pipe_config->double_wide)
>  		pipeconf |= PIPECONF_DOUBLE_WIDE;
>  
>  	/* only g4x and later have fancy bpc/dither controls */
>  	if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
>  		/* Bspec claims that we can't use dithering for 30bpp pipes. */
> -		if (intel_crtc->config->dither && intel_crtc->config->pipe_bpp != 30)
> +		if (pipe_config->dither && pipe_config->pipe_bpp != 30)
>  			pipeconf |= PIPECONF_DITHER_EN |
>  				    PIPECONF_DITHER_TYPE_SP;
>  
> -		switch (intel_crtc->config->pipe_bpp) {
> +		switch (pipe_config->pipe_bpp) {
>  		case 18:
>  			pipeconf |= PIPECONF_6BPC;
>  			break;
> @@ -7280,7 +7272,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
>  		}
>  	}
>  
> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> +	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
>  		if (INTEL_INFO(dev)->gen < 4 ||
>  		    intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO))
>  			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
> @@ -7289,7 +7281,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
>  	} else
>  		pipeconf |= PIPECONF_PROGRESSIVE;
>  
> -	if (IS_VALLEYVIEW(dev) && intel_crtc->config->limited_color_range)
> +	if (IS_VALLEYVIEW(dev) && pipe_config->limited_color_range)
>  		pipeconf |= PIPECONF_COLOR_RANGE_SELECT;
>  
>  	I915_WRITE(PIPECONF(intel_crtc->pipe), pipeconf);
> @@ -8027,7 +8019,8 @@ static int ironlake_get_refclk(struct intel_crtc_state *crtc_state)
>  	return 120000;
>  }
>  
> -static void ironlake_set_pipeconf(struct drm_crtc *crtc)
> +static void ironlake_set_pipeconf(struct drm_crtc *crtc,
> +				  struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -8036,7 +8029,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
>  
>  	val = 0;
>  
> -	switch (intel_crtc->config->pipe_bpp) {
> +	switch (pipe_config->pipe_bpp) {
>  	case 18:
>  		val |= PIPECONF_6BPC;
>  		break;
> @@ -8054,15 +8047,15 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
>  		BUG();
>  	}
>  
> -	if (intel_crtc->config->dither)
> +	if (pipe_config->dither)
>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>  
> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		val |= PIPECONF_INTERLACED_ILK;
>  	else
>  		val |= PIPECONF_PROGRESSIVE;
>  
> -	if (intel_crtc->config->limited_color_range)
> +	if (pipe_config->limited_color_range)
>  		val |= PIPECONF_COLOR_RANGE_SELECT;
>  
>  	I915_WRITE(PIPECONF(pipe), val);
> @@ -8076,7 +8069,8 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc)
>   * is supported, but eventually this should handle various
>   * RGB<->YCbCr scenarios as well.
>   */
> -static void intel_set_pipe_csc(struct drm_crtc *crtc)
> +static void intel_set_pipe_csc(struct drm_crtc *crtc,
> +			       struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -8091,7 +8085,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
>  	 * consideration.
>  	 */
>  
> -	if (intel_crtc->config->limited_color_range)
> +	if (pipe_config->limited_color_range)
>  		coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
>  
>  	/*
> @@ -8115,7 +8109,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
>  	if (INTEL_INFO(dev)->gen > 6) {
>  		uint16_t postoff = 0;
>  
> -		if (intel_crtc->config->limited_color_range)
> +		if (pipe_config->limited_color_range)
>  			postoff = (16 * (1 << 12) / 255) & 0x1fff;
>  
>  		I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
> @@ -8126,28 +8120,29 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc)
>  	} else {
>  		uint32_t mode = CSC_MODE_YUV_TO_RGB;
>  
> -		if (intel_crtc->config->limited_color_range)
> +		if (pipe_config->limited_color_range)
>  			mode |= CSC_BLACK_SCREEN_OFFSET;
>  
>  		I915_WRITE(PIPE_CSC_MODE(pipe), mode);
>  	}
>  }
>  
> -static void haswell_set_pipeconf(struct drm_crtc *crtc)
> +static void haswell_set_pipeconf(struct drm_crtc *crtc,
> +				 struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum pipe pipe = intel_crtc->pipe;
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	uint32_t val;
>  
>  	val = 0;
>  
> -	if (IS_HASWELL(dev) && intel_crtc->config->dither)
> +	if (IS_HASWELL(dev) && pipe_config->dither)
>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>  
> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (pipe_config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		val |= PIPECONF_INTERLACED_ILK;
>  	else
>  		val |= PIPECONF_PROGRESSIVE;
> @@ -8161,7 +8156,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
>  	if (IS_BROADWELL(dev) || INTEL_INFO(dev)->gen >= 9) {
>  		val = 0;
>  
> -		switch (intel_crtc->config->pipe_bpp) {
> +		switch (pipe_config->pipe_bpp) {
>  		case 18:
>  			val |= PIPEMISC_DITHER_6_BPC;
>  			break;
> @@ -8179,7 +8174,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
>  			BUG();
>  		}
>  
> -		if (intel_crtc->config->dither)
> +		if (pipe_config->dither)
>  			val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
>  
>  		I915_WRITE(PIPEMISC(pipe), val);
> @@ -8423,12 +8418,13 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
>  }
>  
>  static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
> -					 enum transcoder transcoder,
> +					 struct intel_crtc_state *pipe_config,
>  					 struct intel_link_m_n *m_n,
>  					 struct intel_link_m_n *m2_n2)
>  {
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	enum transcoder transcoder = pipe_config->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
>  
>  	if (INTEL_INFO(dev)->gen >= 5) {
> @@ -8444,7 +8440,7 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
>  		 * registers are not unnecessarily read).
>  		 */
>  		if (m2_n2 && INTEL_INFO(dev)->gen < 8 &&
> -			crtc->config->has_drrs) {
> +			pipe_config->has_drrs) {
>  			m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder));
>  			m2_n2->link_n =	I915_READ(PIPE_LINK_N2(transcoder));
>  			m2_n2->gmch_m =	I915_READ(PIPE_DATA_M2(transcoder))
> @@ -8470,7 +8466,7 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
>  	if (pipe_config->has_pch_encoder)
>  		intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
>  	else
> -		intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
> +		intel_cpu_transcoder_get_m_n(crtc, pipe_config,
>  					     &pipe_config->dp_m_n,
>  					     &pipe_config->dp_m2_n2);
>  }
> @@ -8478,7 +8474,7 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
>  static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
>  					struct intel_crtc_state *pipe_config)
>  {
> -	intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
> +	intel_cpu_transcoder_get_m_n(crtc, pipe_config,
>  				     &pipe_config->fdi_m_n, NULL);
>  }
>  
> @@ -9331,6 +9327,8 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
>  	int pipe = intel_crtc->pipe;
>  	int x = crtc->cursor_x;
>  	int y = crtc->cursor_y;
> @@ -9339,10 +9337,10 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
>  	if (on)
>  		base = intel_crtc->cursor_addr;
>  
> -	if (x >= intel_crtc->config->pipe_src_w)
> +	if (x >= pipe_config->pipe_src_w)
>  		base = 0;
>  
> -	if (y >= intel_crtc->config->pipe_src_h)
> +	if (y >= pipe_config->pipe_src_h)
>  		base = 0;

Just curiosity: Shouldn't our clamping and visibility computation catch
this already?

>  
>  	if (x < 0) {
> @@ -9966,9 +9964,11 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> +	struct intel_crtc_state *pipe_config =
> +		to_intel_crtc_state(crtc->state);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	struct drm_display_mode *mode;
> -	struct intel_crtc_state pipe_config;
> +	struct intel_crtc_state fake_config;
>  	int htot = I915_READ(HTOTAL(cpu_transcoder));
>  	int hsync = I915_READ(HSYNC(cpu_transcoder));
>  	int vtot = I915_READ(VTOTAL(cpu_transcoder));
> @@ -9986,14 +9986,14 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	 * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
>  	 * to use a real value here instead.
>  	 */
> -	pipe_config.cpu_transcoder = (enum transcoder) pipe;
> -	pipe_config.pixel_multiplier = 1;
> -	pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
> -	pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
> -	pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
> -	i9xx_crtc_clock_get(intel_crtc, &pipe_config);
> -
> -	mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier;
> +	fake_config.cpu_transcoder = (enum transcoder) pipe;
> +	fake_config.pixel_multiplier = 1;
> +	fake_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
> +	fake_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
> +	fake_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
> +	i9xx_crtc_clock_get(intel_crtc, &fake_config);
> +
> +	mode->clock = fake_config.port_clock / fake_config.pixel_multiplier;
>  	mode->hdisplay = (htot & 0xffff) + 1;
>  	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
>  	mode->hsync_start = (hsync & 0xffff) + 1;

s/pipe_config/fake_config is nice but should be split out imo.

> @@ -11839,12 +11839,13 @@ check_crtc_state(struct drm_device *dev)
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *crtc;
>  	struct intel_encoder *encoder;
> -	struct intel_crtc_state pipe_config;
> +	struct intel_crtc_state pipe_config, *sw_config;
>  
>  	for_each_intel_crtc(dev, crtc) {
>  		bool enabled = false;
>  		bool active = false;
>  
> +		sw_config = to_intel_crtc_state(crtc->base.state);
>  		memset(&pipe_config, 0, sizeof(pipe_config));
>  
>  		DRM_DEBUG_KMS("[CRTC:%d]\n",
> @@ -11887,11 +11888,11 @@ check_crtc_state(struct drm_device *dev)
>  		     "(expected %i, found %i)\n", crtc->base.state->active, active);
>  
>  		if (active &&
> -		    !intel_pipe_config_compare(dev, crtc->config, &pipe_config)) {
> +		    !intel_pipe_config_compare(dev, sw_config, &pipe_config)) {
>  			I915_STATE_WARN(1, "pipe state doesn't match!\n");
>  			intel_dump_pipe_config(crtc, &pipe_config,
>  					       "[hw state]");
> -			intel_dump_pipe_config(crtc, crtc->config,
> +			intel_dump_pipe_config(crtc, sw_config,
>  					       "[sw state]");
>  		}
>  	}
> @@ -11990,7 +11991,8 @@ static void update_scanline_offset(struct intel_crtc *crtc)
>  	 * one to the value.
>  	 */
>  	if (IS_GEN2(dev)) {
> -		const struct drm_display_mode *mode = &crtc->config->base.adjusted_mode;
> +		const struct drm_display_mode *mode =
> +			&crtc->base.state->adjusted_mode;
>  		int vtotal;
>  
>  		vtotal = mode->crtc_vtotal;
> @@ -13532,6 +13534,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
>  	crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
>  	if (!crtc_state)
>  		goto fail;
> +
>  	intel_crtc->config = crtc_state;
>  	intel_crtc->base.state = &crtc_state->base;
>  	crtc_state->base.crtc = &intel_crtc->base;
> @@ -14574,19 +14577,20 @@ intel_check_plane_mapping(struct intel_crtc *crtc)
>  	return true;
>  }
>  
> -static void intel_sanitize_crtc(struct intel_crtc *crtc)
> +static void intel_sanitize_crtc(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;
>  	u32 reg;
>  
>  	/* Clear any frame start delays used for debugging left by the BIOS */
> -	reg = PIPECONF(crtc->config->cpu_transcoder);
> +	reg = PIPECONF(pipe_config->cpu_transcoder);
>  	I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
>  
>  	/* restore vblank interrupts to correct state */
>  	drm_crtc_vblank_reset(&crtc->base);
> -	if (crtc->base.state->active) {
> +	if (pipe_config->base.active) {
>  		update_scanline_offset(crtc);
>  		drm_crtc_vblank_on(&crtc->base);
>  	}
> @@ -14626,14 +14630,14 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  				connector->encoder->connectors_active = false;
>  			}
>  
> -		WARN_ON(crtc->base.state->active);
> -		crtc->base.state->enable = false;
> -		crtc->base.state->active = false;
> +		WARN_ON(pipe_config->base.active);
> +		pipe_config->base.enable = false;
> +		pipe_config->base.active = false;
>  		crtc->base.enabled = false;
>  	}
>  
>  	if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
> -	    crtc->pipe == PIPE_A && !crtc->base.state->active) {
> +	    crtc->pipe == PIPE_A && !pipe_config->base.active) {
>  		/* BIOS forgot to enable pipe A, this mostly happens after
>  		 * resume. Force-enable the pipe to fix this, the update_dpms
>  		 * call below we restore the pipe to the right state, but leave
> @@ -14645,7 +14649,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
>  	 * have active connectors/encoders. */
>  	intel_crtc_update_dpms(&crtc->base);
>  
> -	if (crtc->base.state->active || HAS_GMCH_DISPLAY(dev)) {
> +	if (pipe_config->base.active || HAS_GMCH_DISPLAY(dev)) {
>  		/*
>  		 * We start out with underrun reporting disabled to avoid races.
>  		 * For correct bookkeeping mark this on active crtcs.
> @@ -14763,17 +14767,19 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  	for_each_intel_crtc(dev, crtc) {
>  		struct drm_plane *primary = crtc->base.primary;
>  		struct intel_plane_state *plane_state;
> +		struct intel_crtc_state *pipe_config =
> +			to_intel_crtc_state(crtc->base.state);
>  
> -		memset(crtc->config, 0, sizeof(*crtc->config));
> +		memset(pipe_config, 0, sizeof(*pipe_config));
>  
> -		crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
> +		pipe_config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
>  
>  		if (crtc->base.state->active)
>  			*crtc_mask |= drm_crtc_index(&crtc->base);
>  
> -		crtc->base.enabled = crtc->base.state->enable =
> -		crtc->base.state->active =
> -			dev_priv->display.get_pipe_config(crtc, crtc->config);
> +		crtc->base.enabled = pipe_config->base.enable =
> +		pipe_config->base.active =
> +			dev_priv->display.get_pipe_config(crtc, pipe_config);
>  
>  		plane_state = to_intel_plane_state(primary->state);
>  		plane_state->hw_enabled = plane_state->visible =
> @@ -14818,7 +14824,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev,
>  		if (encoder->get_hw_state(encoder, &pipe)) {
>  			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
>  			encoder->base.crtc = &crtc->base;
> -			encoder->get_config(encoder, crtc->config);
> +			encoder->get_config(encoder,
> +				to_intel_crtc_state(crtc->base.state));
>  		} else {
>  			encoder->base.crtc = NULL;
>  		}
> @@ -14883,9 +14890,13 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
>  	}
>  
>  	for_each_pipe(dev_priv, pipe) {
> +		struct intel_crtc_state *pipe_config;
> +
>  		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
> -		intel_sanitize_crtc(crtc);
> -		intel_dump_pipe_config(crtc, crtc->config,
> +		pipe_config = to_intel_crtc_state(crtc->base.state);
> +
> +		intel_sanitize_crtc(crtc, pipe_config);

Another example where there's imo no need to pass around pipe_config
explictly. As I said I didn't highlight all of them.

> +		intel_dump_pipe_config(crtc, pipe_config,
>  				       "[setup_hw_state]");
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index e6876faca7f0..abf8082be40c 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5309,10 +5309,10 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>  	if (INTEL_INFO(dev)->gen >= 8 && !IS_CHERRYVIEW(dev)) {
>  		switch (index) {
>  		case DRRS_HIGH_RR:
> -			intel_dp_set_m_n(intel_crtc, M1_N1);
> +			intel_dp_set_m_n(intel_crtc, pipe_config, M1_N1);
>  			break;
>  		case DRRS_LOW_RR:
> -			intel_dp_set_m_n(intel_crtc, M2_N2);
> +			intel_dp_set_m_n(intel_crtc, pipe_config, M2_N2);

Should be part of the drrs patch.

>  			break;
>  		case DRRS_MAX_RR:
>  		default:
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 7979a2f6838c..6767ed91faaf 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1102,7 +1102,9 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv);
>  void bxt_disable_dc9(struct drm_i915_private *dev_priv);
>  void intel_dp_get_m_n(struct intel_crtc *crtc,
>  		      struct intel_crtc_state *pipe_config);
> -void intel_dp_set_m_n(struct intel_crtc *crtc, enum link_m_n_set m_n);
> +void intel_dp_set_m_n(struct intel_crtc *crtc,
> +		      struct intel_crtc_state *pipe_config,
> +		      enum link_m_n_set m_n);

Misplace hunk ;-)
-Daniel

>  int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
>  void
>  ironlake_check_encoder_dotclock(const struct intel_crtc_state *pipe_config,
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 03/42] drm/i915: Only update required power domains.
  2015-05-11 17:00   ` Daniel Vetter
@ 2015-05-12 12:05     ` Maarten Lankhorst
  2015-05-12 13:13       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 12:05 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 11-05-15 om 19:00 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:39PM +0200, Maarten Lankhorst wrote:
>> This prevents unnecessarily updating power domains, while still
>> enabling all power domains on initial setup.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_display.c | 52 ++++++++++++++++++++++++++++--------
>>  1 file changed, 41 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index af96d686aae2..42d0cc329b37 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -5298,36 +5298,72 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
>>  	return mask;
>>  }
>>  
>> +static bool
>> +needs_modeset(struct drm_crtc_state *state)
> I think we should extract this from drm_atomic_helper.c. But that can be
> done as a follow-up - if you track it ;-)
>> +{
>> +	return state->mode_changed || state->active_changed;
>> +}
>> +
>>  static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
>>  {
>>  	struct drm_device *dev = state->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
>>  	struct intel_crtc *crtc;
>> +	bool init_power = dev_priv->power_domains.init_power_on;
>> +	bool any_power = init_power, any_modeset = false;
>> +	unsigned long domains;
>>  
>>  	/*
>>  	 * First get all needed power domains, then put all unneeded, to avoid
>>  	 * any unnecessary toggling of the power wells.
>>  	 */
>>  	for_each_intel_crtc(dev, crtc) {
>> +		int idx = drm_crtc_index(&crtc->base);
>> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
>>  		enum intel_display_power_domain domain;
>>  
>> -		if (!crtc->base.state->enable)
>> +		if (!init_power && !crtc_state)
>> +			continue;
> 		if (!needs_modeset)
> 			continue;
>
> while you're optimizing this?
>
>> +
>> +		if (needs_modeset(crtc->base.state))
>> +			any_modeset = true;
>> +
>> +		if (crtc->base.state->enable)
>> +			pipe_domains[crtc->pipe] =
>> +				get_crtc_power_domains(&crtc->base);
>> +
>> +		if (pipe_domains[crtc->pipe] == crtc->enabled_power_domains)
>>  			continue;
>>  
>> -		pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
>> +		WARN_ON(!init_power && !needs_modeset(crtc->base.state));
>> +
>> +		any_power = true;
>> +		domains = pipe_domains[crtc->pipe] &
>> +			  ~crtc->enabled_power_domains;
>>  
>> -		for_each_power_domain(domain, pipe_domains[crtc->pipe])
>> +		for_each_power_domain(domain, domains)
>>  			intel_display_power_get(dev_priv, domain);
>>  	}
>>  
>> -	if (dev_priv->display.modeset_global_resources)
>> +	if (any_modeset && dev_priv->display.modeset_global_resources)
>>  		dev_priv->display.modeset_global_resources(state);
>>  
>> +	if (!any_power)
>> +		return;
>> +
>>  	for_each_intel_crtc(dev, crtc) {
>> +		int idx = drm_crtc_index(&crtc->base);
>> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
>>  		enum intel_display_power_domain domain;
>>  
>> -		for_each_power_domain(domain, crtc->enabled_power_domains)
>> +		if (!init_power && !crtc_state)
>> +			continue;
> Same shortcut here?
It's not an optimization, the same path can be used for modeset and updating planes.
If it's a plane update the code might run with irqs disabled, in which case we can't call power_get or power_put because that requires a mutex.

~Maarten

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 04/42] drm/i915: use intel_crtc_control everywhere
  2015-05-11 17:11   ` Daniel Vetter
@ 2015-05-12 12:06     ` Maarten Lankhorst
  2015-05-12 13:16       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 12:06 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 11-05-15 om 19:11 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:40PM +0200, Maarten Lankhorst wrote:
>> @@ -6079,26 +6059,29 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>>  	enum intel_display_power_domain domain;
>>  	unsigned long domains;
>>  
>> +	if (enable == intel_crtc->active)
>> +		return;
>> +
>> +	if (enable && !crtc->state->enable)
>> +		return;
> I think we only need to check for !state->enable here. Changing dpms while
> the crtc is fully of is totally legit. And at least -modesetting loves to
> do just that iirc.
>
> I'll will be caught by state->active implying state->enable, but that's
> hard to read imo.
> -Daniel
As discussed on irc it's not. :-)

~Maarten

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 06/42] drm/i915: get rid of new_crtc
  2015-05-11 17:28   ` Daniel Vetter
@ 2015-05-12 12:07     ` Maarten Lankhorst
  0 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 12:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 11-05-15 om 19:28 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:42PM +0200, Maarten Lankhorst wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Same comment about the terse commit message as in the previous patch.
>
>> ---
>>  drivers/gpu/drm/i915/intel_display.c | 15 ++++-----------
>>  drivers/gpu/drm/i915/intel_drv.h     |  5 -----
>>  2 files changed, 4 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 00b1552a1f91..a9ce827601d8 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -9795,7 +9795,6 @@ retry:
>>  	ret = drm_modeset_lock(&crtc->primary->mutex, ctx);
>>  	if (ret)
>>  		goto fail_unlock;
>> -	intel_encoder->new_crtc = to_intel_crtc(crtc);
>>  
>>  	intel_crtc = to_intel_crtc(crtc);
>>  	intel_crtc->new_enabled = true;
>> @@ -9914,7 +9913,6 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
>>  		if (IS_ERR(crtc_state))
>>  			goto fail;
>>  
>> -		intel_encoder->new_crtc = NULL;
>>  		intel_crtc->new_enabled = false;
>>  
>>  		connector_state->best_encoder = NULL;
>> @@ -11063,12 +11061,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
>>  static void intel_modeset_update_staged_output_state(struct drm_device *dev)
>>  {
>>  	struct intel_crtc *crtc;
>> -	struct intel_encoder *encoder;
>> -
>> -	for_each_intel_encoder(dev, encoder) {
>> -		encoder->new_crtc =
>> -			to_intel_crtc(encoder->base.crtc);
>> -	}
>>  
>>  	for_each_intel_crtc(dev, crtc) {
>>  		crtc->new_enabled = crtc->base.state->enable;
>> @@ -11905,8 +11897,6 @@ check_encoder_state(struct drm_device *dev)
>>  			      encoder->base.base.id,
>>  			      encoder->base.name);
>>  
>> -		I915_STATE_WARN(&encoder->new_crtc->base != encoder->base.crtc,
>> -		     "encoder's stage crtc doesn't match current crtc\n");
>>  		I915_STATE_WARN(encoder->connectors_active && !encoder->base.crtc,
>>  		     "encoder's active_connectors set, but no crtc\n");
>>  
>> @@ -11916,6 +11906,9 @@ check_encoder_state(struct drm_device *dev)
>>  			enabled = true;
>>  			if (connector->base.dpms != DRM_MODE_DPMS_OFF)
>>  				active = true;
>> +
>> +			I915_STATE_WARN(connector->base.state->crtc != encoder->base.crtc,
>> +			     "encoder's stage crtc doesn't match current crtc\n");
> Hm the error message doesn't make that much sense any more. What about
> "encoder's legacy crtc pointer doesn't match up with connector state"?
>
Sounds good!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
  2015-05-12  6:59   ` Daniel Vetter
@ 2015-05-12 12:41     ` Maarten Lankhorst
  2015-05-12 13:18       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 12:41 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 08:59 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:45PM +0200, Maarten Lankhorst wrote:
>> This should be safe.
> Usual request: A few more details about what you've changed to help guide
> the review would be great. E.g. which functions from the atomic helpers
> you're trying to copy here exactly.
That's in the diff. :-)
> It looks like this models set_routing_links. I think it would be rather
> useful to expose this to drivers as a helper function, maybe with a more
> useful name like drm_atomic_helper_update_legacy_state or similar.
I think you're right about this one.
> Another thing I've noticed is that atomic helpers lost the call to
> drm_calc_timestamping_constants. Would be good to add that to the same
> function.
Yeah, but the precise vblanking stuff is not really atomic friendly,
so I'm not sure it should be done outside the driver.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit
  2015-05-11 14:25 ` [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit Maarten Lankhorst
@ 2015-05-12 13:03   ` Daniel Vetter
  2015-05-12 14:16     ` Maarten Lankhorst
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 13:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 04:25:13PM +0200, Maarten Lankhorst wrote:
> crtc->config is gone, swap swap swap. :D
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c  | 36 ++----------------------------------
>  drivers/gpu/drm/i915/intel_display.c |  7 +++++--
>  2 files changed, 7 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index ace6aeeb1359..0315dc44b17a 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -130,7 +130,6 @@ int intel_atomic_commit(struct drm_device *dev,
>  			bool async)
>  {
>  	int ret;
> -	int i;
>  
>  	if (async) {
>  		DRM_DEBUG_KMS("i915 does not yet support async commit\n");
> @@ -142,48 +141,17 @@ int intel_atomic_commit(struct drm_device *dev,
>  		return ret;
>  
>  	/* Point of no return */
> +	drm_atomic_helper_swap_state(dev, state);
>  
>  	/*
>  	 * FIXME:  The proper sequence here will eventually be:
>  	 *
> -	 * drm_atomic_helper_swap_state(dev, state)
>  	 * drm_atomic_helper_commit_modeset_disables(dev, state);
>  	 * drm_atomic_helper_commit_planes(dev, state);
>  	 * drm_atomic_helper_commit_modeset_enables(dev, state);
> -	 * drm_atomic_helper_wait_for_vblanks(dev, state);
> -	 * drm_atomic_helper_cleanup_planes(dev, state);
> -	 * drm_atomic_state_free(state);
> -	 *
> -	 * once we have full atomic modeset.  For now, just manually update
> -	 * plane states to avoid clobbering good states with dummy states
> -	 * while nuclear pageflipping.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
> -		struct drm_plane *plane = state->planes[i];
> -
> -		if (!plane)
> -			continue;
> -
> -		plane->state->state = state;
> -		swap(state->plane_states[i], plane->state);
> -		plane->state->state = NULL;
> -	}
> -
> -	/* swap crtc_scaler_state */
> -	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> -		struct drm_crtc *crtc = state->crtcs[i];
> -		if (!crtc) {
> -			continue;
> -		}
> -
> -		to_intel_crtc_state(crtc->state)->scaler_state =
> -			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> -
> -		if (INTEL_INFO(dev)->gen >= 9)
> -			skl_detach_scalers(to_intel_crtc(crtc));
> -	}
> -
>  	drm_atomic_helper_commit_planes(dev, state);
> +
>  	drm_atomic_helper_wait_for_vblanks(dev, state);
>  	drm_atomic_helper_cleanup_planes(dev, state);
>  	drm_atomic_state_free(state);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 65ee2cd0437c..105bdf84e46a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13202,11 +13202,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
>  
>  	/* Perform vblank evasion around commit operation */
>  	if (intel_crtc->atomic.evade &&
> -	    !dev_priv->power_domains.init_power_on)
> +	    !dev_priv->power_domains.init_power_on) {
> +		if (dev_priv->info.gen >= 9)
> +			skl_detach_scalers(to_intel_crtc(crtc));

Don't we need to update skl_detach_scalers to look at the other config
now? Or is this an issue with the patch splitting?

Also why is this protected by atomic.evade?
-Daniel

> +
>  		intel_crtc->atomic.evade =
>  			intel_pipe_update_start(intel_crtc,
>  						&intel_crtc->atomic.start_vbl_count);
> -	else
> +	} else
>  		intel_crtc->atomic.evade = false;
>  }
>  
> -- 
> 2.1.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 03/42] drm/i915: Only update required power domains.
  2015-05-12 12:05     ` Maarten Lankhorst
@ 2015-05-12 13:13       ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 13:13 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 02:05:52PM +0200, Maarten Lankhorst wrote:
> Op 11-05-15 om 19:00 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:24:39PM +0200, Maarten Lankhorst wrote:
> >> This prevents unnecessarily updating power domains, while still
> >> enabling all power domains on initial setup.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_display.c | 52 ++++++++++++++++++++++++++++--------
> >>  1 file changed, 41 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index af96d686aae2..42d0cc329b37 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -5298,36 +5298,72 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
> >>  	return mask;
> >>  }
> >>  
> >> +static bool
> >> +needs_modeset(struct drm_crtc_state *state)
> > I think we should extract this from drm_atomic_helper.c. But that can be
> > done as a follow-up - if you track it ;-)
> >> +{
> >> +	return state->mode_changed || state->active_changed;
> >> +}
> >> +
> >>  static void modeset_update_crtc_power_domains(struct drm_atomic_state *state)
> >>  {
> >>  	struct drm_device *dev = state->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	unsigned long pipe_domains[I915_MAX_PIPES] = { 0, };
> >>  	struct intel_crtc *crtc;
> >> +	bool init_power = dev_priv->power_domains.init_power_on;
> >> +	bool any_power = init_power, any_modeset = false;
> >> +	unsigned long domains;
> >>  
> >>  	/*
> >>  	 * First get all needed power domains, then put all unneeded, to avoid
> >>  	 * any unnecessary toggling of the power wells.
> >>  	 */
> >>  	for_each_intel_crtc(dev, crtc) {
> >> +		int idx = drm_crtc_index(&crtc->base);
> >> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
> >>  		enum intel_display_power_domain domain;
> >>  
> >> -		if (!crtc->base.state->enable)
> >> +		if (!init_power && !crtc_state)
> >> +			continue;
> > 		if (!needs_modeset)
> > 			continue;
> >
> > while you're optimizing this?
> >
> >> +
> >> +		if (needs_modeset(crtc->base.state))
> >> +			any_modeset = true;
> >> +
> >> +		if (crtc->base.state->enable)
> >> +			pipe_domains[crtc->pipe] =
> >> +				get_crtc_power_domains(&crtc->base);
> >> +
> >> +		if (pipe_domains[crtc->pipe] == crtc->enabled_power_domains)
> >>  			continue;
> >>  
> >> -		pipe_domains[crtc->pipe] = get_crtc_power_domains(&crtc->base);
> >> +		WARN_ON(!init_power && !needs_modeset(crtc->base.state));
> >> +
> >> +		any_power = true;
> >> +		domains = pipe_domains[crtc->pipe] &
> >> +			  ~crtc->enabled_power_domains;
> >>  
> >> -		for_each_power_domain(domain, pipe_domains[crtc->pipe])
> >> +		for_each_power_domain(domain, domains)
> >>  			intel_display_power_get(dev_priv, domain);
> >>  	}
> >>  
> >> -	if (dev_priv->display.modeset_global_resources)
> >> +	if (any_modeset && dev_priv->display.modeset_global_resources)
> >>  		dev_priv->display.modeset_global_resources(state);
> >>  
> >> +	if (!any_power)
> >> +		return;
> >> +
> >>  	for_each_intel_crtc(dev, crtc) {
> >> +		int idx = drm_crtc_index(&crtc->base);
> >> +		struct drm_crtc_state *crtc_state = state->crtc_states[idx];
> >>  		enum intel_display_power_domain domain;
> >>  
> >> -		for_each_power_domain(domain, crtc->enabled_power_domains)
> >> +		if (!init_power && !crtc_state)
> >> +			continue;
> > Same shortcut here?
> It's not an optimization, the same path can be used for modeset and updating planes.
> If it's a plane update the code might run with irqs disabled, in which
> case we can't call power_get or power_put because that requires a mutex.

Plane updates should never ever change the power domains needed, hence for
a plane update we should short-circuit out the entire thing. And if the
pipe is off (state->active == false) then we need to delay the plane
updates until we enable the pipe again. Thus far the code has done that
with a mix of plane_state->visible checking (gated on intel_crtc->active)
and checking intel_crtc->active directly. In the future we just need to
gate plane updates on crtc_state->active. When enabling the pipe we need
to go through all planes anyway, so this should fall out naturally.

Or do I miss something?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 04/42] drm/i915: use intel_crtc_control everywhere
  2015-05-12 12:06     ` Maarten Lankhorst
@ 2015-05-12 13:16       ` Daniel Vetter
  2015-05-12 14:38         ` Daniel Stone
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 13:16 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 02:06:39PM +0200, Maarten Lankhorst wrote:
> Op 11-05-15 om 19:11 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:24:40PM +0200, Maarten Lankhorst wrote:
> >> @@ -6079,26 +6059,29 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
> >>  	enum intel_display_power_domain domain;
> >>  	unsigned long domains;
> >>  
> >> +	if (enable == intel_crtc->active)
> >> +		return;
> >> +
> >> +	if (enable && !crtc->state->enable)
> >> +		return;
> > I think we only need to check for !state->enable here. Changing dpms while
> > the crtc is fully of is totally legit. And at least -modesetting loves to
> > do just that iirc.
> >
> > I'll will be caught by state->active implying state->enable, but that's
> > hard to read imo.
> > -Daniel
> As discussed on irc it's not. :-)

Hm there's actually a bug in drm_atomic_helper_connector_dpms I think ...
we seem to unconditionally update crtc_state->active.

Oh I'm missing that ->enable == false also implies that no connectors are
connected to the crtc, so we can't ever end up setting this to true. So
indeed changing active while enable == false is impossible.

With that is it really possible to see have that early return at all?
Should we wrap it in a WARN_ON as impossible?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
  2015-05-12 12:41     ` Maarten Lankhorst
@ 2015-05-12 13:18       ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 13:18 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 02:41:17PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 08:59 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:24:45PM +0200, Maarten Lankhorst wrote:
> >> This should be safe.
> > Usual request: A few more details about what you've changed to help guide
> > the review would be great. E.g. which functions from the atomic helpers
> > you're trying to copy here exactly.
> That's in the diff. :-)

Indeed ;-)

> > It looks like this models set_routing_links. I think it would be rather
> > useful to expose this to drivers as a helper function, maybe with a more
> > useful name like drm_atomic_helper_update_legacy_state or similar.
> I think you're right about this one.
> > Another thing I've noticed is that atomic helpers lost the call to
> > drm_calc_timestamping_constants. Would be good to add that to the same
> > function.
> Yeah, but the precise vblanking stuff is not really atomic friendly,
> so I'm not sure it should be done outside the driver.

Hm what's unfriendly about it? It's definitely a regression to not update
the constants needed by it compared to crtc helpers. I'll go about and fix
that now.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-12  8:18   ` Daniel Vetter
@ 2015-05-12 13:33     ` Maarten Lankhorst
  2015-05-12 13:43       ` Ville Syrjälä
  2015-05-12 16:00       ` Daniel Vetter
  0 siblings, 2 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 13:33 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 10:18 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
>> This kills off most of the transitional helpers and uses atomic plane updates
>> in the modeset path to update everything.
>>
>> Getting rid of the transitional plane helpers meant that planes had to be added
>> in the crtc check function. On modeset a connector can be moved to a different
>> crtc, and this is not handled correctly otherwise.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Ok pile of comments on this one. I don't yet fully grasp it all, but at
> the very bottom I've jotted down a list of ideas for how to move forward
> with this one.
>
>> ---
>>  drivers/gpu/drm/i915/intel_atomic_plane.c |  59 ++-
>>  drivers/gpu/drm/i915/intel_display.c      | 655 ++++++++++++++++++------------
>>  drivers/gpu/drm/i915/intel_drv.h          |   2 +-
>>  drivers/gpu/drm/i915/intel_sprite.c       |  80 +---
>>  4 files changed, 441 insertions(+), 355 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> index 86ba4b2c3a65..85b87e4d4b6e 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
>> @@ -110,32 +110,40 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
>>  				    struct drm_plane_state *state)
>>  {
>>  	struct drm_crtc *crtc = state->crtc;
>> -	struct intel_crtc *intel_crtc;
>> -	struct intel_crtc_state *crtc_state;
>> +	struct drm_crtc_state *crtc_state;
>>  	struct intel_plane *intel_plane = to_intel_plane(plane);
>>  	struct intel_plane_state *intel_state = to_intel_plane_state(state);
>>  
>> -	crtc = crtc ? crtc : plane->crtc;
>> -	intel_crtc = to_intel_crtc(crtc);
>> -
>> +	intel_state->visible = false;
>>  	/*
>>  	 * Both crtc and plane->crtc could be NULL if we're updating a
>>  	 * property while the plane is disabled.  We don't actually have
>>  	 * anything driver-specific we need to test in that case, so
>>  	 * just return success.
>>  	 */
>> -	if (!crtc)
>> +	if (!crtc) {
>> +		DRM_DEBUG_ATOMIC("Invisible: no crtc\n");
>>  		return 0;
>> +	}
>> +
>> +	crtc_state = state->state->crtc_states[drm_crtc_index(crtc)];
> Please reuse drm_atomic_get_crtc_state, this deref magic is hard to read.
> Maybe we should have a nofail variant of those to encode the below WARN_ON
> even ...
Yeah, there are a few places where I use it like this, because in those cases the relevant state should already exist.
>> +	if (WARN_ON(!crtc_state))
>> +		return 0;
>> +
>> +	if (!crtc_state->enable) {
>> +		DRM_DEBUG_ATOMIC("Invisible: crtc off\n");
>>  
>> -	/* FIXME: temporary hack necessary while we still use the plane update
>> -	 * helper. */
>> -	if (state->state) {
>> -		crtc_state =
>> -			intel_atomic_get_crtc_state(state->state, intel_crtc);
>> -		if (IS_ERR(crtc_state))
>> -			return PTR_ERR(crtc_state);
>> -	} else {
>> -		crtc_state = intel_crtc->config;
>> +		/*
>> +		 * Probably allowed after converting to atomic. Right
>> +		 * now it probably means we have the state confused.
>> +		 */
>> +		I915_STATE_WARN_ON(plane->type == DRM_PLANE_TYPE_PRIMARY);
> This is already possible with the primary plane support - you can disable
> it (though not change the mode at the same time).
That explains a few warnings, thanks. :-)
>> +		return 0;
>> +	}
>> +
>> +	if (!crtc_state->active) {
>> +		DRM_DEBUG_ATOMIC("Invisible: dpms off\n");
>> +		return 0;
>>  	}
>>  
>>  	/*
>> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
>>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
>>  	intel_state->clip.x1 = 0;
>>  	intel_state->clip.y1 = 0;
>> -	intel_state->clip.x2 =
>> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
>> -	intel_state->clip.y2 =
>> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
>> -
>> -	/*
>> -	 * Disabling a plane is always okay; we just need to update
>> -	 * fb tracking in a special way since cleanup_fb() won't
>> -	 * get called by the plane helpers.
>> -	 */
>> -	if (state->fb == NULL && plane->state->fb != NULL) {
>> -		/*
>> -		 * 'prepare' is never called when plane is being disabled, so
>> -		 * we need to handle frontbuffer tracking as a special case
>> -		 */
>> -		intel_crtc->atomic.disabled_planes |=
>> -			(1 << drm_plane_index(plane));
>> -	}
>> +	drm_crtc_get_hv_timing(&crtc_state->mode,
>> +			       &intel_state->clip.x2,
>> +			       &intel_state->clip.y2);
> Imo this is obfuscating things a bit, why not just unconditionally copy
> pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
> most platforms must match the primary plane window except for gen2 and
> gen9+.
pipe_src_* is calculated in the same way, and at the time of plane validation the crtc validation hasn't run yet,
so pipe_src_* contains outdated values which break in interesting ways.

>>  
>>  	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
>>  		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 956c9964275d..9610f76a2489 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -100,14 +100,16 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>>  			    const struct intel_crtc_state *pipe_config);
>>  static void chv_prepare_pll(struct intel_crtc *crtc,
>>  			    const struct intel_crtc_state *pipe_config);
>> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
>> +				   struct drm_crtc_state *crtc_state);
> I consider forward declarations evil, but given how much of a mess
> intel_display.c is it doesn't really matter much ;-)
>
>>  static void intel_begin_crtc_commit(struct drm_crtc *crtc);
>>  static void intel_finish_crtc_commit(struct drm_crtc *crtc);
>>  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
>>  	struct intel_crtc_state *crtc_state);
>>  static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
>>  			   int num_connectors);
>> -static void intel_crtc_enable_planes(struct drm_crtc *crtc);
>> -static void intel_crtc_disable_planes(struct drm_crtc *crtc);
>> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
>> +static void intel_post_enable_primary(struct drm_crtc *crtc);
>>  
>>  static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
>>  {
>> @@ -2220,28 +2222,6 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>>  	POSTING_READ(reg);
>>  }
>>  
>> -/**
>> - * intel_enable_primary_hw_plane - enable the primary plane on a given pipe
>> - * @plane:  plane to be enabled
>> - * @crtc: crtc for the plane
>> - *
>> - * Enable @plane on @crtc, making sure that the pipe is running first.
>> - */
>> -static void intel_enable_primary_hw_plane(struct drm_plane *plane,
>> -					  struct drm_crtc *crtc)
>> -{
>> -	struct drm_device *dev = plane->dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> -
>> -	/* If the pipe isn't enabled, we can't pump pixels and may hang */
>> -	assert_pipe_enabled(dev_priv, intel_crtc->pipe);
>> -	to_intel_plane_state(plane->state)->visible = true;
>> -
>> -	dev_priv->display.update_primary_plane(crtc, plane->fb,
>> -					       crtc->x, crtc->y);
>> -}
>> -
>>  static bool need_vtd_wa(struct drm_device *dev)
>>  {
>>  #ifdef CONFIG_INTEL_IOMMU
>> @@ -3161,11 +3141,20 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
>>  {
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_plane_state *plane_state =
>> +		to_intel_plane_state(crtc->primary->state);
>> +	bool was_visible = plane_state->visible;
>>  
>> -	if (dev_priv->display.disable_fbc)
>> +	/* Not supported right now by the helper, but lets be thorough. */
>> +	if (was_visible && !fb)
>> +		intel_pre_disable_primary(crtc);
>> +	else if (was_visible && dev_priv->display.disable_fbc)
>>  		dev_priv->display.disable_fbc(dev);
>>  
>> +	plane_state->visible = !!fb;
>>  	dev_priv->display.update_primary_plane(crtc, fb, x, y);
>> +	if (!was_visible && fb)
>> +		intel_post_enable_primary(crtc);
> This contains a vblank_wait (at least for broadwell) which is a no-go in
> set_base_atomic. Given that this is only used by kgdb and I'm not aware of
> anyone using that and we also don't have any testcase for this code I
> think the best would be to just not touch this and let it keep on
> bitrotting ...
Ok, I'll drop this hunk.

>>  
>>  	return 0;
>>  }
>> @@ -3192,16 +3181,17 @@ static void intel_update_primary_planes(struct drm_device *dev)
>>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  
>>  		drm_modeset_lock(&crtc->mutex, NULL);
>> -		/*
>> -		 * FIXME: Once we have proper support for primary planes (and
>> -		 * disabling them without disabling the entire crtc) allow again
>> -		 * a NULL crtc->primary->fb.
>> -		 */
>> -		if (intel_crtc->active && crtc->primary->fb)
>> +
>> +		if (intel_crtc->active) {
>> +			const struct intel_plane_state *state =
>> +				to_intel_plane_state(crtc->primary->state);
>> +
>>  			dev_priv->display.update_primary_plane(crtc,
>> -							       crtc->primary->fb,
>> -							       crtc->x,
>> -							       crtc->y);
>> +							state->base.fb,
>> +							state->src.x1 >> 16,
>> +							state->src.y1 >> 16);
>> +		}
> I think the above hunk could be split out. And I'm not sure it's required
> really, this is just to catch up on CS flips. Which won't be used any more
> once we have atomic, but until then the legacy state stuff used here
> should be good enough.
?
>> +
>>  		drm_modeset_unlock(&crtc->mutex);
>>  	}
>>  }
>> @@ -4572,20 +4562,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
>>  	}
>>  }
>>  
>> -static void intel_enable_sprite_planes(struct drm_crtc *crtc)
>> -{
>> -	struct drm_device *dev = crtc->dev;
>> -	enum pipe pipe = to_intel_crtc(crtc)->pipe;
>> -	struct drm_plane *plane;
>> -	struct intel_plane *intel_plane;
>> -
>> -	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
>> -		intel_plane = to_intel_plane(plane);
>> -		if (intel_plane->pipe == pipe)
>> -			intel_plane_restore(&intel_plane->base);
>> -	}
>> -}
>> -
>>  void hsw_enable_ips(struct intel_crtc *crtc)
>>  {
>>  	struct drm_device *dev = crtc->base.dev;
>> @@ -4815,44 +4791,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
>>  	hsw_disable_ips(intel_crtc);
>>  }
>>  
>> -static void intel_crtc_enable_planes(struct drm_crtc *crtc)
>> -{
>> -	intel_enable_primary_hw_plane(crtc->primary, crtc);
>> -	intel_enable_sprite_planes(crtc);
>> -	intel_crtc_update_cursor(crtc, true);
>> -
>> -	intel_post_enable_primary(crtc);
>> -}
>> -
>> -static void intel_crtc_disable_planes(struct drm_crtc *crtc)
>> -{
>> -	struct drm_device *dev = crtc->dev;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> -	struct intel_plane *intel_plane;
>> -	int pipe = intel_crtc->pipe;
>> -
>> -	intel_crtc_wait_for_pending_flips(crtc);
>> -
>> -	intel_pre_disable_primary(crtc);
>> -
>> -	intel_crtc_dpms_overlay_disable(intel_crtc);
>> -	for_each_intel_plane(dev, intel_plane) {
>> -		if (intel_plane->pipe == pipe) {
>> -			struct drm_crtc *from = intel_plane->base.crtc;
>> -
>> -			intel_plane->disable_plane(&intel_plane->base,
>> -						   from ?: crtc, true);
>> -		}
>> -	}
>> -
>> -	/*
>> -	 * FIXME: Once we grow proper nuclear flip support out of this we need
>> -	 * to compute the mask of flip planes precisely. For the time being
>> -	 * consider this a flip to a NULL plane.
>> -	 */
>> -	intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
>> -}
>> -
>>  static void ironlake_crtc_enable(struct drm_crtc *crtc)
>>  {
>>  	struct drm_device *dev = crtc->dev;
>> @@ -11061,6 +10999,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
>>  	.load_lut = intel_crtc_load_lut,
>>  	.atomic_begin = intel_begin_crtc_commit,
>>  	.atomic_flush = intel_finish_crtc_commit,
>> +	.atomic_check = intel_atomic_check_crtc,
>>  };
>>  
>>  /* Transitional helper to copy current connector/encoder state to
>> @@ -11426,16 +11365,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>>  	int i;
>>  	bool retry = true;
>>  
>> -	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
>> -		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
>> -		return -EINVAL;
>> -	}
>> -
>> -	if (!check_digital_port_conflicts(state)) {
>> -		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
>> -		return -EINVAL;
>> -	}
>> -
> I think it would help if you'd split out the addition of the crtc_check
> function into a separate prep patch. At least I don't see a depency here
> ...
Yeah but that would be the only thing put in there, oh well got to start somewhere...
>
>> @@ -12275,7 +12333,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>>  	struct drm_atomic_state *state = pipe_config->base.state;
>>  	struct drm_crtc *crtc;
>>  	struct drm_crtc_state *crtc_state;
>> -	int ret = 0;
>> +	int ret;
>>  	int i;
>>  
>>  	ret = __intel_set_mode_checks(state);
>> @@ -12286,14 +12344,14 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>>  	if (ret)
>>  		return ret;
>>  
>> +	__intel_set_mode_update_planes(dev, state);
> This calls crtc->atomic_begin, which does an irq_disable ...
Yeah I tried to handle it by fixing all previous places to prevent atomic evading on modeset,
which means it is mostly safe to do it like this.

>
>> +
>>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>>  		if (!needs_modeset(crtc_state))
>>  			continue;
>>  
>> -		intel_crtc_disable_planes(crtc);
>> +		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>>  		dev_priv->display.crtc_disable(crtc);
>> -		if (!crtc_state->enable)
>> -			drm_plane_helper_disable(crtc->primary);
>>  	}
>>  
>>  	/* Only after disabling all output pipelines that will be changed can we
>> @@ -12305,8 +12363,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>>  
>>  	modeset_update_crtc_power_domains(state);
>>  
>> -	drm_atomic_helper_commit_planes(dev, state);
>> -
>>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
>>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>>  		if (!crtc->state->active)
>> @@ -12314,13 +12370,13 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
>>  
>>  		update_scanline_offset(to_intel_crtc(crtc));
>>  
>> -		dev_priv->display.crtc_enable(crtc);
>> -		intel_crtc_enable_planes(crtc);
>> +		if (needs_modeset(crtc->state))
>> +			dev_priv->display.crtc_enable(crtc);
>>  	}
>>  
>> -	/* FIXME: add subpixel order */
>> +	__intel_set_mode_cleanup_planes(dev, state);
> which is only cleared in atomic_flush here. We need both of these at the
> bottom here. In atomic-helpers-speak the sequence should be
>
> drm_atomic_helper_commit_modeset_disables();
> drm_atomic_helper_commit_modeset_enables();
> drm_atomic_helper_commit_planes();
>
> with the note that our crtc_disable must do the unconditional plane
> disabling itself. I.e. you can't just remove disable_planes without
> replacement, that one needs to be open-coded (using plane->atomic_disable
> if possible).
>
> Doing things this way would also alleviate any need to split up swap_state
> as you do in this patch here.
You're right it could be done like this, but doing commit_planes around the modesets allows
us to test the same code for calculating disable planes during modeset as when togging planes
separately. For example this is useful when a connector moves to a different crtc.

In any case this is cosmetic, and done for bisecting. I can move the swap_states in this commit,
but chose to do it 2 commits later for easier bisection.

I can't move it to before this commit because calling the plane helpers messes up the state.

>>  
>> -	drm_atomic_helper_cleanup_planes(dev, state);
> Please keep this separate and don't hide it in another function, it's a
> distinct step from the hw update (which is now done in the misnamed
> intel_set_mode_cleanup_planes).
Ok.
>
>> +	/* FIXME: add subpixel order */
>>  
>>  	drm_atomic_state_free(state);
>>  
>> @@ -12568,20 +12624,11 @@ intel_modeset_stage_output_state(struct drm_device *dev,
>>  	return 0;
>>  }
>>  
>> -static bool primary_plane_visible(struct drm_crtc *crtc)
>> -{
>> -	struct intel_plane_state *plane_state =
>> -		to_intel_plane_state(crtc->primary->state);
>> -
>> -	return plane_state->visible;
>> -}
>> -
>>  static int intel_crtc_set_config(struct drm_mode_set *set)
>>  {
>>  	struct drm_device *dev;
>>  	struct drm_atomic_state *state = NULL;
>>  	struct intel_crtc_state *pipe_config;
>> -	bool primary_plane_was_visible;
>>  	int ret;
>>  
>>  	BUG_ON(!set);
>> @@ -12620,38 +12667,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
>>  
>>  	intel_update_pipe_size(to_intel_crtc(set->crtc));
>>  
>> -	primary_plane_was_visible = primary_plane_visible(set->crtc);
>> -
>>  	ret = intel_set_mode_with_config(set->crtc, pipe_config);
>> -
>> -	if (ret == 0 &&
>> -	    pipe_config->base.enable &&
>> -	    pipe_config->base.planes_changed &&
>> -	    !needs_modeset(&pipe_config->base)) {
>> -		struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
>> -
>> -		/*
>> -		 * We need to make sure the primary plane is re-enabled if it
>> -		 * has previously been turned off.
>> -		 */
>> -		if (ret == 0 && !primary_plane_was_visible &&
>> -		    primary_plane_visible(set->crtc)) {
>> -			WARN_ON(!intel_crtc->active);
>> -			intel_post_enable_primary(set->crtc);
>> -		}
>> -
>> -		/*
>> -		 * In the fastboot case this may be our only check of the
>> -		 * state after boot.  It would be better to only do it on
>> -		 * the first update, but we don't have a nice way of doing that
>> -		 * (and really, set_config isn't used much for high freq page
>> -		 * flipping, so increasing its cost here shouldn't be a big
>> -		 * deal).
>> -		 */
>> -		if (i915.fastboot && ret == 0)
>> -			intel_modeset_check_state(set->crtc->dev);
>> -	}
>> -
>>  	if (ret) {
>>  		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
>>  			      set->crtc->base.id, ret);
>> @@ -12791,6 +12807,9 @@ bool intel_wm_need_update(struct drm_plane *plane,
>>  	    plane->state->rotation != state->rotation)
>>  		return true;
>>  
>> +	if (plane->state->crtc_w != state->crtc_w)
>> +		return true;
>> +
>>  	return false;
>>  }
>>  
>> @@ -12819,6 +12838,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>>  	unsigned frontbuffer_bits = 0;
>>  	int ret = 0;
>>  
>> +	if (!to_intel_plane_state(plane->state)->visible)
>> +		old_obj = NULL;
>> +
>>  	if (!obj)
>>  		return 0;
>>  
>> @@ -12915,10 +12937,8 @@ intel_check_primary_plane(struct drm_plane *plane,
>>  			  struct intel_plane_state *state)
>>  {
>>  	struct drm_device *dev = plane->dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct drm_crtc *crtc = state->base.crtc;
>>  	struct intel_crtc *intel_crtc;
>> -	struct intel_crtc_state *crtc_state;
>>  	struct drm_framebuffer *fb = state->base.fb;
>>  	struct drm_rect *dest = &state->dst;
>>  	struct drm_rect *src = &state->src;
>> @@ -12926,90 +12946,46 @@ intel_check_primary_plane(struct drm_plane *plane,
>>  	bool can_position = false;
>>  	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
>>  	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
>> -	int ret;
>>  
>> -	crtc = crtc ? crtc : plane->crtc;
>>  	intel_crtc = to_intel_crtc(crtc);
>> -	crtc_state = state->base.state ?
>> -		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
>>  
>>  	if (INTEL_INFO(dev)->gen >= 9) {
>> +		struct intel_crtc_state *crtc_state =
>> +			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
>> +
>>  		min_scale = 1;
>>  		max_scale = skl_max_scale(intel_crtc, crtc_state);
>>  		can_position = true;
>>  	}
>>  
>> -	ret = drm_plane_helper_check_update(plane, crtc, fb,
>> -					    src, dest, clip,
>> -					    min_scale,
>> -					    max_scale,
>> -					    can_position, true,
>> -					    &state->visible);
>> -	if (ret)
>> -		return ret;
>> -
>> -	if (intel_crtc->active) {
>> -		struct intel_plane_state *old_state =
>> -			to_intel_plane_state(plane->state);
>> -
>> -		intel_crtc->atomic.wait_for_flips = true;
>> -
>> -		/*
>> -		 * FBC does not work on some platforms for rotated
>> -		 * planes, so disable it when rotation is not 0 and
>> -		 * update it when rotation is set back to 0.
>> -		 *
>> -		 * FIXME: This is redundant with the fbc update done in
>> -		 * the primary plane enable function except that that
>> -		 * one is done too late. We eventually need to unify
>> -		 * this.
>> -		 */
>> -		if (state->visible &&
>> -		    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
>> -		    dev_priv->fbc.crtc == intel_crtc &&
>> -		    state->base.rotation != BIT(DRM_ROTATE_0)) {
>> -			intel_crtc->atomic.disable_fbc = true;
>> -		}
>> -
>> -		if (state->visible && !old_state->visible) {
>> -			/*
>> -			 * BDW signals flip done immediately if the plane
>> -			 * is disabled, even if the plane enable is already
>> -			 * armed to occur at the next vblank :(
>> -			 */
>> -			if (IS_BROADWELL(dev))
>> -				intel_crtc->atomic.wait_vblank = true;
>> -		}
>> -
>> -		intel_crtc->atomic.fb_bits |=
>> -			INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
>> -
>> -		intel_crtc->atomic.update_fbc = true;
>> -
>> -		if (intel_wm_need_update(plane, &state->base))
>> -			intel_crtc->atomic.update_wm = true;
>> -	}
>> +	return drm_plane_helper_check_update(plane, crtc, fb,
>> +					     src, dest, clip,
>> +					     min_scale, max_scale,
>> +					     can_position, true,
>> +					     &state->visible);
>> +}
>>  
>> -	if (INTEL_INFO(dev)->gen >= 9) {
>> -		ret = skl_update_scaler_users(intel_crtc, crtc_state,
>> -			to_intel_plane(plane), state, 0);
>> -		if (ret)
>> -			return ret;
>> -	}
>> +static void
>> +intel_disable_primary_plane(struct drm_plane *plane,
>> +			    struct drm_crtc *crtc,
>> +			    bool force)
>> +{
>> +	struct drm_device *dev = plane->dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>>  
>> -	return 0;
>> +	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
>>  }
>>  
>>  static void
>>  intel_commit_primary_plane(struct drm_plane *plane,
>> -			   struct intel_plane_state *state)
>> +			   struct intel_plane_state *new_state)
>>  {
>> -	struct drm_crtc *crtc = state->base.crtc;
>> -	struct drm_framebuffer *fb = state->base.fb;
>> +	struct drm_crtc *crtc = new_state->base.crtc;
>> +	struct drm_framebuffer *fb = new_state->base.fb;
>>  	struct drm_device *dev = plane->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_crtc *intel_crtc;
>> -	struct drm_rect *src = &state->src;
>> +	struct drm_rect *src = &new_state->src;
>>  
>>  	crtc = crtc ? crtc : plane->crtc;
>>  	intel_crtc = to_intel_crtc(crtc);
>> @@ -13018,25 +12994,178 @@ intel_commit_primary_plane(struct drm_plane *plane,
>>  	crtc->x = src->x1 >> 16;
>>  	crtc->y = src->y1 >> 16;
>>  
>> -	if (intel_crtc->active) {
>> -		if (state->visible)
>> -			/* FIXME: kill this fastboot hack */
>> -			intel_update_pipe_size(intel_crtc);
>> +	if (!new_state->visible ||
>> +	    WARN_ON(new_state->visible && !crtc->state->active)) {
>> +		intel_disable_primary_plane(plane, crtc, false);
>> +	} else {
>> +		/* FIXME: kill this fastboot hack */
>> +		intel_update_pipe_size(intel_crtc);
>>  
>> -		dev_priv->display.update_primary_plane(crtc, plane->fb,
>> -						       crtc->x, crtc->y);
>> +		dev_priv->display.update_primary_plane(crtc, fb,
>> +						       src->x1 >> 16,
>> +						       src->y1 >> 16);
>>  	}
>>  }
>>  
>> -static void
>> -intel_disable_primary_plane(struct drm_plane *plane,
>> -			    struct drm_crtc *crtc,
>> -			    bool force)
>> +/* Transitional checking here, mostly for plane updates */
>> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
>> +				   struct drm_crtc_state *crtc_state)
>>  {
>> -	struct drm_device *dev = plane->dev;
>> +	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> +	struct drm_atomic_state *state = crtc_state->state;
>> +	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct drm_plane *plane;
>> +	unsigned plane_mask;
>> +	int idx, ret;
>> +	bool mode_changed = needs_modeset(crtc_state);
>> +	bool is_crtc_enabled = crtc_state->active;
>> +	bool was_crtc_enabled = crtc->state->active;
>>  
>> -	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
>> +	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
>> +		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
>> +		return -EINVAL;
>> +	}
> I think we need two have 2 blocks in the crtc_check function: One part
> that just updates watermarks (when state->plane_changed is set) and one
> part that deals with the modeset checks (adding planes, checking cloning
> and all that) when needs_modeset(state) is true.
Makes sense.

>> +
>> +	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
>> +	intel_crtc->atomic.update_wm = mode_changed;
>> +
>> +	idx = crtc->base.id;
>> +	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
>> +		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
>> +		idx, crtc->state->active, intel_crtc->active);
> State computation is async, you cant check this in the atomic_check
> functions. If you think this is useful then we'd need to check this every
> time before we update intel_crtc->active. But we have the various WARN_ON
> all over the place (converted over to crtc->state->active) so I think
> we're more than covered and can just rip out our own intel_crtc->active
> eventually. At least that's kinda been my idea with state->active too.
Yeah, it's a remainder when I had the commits in a different order.
>> +
>> +	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
>> +			 idx, was_crtc_enabled, is_crtc_enabled);
>> +
>> +	plane_mask = crtc_state->plane_mask | crtc->state->plane_mask;
>> +	drm_for_each_plane_mask(plane, dev, plane_mask) {
>> +		int i = drm_plane_index(plane);
>> +		struct drm_plane_state *plane_state = state->plane_states[i];
>> +		struct intel_plane_state *old_plane_state;
>> +		bool turn_off, turn_on, visible, was_visible;
>> +		struct drm_framebuffer *fb;
>> +
>> +		if (!plane_state) {
>> +			const struct drm_plane_helper_funcs *funcs;
>> +			int ret;
>> +
>> +			if (!mode_changed || !plane->state->fb)
>> +				continue;
>> +
>> +			plane_state = drm_atomic_get_plane_state(state, plane);
> We need to check for the crtc constrains before acquiring the plane state,
> otherwise all the locking goes single-threaded. On intel hw we can do that
> because the plane->crtc links are static, you can look at
> intel_plane->pipe.
This code is to make sure all planes are checked when mode_changed && plane->state->fb,
plane_state->visible needs to be updated in that case.

>> +			if (IS_ERR(plane_state))
>> +				return PTR_ERR(plane_state);
>> +
>> +			funcs = plane->helper_private;
>> +			ret = funcs->atomic_check(plane, plane_state);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +		old_plane_state = to_intel_plane_state(plane->state);
>> +
>> +		was_visible = was_crtc_enabled && (old_plane_state->visible ||
>> +			      old_plane_state->hw_enabled);
>> +		visible = to_intel_plane_state(plane_state)->visible &&
>> +			      is_crtc_enabled;
>> +
>> +		if (plane->state->crtc != crtc)
>> +			was_visible = false;
>> +		if (plane_state->crtc != crtc)
>> +			visible = false;
>> +
>> +		if (!was_visible && !visible)
>> +			continue;
>> +
>> +		turn_off = was_visible && (!visible || mode_changed);
>> +		turn_on = visible && (!was_visible || mode_changed);
>> +		fb = plane_state->fb;
>> +
>> +		DRM_DEBUG_ATOMIC("Crtc %i has plane %i with fb %i\n", idx,
>> +			plane->base.id, fb ? fb->base.id : -1);
>> +		DRM_DEBUG_ATOMIC("\tvisible %i -> %i, off %i, on %i, ms %i\n",
>> +			was_visible, visible, turn_off, turn_on, mode_changed);
>> +
>> +		/* plane being turned off as part of modeset or changes? */
>> +		if (intel_wm_need_update(plane, plane_state))
>> +			intel_crtc->atomic.update_wm = true;
>> +
>> +		if (INTEL_INFO(dev)->gen >= 9 &&
>> +		    plane->base.type != DRM_PLANE_TYPE_CURSOR) {
>> +			ret = skl_update_scaler_users(intel_crtc, pipe_config,
>> +					to_intel_plane(plane),
>> +					to_intel_plane_state(plane_state), 0);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +
>> +		/*
>> +		 * 'prepare' is never called when plane is being disabled, so
>> +		 * we need to handle frontbuffer tracking as a special case
>> +		 */
>> +		if (old_plane_state->base.fb && !visible)
>> +			intel_crtc->atomic.disabled_planes |= 1 << i;
>> +
>> +		switch (plane->base.type) {
> We should probably store the frontbuffer tracking mask in intel_plane
> somewhere.

Indeed, but this code's already complicated enough so I felt that initially doing
a 1:1 moving from plane_check to crtc_check would be easier to debug.


>> <snip>
> I'm completely lost as to why we need to move all the plane->atomic_check
> code into a loop in the crtc_check function?
To calculate what needs to happen during atomic_begin and atomic_flush() on each crtc.

>> <snip>
>> @@ -13306,20 +13427,26 @@ intel_disable_cursor_plane(struct drm_plane *plane,
>>  
>>  static void
>>  intel_commit_cursor_plane(struct drm_plane *plane,
>> -			  struct intel_plane_state *state)
>> +			  struct intel_plane_state *new_state)
>>  {
>> -	struct drm_crtc *crtc = state->base.crtc;
>> +	struct drm_crtc *crtc = new_state->base.crtc;
>>  	struct drm_device *dev = plane->dev;
>>  	struct intel_crtc *intel_crtc;
>> -	struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
>> +	struct drm_i915_gem_object *obj = intel_fb_obj(new_state->base.fb);
>>  	uint32_t addr;
>>  
>>  	crtc = crtc ? crtc : plane->crtc;
>>  	intel_crtc = to_intel_crtc(crtc);
>>  
>> -	plane->fb = state->base.fb;
>> -	crtc->cursor_x = state->base.crtc_x;
>> -	crtc->cursor_y = state->base.crtc_y;
>> +	plane->fb = new_state->base.fb;
>> +	crtc->cursor_x = new_state->base.crtc_x;
>> +	crtc->cursor_y = new_state->base.crtc_y;
>> +
>> +	if (!new_state->visible ||
>> +	    WARN_ON(new_state->visible && !crtc->state->active)) {
> As an aside: We must move over to compute ->visible irrespective of
> ->active. I haven't check whether you fix that later on already, but this
> is important to be able to check wm constraints correctly. The
> crtc_state->active handling should imo be done in the common code by
> simply not calling any of the plane or crtc functions hw update if the
> crtc is off.
In the crtc_check function I'm setting:
intel_crtc->atomic.update_wm = mode_changed; ?

It means recalculating wm on dpms off->on too but is that really such a burden?
Treating crtc->state->active as the only knob for crtc on/off simplifies things.
> Of course that means we need to add all planes both for ->mode_changed and
> for ->active_changed, but needs_modeset(crtc_state) takes care of that
> already.
This is exactly why I add all planes in the check function.

> Aside: The idea behind the split between drm_atomic_helper_check_planes
> and drm_atomic_helper_check_modeset is that the former handles planes-only
> updates while the latter handles modeset. We can't fully use
> check_modesets because we don't use crtc helpers, but I think reusing the
> same idea still has merit:
>
> - We create an intel_check_modeset which calls the helper's check_modeset
>   plus afterwards all the modeset checks (dpll, cloning checks, adding
>   plane states and global resources) that we do in crtc_compute_config and
>   friends right now. That one would also add plane states as needed (but
>   not call plane->atomic_check). All of this would be skipped if
>   needs_modeset isn't true.
Might be doable if we do add planes between check_modeset and check_planes.

Originally I tried it in intel_modeset_compute_config, but that didn't work when
the crtc was different from the one that had the argument passed.

> - After that we'd call the helper's plane_check functions which does
>   exclusively plane-update related checks. crtc/plane->atomic_check
>   wouldn't contain any modeset related checks (like the encoder cloning or
>   plane adding you're doing right now).
I think encoder cloning ought to be part of the crtc check since its done on each crtc.
>> <snip>
> Ok I think overall this patch is too big and needs to be split a bit. The
> following should be doable as prep-patches:
> - set_base_atomic (if we dare to touch it at all)
I think I'll drop it.
> - shuffling the crtc modeset check logic around to add plane states as
>   needed, making sure we only run that if needs_modeset indicates so.
I think splitting this out would break the transitional helpers, they rely on the plane state not being there so the state is correctly updated
when the transitional plane helpers run, else we would cause stale state to be swapped. :-(
> - Pushing the checks for intel_crtc->active or crtc->state->active out of
>   the low-level plane code up into higher level atomic plane code (and the
>   few legacy entry points for plane updates that we still have maybe, but
>   those should be covered I think with the universal plane + transitional
>   helpers).
I fear this might break the transitional helper calls too, the transitional helpers require the transitional state to be mostly in sync with the atomic state.

> Then we can put in the meat of this patch, i.e. replacing the helpers with
> atomic updates in the modeset code.
I wish that would work. ;-)

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c
  2015-05-12  9:03   ` Daniel Vetter
@ 2015-05-12 13:36     ` Maarten Lankhorst
  0 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 13:36 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 11:03 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:24:56PM +0200, Maarten Lankhorst wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_atomic.c | 10 +++-------
>>  drivers/gpu/drm/i915/intel_sprite.c |  4 ++--
>>  2 files changed, 5 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
>> index 7ed8033aae60..ace6aeeb1359 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>> @@ -176,7 +176,7 @@ int intel_atomic_commit(struct drm_device *dev,
>>  			continue;
>>  		}
>>  
>> -		to_intel_crtc(crtc)->config->scaler_state =
>> +		to_intel_crtc_state(crtc->state)->scaler_state =
>>  			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
>>  
>>  		if (INTEL_INFO(dev)->gen >= 9)
>> @@ -241,14 +241,10 @@ intel_connector_atomic_get_property(struct drm_connector *connector,
>>  struct drm_crtc_state *
>>  intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  	struct intel_crtc_state *crtc_state;
>>  
>> -	if (WARN_ON(!intel_crtc->config))
>> -		crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
>> -	else
>> -		crtc_state = kmemdup(intel_crtc->config,
>> -				     sizeof(*intel_crtc->config), GFP_KERNEL);
>> +	crtc_state = kmemdup(crtc->state,
>> +			     sizeof(*crtc_state), GFP_KERNEL);
> Separate patch for this hunk please.
> -Daniel
>
Ok.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c
  2015-05-12  9:20   ` Daniel Vetter
@ 2015-05-12 13:41     ` Maarten Lankhorst
  0 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 13:41 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 11:20 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:25:01PM +0200, Maarten Lankhorst wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_psr.c | 25 ++++++++++++++-----------
>>  1 file changed, 14 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
>> index 5ee0fa57ed19..868817402c11 100644
>> --- a/drivers/gpu/drm/i915/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/intel_psr.c
>> @@ -73,14 +73,15 @@ static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
>>  }
>>  
>>  static void intel_psr_write_vsc(struct intel_dp *intel_dp,
>> -				    struct edp_vsc_psr *vsc_psr)
>> +				struct edp_vsc_psr *vsc_psr)
>>  {
>>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>>  	struct drm_device *dev = dig_port->base.base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
>> -	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder);
>> -	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config->cpu_transcoder);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(dig_port->base.base.crtc->state);
>> +	u32 ctl_reg = HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder);
>> +	u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(pipe_config->cpu_transcoder);
>>  	uint32_t *data = (uint32_t *) vsc_psr;
>>  	unsigned int i;
>>  
>> @@ -282,13 +283,13 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
>>  				EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
>>  }
>>  
>> -static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
>> +static bool intel_psr_match_conditions(struct intel_dp *intel_dp,
>> +				       struct intel_crtc_state *pipe_config)
> I spotted this pattern in a few other places as well already, where you
> add a local variable to avoid the dereference dance again. But this is
> called from a pre_enable hook, i.e. we can just directly access
> crtc->state to get at the right pipe config. If you instead pass it as a
> parameter I have to hunt around to make sure it's the right one.
>
> Imo passing pipe_config should only be done if the code can be called in
> the compute_config/check phase or in the disable phase. That then gives
> reviewers a nice heads-up about the potential trickiness.
>
Ok.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-12 13:33     ` Maarten Lankhorst
@ 2015-05-12 13:43       ` Ville Syrjälä
  2015-05-12 13:46         ` Ville Syrjälä
  2015-05-12 15:31         ` Daniel Vetter
  2015-05-12 16:00       ` Daniel Vetter
  1 sibling, 2 replies; 98+ messages in thread
From: Ville Syrjälä @ 2015-05-12 13:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 03:33:12PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 10:18 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
> >> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
> >>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
> >>  	intel_state->clip.x1 = 0;
> >>  	intel_state->clip.y1 = 0;
> >> -	intel_state->clip.x2 =
> >> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
> >> -	intel_state->clip.y2 =
> >> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
> >> -
> >> -	/*
> >> -	 * Disabling a plane is always okay; we just need to update
> >> -	 * fb tracking in a special way since cleanup_fb() won't
> >> -	 * get called by the plane helpers.
> >> -	 */
> >> -	if (state->fb == NULL && plane->state->fb != NULL) {
> >> -		/*
> >> -		 * 'prepare' is never called when plane is being disabled, so
> >> -		 * we need to handle frontbuffer tracking as a special case
> >> -		 */
> >> -		intel_crtc->atomic.disabled_planes |=
> >> -			(1 << drm_plane_index(plane));
> >> -	}
> >> +	drm_crtc_get_hv_timing(&crtc_state->mode,
> >> +			       &intel_state->clip.x2,
> >> +			       &intel_state->clip.y2);
> > Imo this is obfuscating things a bit, why not just unconditionally copy
> > pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
> > most platforms must match the primary plane window except for gen2 and
> > gen9+.
> pipe_src_* is calculated in the same way,

Except we may end up rounding pipe_src_w down if we have
double-wide/dual link lvds etc., and we definitely need to clip the
planes against the real pipe src size.

> and at the time of plane validation the crtc validation hasn't run yet,
> so pipe_src_* contains outdated values which break in interesting ways.

Just check crtc first. Or actually we probably need pre + post crtc
checks since we want to do wm compute and such after the planes have
been handled.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c
  2015-05-12  9:22   ` Daniel Vetter
@ 2015-05-12 13:43     ` Maarten Lankhorst
  0 siblings, 0 replies; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 13:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 11:22 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:25:03PM +0200, Maarten Lankhorst wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c | 33 ++++++++++++++++++---------------
>>  1 file changed, 18 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index eda1b22c3111..e6876faca7f0 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -1536,7 +1536,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	enum port port = dp_to_dig_port(intel_dp)->port;
>>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
>> -	struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->base.state);
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>>  
>>  	/*
>>  	 * There are four kinds of DP registers:
>> @@ -1564,7 +1566,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
>>  	intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
>>  	intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count);
>>  
>> -	if (crtc->config->has_audio)
>> +	if (pipe_config->has_audio)
>>  		intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE;
>>  
>>  	/* Split out the IBX/CPU vs CPT settings */
>> @@ -2504,6 +2506,8 @@ static void intel_enable_dp(struct intel_encoder *encoder)
>>  	struct drm_device *dev = encoder->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->base.state);
>>  	uint32_t dp_reg = I915_READ(intel_dp->output_reg);
>>  	unsigned int lane_mask = 0x0;
>>  
>> @@ -2532,7 +2536,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
>>  	intel_dp_complete_link_train(intel_dp);
>>  	intel_dp_stop_link_train(intel_dp);
>>  
>> -	if (crtc->config->has_audio) {
>> +	if (pipe_config->has_audio) {
>>  		DRM_DEBUG_DRIVER("Enabling DP audio on pipe %c\n",
>>  				 pipe_name(crtc->pipe));
>>  		intel_audio_codec_enable(encoder);
>> @@ -2741,6 +2745,8 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>>  	struct intel_crtc *intel_crtc =
>>  		to_intel_crtc(encoder->base.crtc);
>>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(intel_crtc->base.state);
>>  	int pipe = intel_crtc->pipe;
>>  	int data, i, stagger;
>>  	u32 val;
>> @@ -2782,13 +2788,13 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
>>  	}
>>  
>>  	/* Data lane stagger programming */
>> -	if (intel_crtc->config->port_clock > 270000)
>> +	if (pipe_config->port_clock > 270000)
>>  		stagger = 0x18;
>> -	else if (intel_crtc->config->port_clock > 135000)
>> +	else if (pipe_config->port_clock > 135000)
>>  		stagger = 0xd;
>> -	else if (intel_crtc->config->port_clock > 67500)
>> +	else if (pipe_config->port_clock > 67500)
>>  		stagger = 0x7;
>> -	else if (intel_crtc->config->port_clock > 33750)
>> +	else if (pipe_config->port_clock > 33750)
>>  		stagger = 0x4;
>>  	else
>>  		stagger = 0x2;
>> @@ -4302,7 +4308,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
>>  	if (WARN_ON(!intel_encoder->base.crtc))
>>  		return;
>>  
>> -	if (!to_intel_crtc(intel_encoder->base.crtc)->active)
>> +	if (!intel_encoder->base.crtc->state->active)
>>  		return;
>>  
>>  	/* Try to read receiver status if the link appears to be up */
>> @@ -5255,7 +5261,8 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
>>  	struct intel_encoder *encoder;
>>  	struct intel_digital_port *dig_port = NULL;
>>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
>> -	struct intel_crtc *intel_crtc = NULL;
>> +	struct intel_crtc *intel_crtc;
>> +	struct intel_crtc_state *pipe_config;
>>  	u32 reg, val;
>>  	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
>>  
>> @@ -5277,6 +5284,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
> set_drrs_state is also called from _disable hooks, which means you need to
> pass the right pipe_config explicitly.
>
Argh, missed that, thanks.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-12 13:43       ` Ville Syrjälä
@ 2015-05-12 13:46         ` Ville Syrjälä
  2015-05-12 15:31         ` Daniel Vetter
  1 sibling, 0 replies; 98+ messages in thread
From: Ville Syrjälä @ 2015-05-12 13:46 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:43:09PM +0300, Ville Syrjälä wrote:
> On Tue, May 12, 2015 at 03:33:12PM +0200, Maarten Lankhorst wrote:
> > Op 12-05-15 om 10:18 schreef Daniel Vetter:
> > > On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
> > >> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
> > >>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
> > >>  	intel_state->clip.x1 = 0;
> > >>  	intel_state->clip.y1 = 0;
> > >> -	intel_state->clip.x2 =
> > >> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
> > >> -	intel_state->clip.y2 =
> > >> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
> > >> -
> > >> -	/*
> > >> -	 * Disabling a plane is always okay; we just need to update
> > >> -	 * fb tracking in a special way since cleanup_fb() won't
> > >> -	 * get called by the plane helpers.
> > >> -	 */
> > >> -	if (state->fb == NULL && plane->state->fb != NULL) {
> > >> -		/*
> > >> -		 * 'prepare' is never called when plane is being disabled, so
> > >> -		 * we need to handle frontbuffer tracking as a special case
> > >> -		 */
> > >> -		intel_crtc->atomic.disabled_planes |=
> > >> -			(1 << drm_plane_index(plane));
> > >> -	}
> > >> +	drm_crtc_get_hv_timing(&crtc_state->mode,
> > >> +			       &intel_state->clip.x2,
> > >> +			       &intel_state->clip.y2);
> > > Imo this is obfuscating things a bit, why not just unconditionally copy
> > > pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
> > > most platforms must match the primary plane window except for gen2 and
> > > gen9+.
> > pipe_src_* is calculated in the same way,
> 
> Except we may end up rounding pipe_src_w down if we have
> double-wide/dual link lvds etc., and we definitely need to clip the
> planes against the real pipe src size.

Oh and we definitely want to keep the 'user mode == pipe src'
assumptions to a minimum so that we might some day finish the "expose
panel fitter to userland" task.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 32/42] drm/i915: Calculate haswell plane workaround.
  2015-05-12  9:43   ` Daniel Vetter
@ 2015-05-12 14:05     ` Maarten Lankhorst
  2015-05-12 16:54       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 14:05 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 11:43 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:25:08PM +0200, Maarten Lankhorst wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_display.c | 109 +++++++++++++++++++++++++----------
>>  drivers/gpu/drm/i915/intel_drv.h     |   2 +
>>  2 files changed, 81 insertions(+), 30 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 7bc78b49f9f4..7a79659dca00 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -4848,35 +4848,6 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
>>  	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
>>  }
>>  
>> -/*
>> - * This implements the workaround described in the "notes" section of the mode
>> - * set sequence documentation. When going from no pipes or single pipe to
>> - * multiple pipes, and planes are enabled after the pipe, we need to wait at
>> - * least 2 vblanks on the first pipe before enabling planes on the second pipe.
>> - */
>> -static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
>> -{
>> -	struct drm_device *dev = crtc->base.dev;
>> -	struct intel_crtc *crtc_it, *other_active_crtc = NULL;
>> -
>> -	/* We want to get the other_active_crtc only if there's only 1 other
>> -	 * active crtc. */
>> -	for_each_intel_crtc(dev, crtc_it) {
>> -		if (!crtc_it->active || crtc_it == crtc)
>> -			continue;
>> -
>> -		if (other_active_crtc)
>> -			return;
>> -
>> -		other_active_crtc = crtc_it;
>> -	}
>> -	if (!other_active_crtc)
>> -		return;
>> -
>> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
>> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
>> -}
>> -
>>  static void haswell_crtc_enable(struct drm_crtc *crtc)
>>  {
>>  	struct drm_device *dev = crtc->dev;
>> @@ -4967,7 +4938,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>>  
>>  	/* If we change the relative order between pipe/planes enabling, we need
>>  	 * to change the workaround. */
>> -	haswell_mode_set_planes_workaround(intel_crtc);
>> +	if (pipe_config->hsw_workaround_pipe != INVALID_PIPE) {
>> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
>> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
>> +	}
>>  }
>>  
>>  static void ironlake_pfit_disable(struct intel_crtc *crtc)
>> @@ -12147,6 +12121,74 @@ done:
>>  	return ret;
>>  }
>>  
>> +/*
>> + * This implements the workaround described in the "notes" section of the mode
>> + * set sequence documentation. When going from no pipes or single pipe to
>> + * multiple pipes, and planes are enabled after the pipe, we need to wait at
>> + * least 2 vblanks on the first pipe before enabling planes on the second pipe.
>> + */
>> +static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
>> +{
>> +	struct drm_crtc *crtc;
>> +	struct drm_crtc_state *crtc_state;
>> +	struct intel_crtc_state *first_crtc_state = NULL, *other_crtc_state = NULL;
>> +	struct intel_crtc *intel_crtc, *first_crtc = NULL, *enabled_crtc;
>> +	int enabled_crtcs = 0, ret, i;
>> +
>> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
>> +		struct intel_crtc_state *pipe_config =
>> +			to_intel_crtc_state(crtc_state);
>> +
>> +		pipe_config->hsw_workaround_pipe = INVALID_PIPE;
> This kind of state resetting should be done in duplicate_state.
The v2 of this patch uses intel_crtc->atomic.hsw_workaround pipe, which would work better. :)
>> +
>> +		if (!crtc_state->active)
>> +			continue;
>> +
>> +		if (!needs_modeset(crtc_state)) {
>> +			enabled_crtcs++;
>> +			enabled_crtc = to_intel_crtc(crtc);
>> +			continue;
>> +		}
>> +
>> +		if (first_crtc) {
>> +			other_crtc_state = pipe_config;
>> +			break;
>> +		}
>> +		first_crtc = to_intel_crtc(crtc);
>> +		first_crtc_state = pipe_config;
>> +	}
>> +
>> +	/* No workaround needed? */
>> +	if (!first_crtc || enabled_crtcs > 1)
>> +		return 0;
>> +
>> +	for_each_intel_crtc(state->dev, intel_crtc) {
>> +		if (state->crtcs[drm_crtc_index(&intel_crtc->base)])
>> +			continue;
>> +
>> +		ret = drm_modeset_lock(&intel_crtc->base.mutex,
>> +				       state->acquire_ctx);
>> +		if (ret)
>> +			return ret;
>> +
>> +		if (!intel_crtc->base.state->active)
>> +			continue;
> Imo just unconditionally acquire the crtc state, there' shouldn't be any
> harm in that (as long as we leave mode/active/planes_changed untouched).
Probably.
>> +
>> +		/* 2 enabled crtcs means no need for w/a */
>> +		if (++enabled_crtcs >= 2)
>> +			return 0;
>> +
>> +		enabled_crtc = intel_crtc;
>> +	}
>> +
>> +	if (enabled_crtcs == 1)
>> +		first_crtc_state->hsw_workaround_pipe = enabled_crtc->pipe;
> first_crtc_state could be miscomputed if 1 crtc is already on and you add
> another one. Then first_crtc will point at the other crtc since that's the
> only one at first in the atomic set. Imo a simpler algo would be:
No, in that case enabled_crtcs != 0 and enabled_crtc is set to the correct crtc.


> 1. Check whether your activating any crtc at all.
> 2. If so add all crtc states.
> 3. Same loop as the old one, just using for_each_crtc_in_state.
>
> There's other cases with shared resources where we need to grab all crtc
> locks already anyway (shared dpll), trying to be clever doesn't seem
> beneficial. And if this indeed becomes a problem then we need a global
> state ww mutex and use that (instead of crtc locks) for this book-keeping:
> First enable crtc would set global_state->hsw_wa_pipe, 2nd and later would
> clear it. We might need this eventually (I've heard rumours about people
> not liking stalls when unplugging external screens that much), but let's
> not overcomplicate things while we do this conversion.
You would still need it when disabling crtc's then. To do it right you would need to keep crtc->active,
or use a crtc_mask, but that would be abused so I'd rather not. The crtc lock is also needed so the
other crtc's cannot be disabled or enabled while modesetting, but I guess always taking the
connector_mutex for that could work too.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-12 10:03   ` Daniel Vetter
@ 2015-05-12 14:07     ` Maarten Lankhorst
  2015-05-12 16:57       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 14:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 12:03 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 4:25 PM, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
>>
>>                 for_each_intel_crtc(dev, crtc) {
>>                         if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
>> -                               enabled_crtcs++;
>> -                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
>>                                 active_crtcs++;
>>                 }
>>                 I915_STATE_WARN(pll->active != active_crtcs,
>>                      "pll active crtcs mismatch (expected %i, found %i)\n",
>>                      pll->active, active_crtcs);
>> -               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
>> +               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
>>                      "pll enabled crtcs mismatch (expected %i, found %i)\n",
>> -                    hweight32(pll->config.crtc_mask), enabled_crtcs);
>> +                    hweight32(pll->config.crtc_mask), active_crtcs);
>
> Missed one: Why do you remove this? Imo that's a fairly crucial
> consistency check.
> -Daniel
It's not removed, but crtc->active is the same as crtc->base.state->active now. The check still works as intended. :-)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1
  2015-05-12 10:11   ` Daniel Vetter
@ 2015-05-12 14:13     ` Maarten Lankhorst
  2015-05-12 17:01       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 14:13 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 12:11 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:25:10PM +0200, Maarten Lankhorst wrote:
>> Removed some occurences, roughly based on where the errors of
>> removing crtc->config occured. Because it's used a lot in this
>> file the changes are done in passes.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_display.c | 205 ++++++++++++++++++-----------------
>>  drivers/gpu/drm/i915/intel_drv.h     |   4 +-
>>  drivers/gpu/drm/i915/intel_lvds.c    |   2 +-
>>  3 files changed, 105 insertions(+), 106 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 004067bd0b6c..fb2ecb65aaaa 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -1141,29 +1141,20 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
>>  #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
>>  #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
>>  
>> -struct intel_shared_dpll *
>> -intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
>> -{
>> -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>> -
>> -	if (crtc->config->shared_dpll < 0)
>> -		return NULL;
>> -
>> -	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
>> -}
>> -
>>  /* For ILK+ */
>>  void assert_shared_dpll(struct drm_i915_private *dev_priv,
>> -			struct intel_shared_dpll *pll,
>> +			enum intel_dpll_id shared_dpll,
>>  			bool state)
>>  {
>> -	bool cur_state;
>>  	struct intel_dpll_hw_state hw_state;
>> +	struct intel_shared_dpll *pll;
>> +	bool cur_state;
>>  
>> -	if (WARN (!pll,
>> +	if (WARN(shared_dpll < 0,
>>  		  "asserting DPLL %s with no DPLL\n", state_string(state)))
>>  		return;
>>  
>> +	pll = &dev_priv->shared_dplls[shared_dpll];
>>  	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
>>  	I915_STATE_WARN(cur_state != state,
>>  	     "%s assertion failure (expected %s, current %s)\n",
>> @@ -1691,7 +1682,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	int reg = DPLL(crtc->pipe);
>> -	u32 dpll = crtc->config->dpll_hw_state.dpll;
>> +	u32 dpll = pipe_config->dpll_hw_state.dpll;
> Lots of your patches are sprinkled with unrelated crtc->config ->
> pipe_config conversions. Or just plain rolling out of a local variable
> instead of accessing some other pointer. That makes it fairly hard to
> review them for a given topic (like shared dpll here) since it's never
> clear whether it really includes everything, and what's the reason for all
> the other hunks.
>
>>  
>>  	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
>>  
>> @@ -1721,7 +1712,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
>>  
>>  	if (INTEL_INFO(dev)->gen >= 4) {
>>  		I915_WRITE(DPLL_MD(crtc->pipe),
>> -			   crtc->config->dpll_hw_state.dpll_md);
>> +			   pipe_config->dpll_hw_state.dpll_md);
>>  	} else {
>>  		/* The pixel multiplier can only be updated once the
>>  		 * DPLL is enabled and the clocks are stable.
>> @@ -1859,20 +1850,19 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
>>  		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
>>  }
>>  
>> -static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
>> +static void intel_prepare_shared_dpll(struct drm_i915_private *dev_priv,
>> +				      enum intel_dpll_id shared_dpll)
>>  {
>> -	struct drm_device *dev = crtc->base.dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
>> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
> Why change anything here? This is called from enable hooks, so can keep on
> accessing intel_crtc->state ... or not?
I got rid of intel_crtc_to_shared_dpll, because it only required pipe_config->shared_dpll I felt it could be passed as argument instead.

>>  
>> -	if (WARN_ON(pll == NULL))
>> +	if (WARN_ON(shared_dpll < 0))
>>  		return;
>>  
>>  	WARN_ON(!pll->config.crtc_mask);
>>  	if (pll->active == 0) {
>>  		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
>>  		WARN_ON(pll->on);
>> -		assert_shared_dpll_disabled(dev_priv, pll);
>> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
>>  
>>  		pll->mode_set(dev_priv, pll);
>>  	}
>> @@ -1886,25 +1876,23 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
>>   * The PCH PLL needs to be enabled before the PCH transcoder, since it
>>   * drives the transcoder clock.
>>   */
>> -static void intel_enable_shared_dpll(struct intel_crtc *crtc)
>> +static void intel_enable_shared_dpll(struct drm_i915_private *dev_priv,
>> +				     enum intel_dpll_id shared_dpll)
>>  {
>> -	struct drm_device *dev = crtc->base.dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
>> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
>>  
>> -	if (WARN_ON(pll == NULL))
>> +	if (WARN_ON(shared_dpll < 0))
>>  		return;
>>  
>>  	if (WARN_ON(pll->config.crtc_mask == 0))
>>  		return;
>>  
>> -	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
>> -		      pll->name, pll->active, pll->on,
>> -		      crtc->base.base.id);
>> +	DRM_DEBUG_KMS("enable %s (active %d, on? %d)\n",
>> +		      pll->name, pll->active, pll->on);
>>  
>>  	if (pll->active++) {
>>  		WARN_ON(!pll->on);
>> -		assert_shared_dpll_enabled(dev_priv, pll);
>> +		assert_shared_dpll_enabled(dev_priv, shared_dpll);
>>  		return;
>>  	}
>>  	WARN_ON(pll->on);
>> @@ -1916,30 +1904,29 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
>>  	pll->on = true;
>>  }
>>  
>> -static void intel_disable_shared_dpll(struct intel_crtc *crtc)
>> +static void intel_disable_shared_dpll(struct drm_i915_private *dev_priv,
>> +				      enum intel_dpll_id shared_dpll)
>>  {
>> -	struct drm_device *dev = crtc->base.dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
>> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
>> +
>> +	if (shared_dpll < 0)
>> +		return;
>>  
>>  	/* PCH only available on ILK+ */
>> -	BUG_ON(INTEL_INFO(dev)->gen < 5);
>> -	if (WARN_ON(pll == NULL))
>> -	       return;
>> +	BUG_ON(dev_priv->info.gen < 5);
>>  
>>  	if (WARN_ON(pll->config.crtc_mask == 0))
>>  		return;
>>  
>> -	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
>> -		      pll->name, pll->active, pll->on,
>> -		      crtc->base.base.id);
>> +	DRM_DEBUG_KMS("disable %s (active %d, on? %d)\n",
>> +		      pll->name, pll->active, pll->on);
>>  
>>  	if (WARN_ON(pll->active == 0)) {
>> -		assert_shared_dpll_disabled(dev_priv, pll);
>> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
>>  		return;
>>  	}
>>  
>> -	assert_shared_dpll_enabled(dev_priv, pll);
>> +	assert_shared_dpll_enabled(dev_priv, shared_dpll);
>>  	WARN_ON(!pll->on);
>>  	if (--pll->active)
>>  		return;
>> @@ -1964,8 +1951,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
>>  	BUG_ON(!HAS_PCH_SPLIT(dev));
>>  
>>  	/* Make sure PCH DPLL is enabled */
>> -	assert_shared_dpll_enabled(dev_priv,
>> -				   intel_crtc_to_shared_dpll(intel_crtc));
>> +	assert_shared_dpll_enabled(dev_priv, pipe_config->shared_dpll);
>>  
>>  	/* FDI must be feeding us bits for PCH ports */
>>  	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
>> @@ -2126,7 +2112,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
>>  		else
>>  			assert_pll_enabled(dev_priv, pipe);
>>  	else {
>> -		if (crtc->config->has_pch_encoder) {
>> +		if (pipe_config->has_pch_encoder) {
>>  			/* if driving the PCH, we need FDI enabled */
>>  			assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
>>  			assert_fdi_tx_pll_enabled(dev_priv,
>> @@ -2622,6 +2608,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>  	bool visible = to_intel_plane_state(primary->state)->visible;
>>  	struct drm_i915_gem_object *obj;
>>  	int plane = intel_crtc->plane;
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->state);
>>  	unsigned long linear_offset;
>>  	u32 dspcntr;
>>  	u32 reg = DSPCNTR(plane);
>> @@ -2655,13 +2643,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>  		 * which should always be the user's requested size.
>>  		 */
>>  		I915_WRITE(DSPSIZE(plane),
>> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
>> -			   (intel_crtc->config->pipe_src_w - 1));
>> +			   ((pipe_config->pipe_src_h - 1) << 16) |
>> +			   (pipe_config->pipe_src_w - 1));
>>  		I915_WRITE(DSPPOS(plane), 0);
>>  	} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
>>  		I915_WRITE(PRIMSIZE(plane),
>> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
>> -			   (intel_crtc->config->pipe_src_w - 1));
>> +			   ((pipe_config->pipe_src_h - 1) << 16) |
>> +			   (pipe_config->pipe_src_w - 1));
>>  		I915_WRITE(PRIMPOS(plane), 0);
>>  		I915_WRITE(PRIMCNSTALPHA(plane), 0);
>>  	}
>> @@ -2719,14 +2707,14 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
>>  		dspcntr |= DISPPLANE_ROTATE_180;
>>  
>> -		x += (intel_crtc->config->pipe_src_w - 1);
>> -		y += (intel_crtc->config->pipe_src_h - 1);
>> +		x += (pipe_config->pipe_src_w - 1);
>> +		y += (pipe_config->pipe_src_h - 1);
>>  
>>  		/* Finding the last pixel of the last line of the display
>>  		data and adding to linear_offset*/
>>  		linear_offset +=
>> -			(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
>> -			(intel_crtc->config->pipe_src_w - 1) * pixel_size;
>> +			(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
>> +			(pipe_config->pipe_src_w - 1) * pixel_size;
> Unrelated changes above, or do I miss something?
What's unrelated? But yeah I mostly split it up by fixing things up until it started compiling again. I should split the display stuff up further.

>>  	}
>>  
>>  	I915_WRITE(reg, dspcntr);
>> @@ -2818,17 +2806,20 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>  					       fb->pitches[0]);
>>  	linear_offset -= intel_crtc->dspaddr_offset;
>>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
>> +		struct intel_crtc_state *pipe_config =
>> +			to_intel_crtc_state(crtc->state);
>> +
>>  		dspcntr |= DISPPLANE_ROTATE_180;
>>  
>>  		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
>> -			x += (intel_crtc->config->pipe_src_w - 1);
>> -			y += (intel_crtc->config->pipe_src_h - 1);
>> +			x += (pipe_config->pipe_src_w - 1);
>> +			y += (pipe_config->pipe_src_h - 1);
>>  
>>  			/* Finding the last pixel of the last line of the display
>>  			data and adding to linear_offset*/
>>  			linear_offset +=
>> -				(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
>> -				(intel_crtc->config->pipe_src_w - 1) * pixel_size;
>> +				(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
>> +				(pipe_config->pipe_src_w - 1) * pixel_size;
>>  		}
>>  	}
>>  
>> @@ -2901,12 +2892,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
>>  	struct intel_crtc_scaler_state *scaler_state;
>>  	int i;
>>  
>> -	if (!intel_crtc || !intel_crtc->config)
>> +	if (!intel_crtc)
>>  		return;
>>  
>>  	dev = intel_crtc->base.dev;
>>  	dev_priv = dev->dev_private;
>> -	scaler_state = &intel_crtc->config->scaler_state;
>> +	scaler_state =
>> +		&to_intel_crtc_state(intel_crtc->base.state)->scaler_state;
>>  
>>  	/* loop through and disable scalers that aren't in use */
>>  	for (i = 0; i < intel_crtc->num_scalers; i++) {
>> @@ -3298,6 +3290,8 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	const struct drm_display_mode *adjusted_mode;
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->base.state);
>>  
>>  	if (!i915.fastboot)
>>  		return;
>> @@ -3316,20 +3310,20 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
>>  	 * then update the pipesrc and pfit state, even on the flip path.
>>  	 */
>>  
>> -	adjusted_mode = &crtc->config->base.adjusted_mode;
>> +	adjusted_mode = &pipe_config->base.adjusted_mode;
>>  
>>  	I915_WRITE(PIPESRC(crtc->pipe),
>>  		   ((adjusted_mode->crtc_hdisplay - 1) << 16) |
>>  		   (adjusted_mode->crtc_vdisplay - 1));
>> -	if (!crtc->config->pch_pfit.enabled &&
>> +	if (!pipe_config->pch_pfit.enabled &&
>>  	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
>>  	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
>>  		I915_WRITE(PF_CTL(crtc->pipe), 0);
>>  		I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
>>  		I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
>>  	}
>> -	crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
>> -	crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
>> +	pipe_config->pipe_src_w = adjusted_mode->crtc_hdisplay;
>> +	pipe_config->pipe_src_h = adjusted_mode->crtc_vdisplay;
>>  }
>>  
>>  static void intel_fdi_normal_train(struct drm_crtc *crtc)
>> @@ -3379,6 +3373,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->state);
>>  	int pipe = intel_crtc->pipe;
>>  	u32 reg, temp, tries;
>>  
>> @@ -3396,7 +3392,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
>>  	reg = FDI_TX_CTL(pipe);
>>  	temp = I915_READ(reg);
>>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
>> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
>> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>>  	temp &= ~FDI_LINK_TRAIN_NONE;
>>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
>>  	I915_WRITE(reg, temp | FDI_TX_ENABLE);
>> @@ -3476,6 +3472,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->state);
>>  	int pipe = intel_crtc->pipe;
>>  	u32 reg, temp, i, retry;
>>  
>> @@ -3494,7 +3492,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
>>  	reg = FDI_TX_CTL(pipe);
>>  	temp = I915_READ(reg);
>>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
>> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
>> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>>  	temp &= ~FDI_LINK_TRAIN_NONE;
>>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
>>  	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
>> @@ -3608,6 +3606,8 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> +	struct intel_crtc_state *pipe_config =
>> +		to_intel_crtc_state(crtc->state);
>>  	int pipe = intel_crtc->pipe;
>>  	u32 reg, temp, i, j;
>>  
>> @@ -3645,7 +3645,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
>>  		reg = FDI_TX_CTL(pipe);
>>  		temp = I915_READ(reg);
>>  		temp &= ~FDI_DP_PORT_WIDTH_MASK;
>> -		temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
>> +		temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
>>  		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
>>  		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
>>  		temp |= snb_b_fdi_train_param[j/2];
>> @@ -3914,11 +3914,10 @@ void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
>>  }
>>  
>>  /* Program iCLKIP clock to the desired frequency */
>> -static void lpt_program_iclkip(struct drm_crtc *crtc)
>> +static void lpt_program_iclkip(struct drm_i915_private *dev_priv,
>> +			       struct intel_crtc_state *pipe_config)
>>  {
>> -	struct drm_device *dev = crtc->dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
>> +	int clock = pipe_config->base.adjusted_mode.crtc_clock;
>>  	u32 divsel, phaseinc, auxdiv, phasedir = 0;
>>  	u32 temp;
>>  
>> @@ -4002,13 +4001,10 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
>>  	mutex_unlock(&dev_priv->dpio_lock);
>>  }
>>  
>> -static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
>> +static void ironlake_pch_transcoder_set_timings(struct drm_i915_private *dev_priv,
>> +						enum transcoder cpu_transcoder,
>>  						enum pipe pch_transcoder)
>>  {
>> -	struct drm_device *dev = crtc->base.dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
>> -
>>  	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
>>  		   I915_READ(HTOTAL(cpu_transcoder)));
>>  	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
>> @@ -4026,7 +4022,8 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
>>  		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
>>  }
>>  
>> -static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
>> +static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev,
>> +				       bool enable)
>>  {
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>  	uint32_t temp;
>> @@ -4047,15 +4044,15 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
>>  	POSTING_READ(SOUTH_CHICKEN1);
>>  }
>>  
>> -static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
>> +static void ivybridge_update_fdi_bc_bifurcation(struct drm_device *dev,
>> +					struct intel_crtc *intel_crtc,
>> +					struct intel_crtc_state *pipe_config)
>>  {
>> -	struct drm_device *dev = intel_crtc->base.dev;
>> -
>>  	switch (intel_crtc->pipe) {
>>  	case PIPE_A:
>>  		break;
>>  	case PIPE_B:
>> -		if (intel_crtc->config->fdi_lanes > 2)
>> +		if (pipe_config->fdi_lanes > 2)
>>  			cpt_set_fdi_bc_bifurcation(dev, false);
>>  		else
>>  			cpt_set_fdi_bc_bifurcation(dev, true);
>> @@ -4078,7 +4075,8 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
>>   *   - DP transcoding bits
>>   *   - transcoder
>>   */
>> -static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
>> +static void ironlake_pch_enable(struct drm_crtc *crtc,
>> +				struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>> @@ -4089,7 +4087,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>>  	assert_pch_transcoder_disabled(dev_priv, pipe);
>>  
>>  	if (IS_IVYBRIDGE(dev))
>> -		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
>> +		ivybridge_update_fdi_bc_bifurcation(dev, intel_crtc,
>> +						    pipe_config);
>>  
>>  	/* Write the TU size bits before fdi link training, so that error
>>  	 * detection works. */
>> @@ -4121,11 +4120,12 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>>  	 * Note that enable_shared_dpll tries to do the right thing, but
>>  	 * get_shared_dpll unconditionally resets the pll - we need that to have
>>  	 * the right LVDS enable sequence. */
>> -	intel_enable_shared_dpll(intel_crtc);
>> +	intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>>  
>>  	/* set transcoder timing, panel must allow it */
>>  	assert_panel_unlocked(dev_priv, pipe);
>> -	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
>> +	ironlake_pch_transcoder_set_timings(dev_priv,
>> +					    pipe_config->cpu_transcoder, pipe);
>>  
>>  	intel_fdi_normal_train(crtc);
>>  
>> @@ -4166,19 +4166,17 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
>>  	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
>>  }
>>  
>> -static void lpt_pch_enable(struct drm_crtc *crtc)
>> +static void lpt_pch_enable(struct drm_i915_private *dev_priv,
>> +			   struct intel_crtc_state *pipe_config)
>>  {
>> -	struct drm_device *dev = crtc->dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
>> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>>  
>>  	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
>>  
>> -	lpt_program_iclkip(crtc);
>> +	lpt_program_iclkip(dev_priv, pipe_config);
>>  
>>  	/* Set transcoder timing. */
>> -	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
>> +	ironlake_pch_transcoder_set_timings(dev_priv, cpu_transcoder, PIPE_A);
>>  
>>  	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
>>  }
>> @@ -4781,7 +4779,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>>  	pipe_config = to_intel_crtc_state(crtc->state);
>>  
>>  	if (pipe_config->has_pch_encoder)
>> -		intel_prepare_shared_dpll(intel_crtc);
>> +		intel_prepare_shared_dpll(dev_priv,
>> +					  pipe_config->shared_dpll);
>>  
>>  	if (pipe_config->has_dp_encoder)
>>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>> @@ -4854,8 +4853,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>>  	WARN_ON(!crtc->state->enable);
>>  
>>  	pipe_config = to_intel_crtc_state(crtc->state);
>> -	if (intel_crtc_to_shared_dpll(intel_crtc))
>> -		intel_enable_shared_dpll(intel_crtc);
>> +	if (pipe_config->shared_dpll >= 0)
>> +		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>>  
>>  	if (pipe_config->has_dp_encoder)
>>  		intel_dp_set_m_n(intel_crtc, M1_N1);
>> @@ -4910,7 +4909,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>>  	intel_enable_pipe(intel_crtc);
>>  
>>  	if (intel_crtc->config->has_pch_encoder)
>> -		lpt_pch_enable(crtc);
>> +		lpt_pch_enable(dev_priv, pipe_config);
>>  
>>  	if (intel_crtc->config->dp_encoder_is_mst)
>>  		intel_ddi_set_vc_payload_alloc(crtc,
>> @@ -11929,7 +11928,8 @@ check_shared_dpll_state(struct drm_device *dev)
>>  		     pll->on, active);
>>  
>>  		for_each_intel_crtc(dev, crtc) {
>> -			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
>> +			if (crtc->base.state->active &&
>> +			    to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
>>  				active_crtcs++;
>>  		}
>>  		I915_STATE_WARN(pll->active != active_crtcs,
>> @@ -12311,7 +12311,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>>  	__intel_set_mode_update_planes(dev, state);
>>  
>>  	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
>> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  		struct intel_crtc_state *pipe_config;
>>  
>>  		if (!needs_modeset(crtc->state))
>> @@ -12324,8 +12323,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
>>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
>>  		dev_priv->display.crtc_disable(crtc, pipe_config);
>>  
>> -		if (intel_crtc_to_shared_dpll(intel_crtc))
>> -			intel_disable_shared_dpll(intel_crtc);
>> +		intel_disable_shared_dpll(dev_priv, pipe_config->shared_dpll);
>>  	}
>>  
>>  	/* Only after disabling all output pipelines that will be changed can we
>> @@ -12719,7 +12717,9 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
>>  
>>  	/* Make sure no transcoder isn't still depending on us. */
>>  	for_each_intel_crtc(dev, crtc) {
>> -		if (intel_crtc_to_shared_dpll(crtc) == pll)
>> +		int i = pll - dev_priv->shared_dplls;
>> +
>> +		if (to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
>>  			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
>>  	}
> This is called with the with the new config already put in place, but it
> should check whether any of the _old_ pipe configs that used the dpll are
> really all shut down. This won't misfire since if we shut it down to use
> it in some other configuration then those pipes should be ofc off too.
> Otoh we do check before enabling the pipe that the dpll is running, hence
> I think this is redundant and maybe we could remove
> it right away?
Removing sounds fine.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit
  2015-05-12 13:03   ` Daniel Vetter
@ 2015-05-12 14:16     ` Maarten Lankhorst
  2015-05-12 17:03       ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Maarten Lankhorst @ 2015-05-12 14:16 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Op 12-05-15 om 15:03 schreef Daniel Vetter:
> On Mon, May 11, 2015 at 04:25:13PM +0200, Maarten Lankhorst wrote:
>> crtc->config is gone, swap swap swap. :D
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_atomic.c  | 36 ++----------------------------------
>>  drivers/gpu/drm/i915/intel_display.c |  7 +++++--
>>  2 files changed, 7 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
>> index ace6aeeb1359..0315dc44b17a 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>> @@ -130,7 +130,6 @@ int intel_atomic_commit(struct drm_device *dev,
>>  			bool async)
>>  {
>>  	int ret;
>> -	int i;
>>  
>>  	if (async) {
>>  		DRM_DEBUG_KMS("i915 does not yet support async commit\n");
>> @@ -142,48 +141,17 @@ int intel_atomic_commit(struct drm_device *dev,
>>  		return ret;
>>  
>>  	/* Point of no return */
>> +	drm_atomic_helper_swap_state(dev, state);
>>  
>>  	/*
>>  	 * FIXME:  The proper sequence here will eventually be:
>>  	 *
>> -	 * drm_atomic_helper_swap_state(dev, state)
>>  	 * drm_atomic_helper_commit_modeset_disables(dev, state);
>>  	 * drm_atomic_helper_commit_planes(dev, state);
>>  	 * drm_atomic_helper_commit_modeset_enables(dev, state);
>> -	 * drm_atomic_helper_wait_for_vblanks(dev, state);
>> -	 * drm_atomic_helper_cleanup_planes(dev, state);
>> -	 * drm_atomic_state_free(state);
>> -	 *
>> -	 * once we have full atomic modeset.  For now, just manually update
>> -	 * plane states to avoid clobbering good states with dummy states
>> -	 * while nuclear pageflipping.
>>  	 */
>> -	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
>> -		struct drm_plane *plane = state->planes[i];
>> -
>> -		if (!plane)
>> -			continue;
>> -
>> -		plane->state->state = state;
>> -		swap(state->plane_states[i], plane->state);
>> -		plane->state->state = NULL;
>> -	}
>> -
>> -	/* swap crtc_scaler_state */
>> -	for (i = 0; i < dev->mode_config.num_crtc; i++) {
>> -		struct drm_crtc *crtc = state->crtcs[i];
>> -		if (!crtc) {
>> -			continue;
>> -		}
>> -
>> -		to_intel_crtc_state(crtc->state)->scaler_state =
>> -			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
>> -
>> -		if (INTEL_INFO(dev)->gen >= 9)
>> -			skl_detach_scalers(to_intel_crtc(crtc));
>> -	}
>> -
>>  	drm_atomic_helper_commit_planes(dev, state);
>> +
>>  	drm_atomic_helper_wait_for_vblanks(dev, state);
>>  	drm_atomic_helper_cleanup_planes(dev, state);
>>  	drm_atomic_state_free(state);
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 65ee2cd0437c..105bdf84e46a 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -13202,11 +13202,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
>>  
>>  	/* Perform vblank evasion around commit operation */
>>  	if (intel_crtc->atomic.evade &&
>> -	    !dev_priv->power_domains.init_power_on)
>> +	    !dev_priv->power_domains.init_power_on) {
>> +		if (dev_priv->info.gen >= 9)
>> +			skl_detach_scalers(to_intel_crtc(crtc));
> Don't we need to update skl_detach_scalers to look at the other config
> now? Or is this an issue with the patch splitting?
>
> Also why is this protected by atomic.evade?
Mostly to not run if a modeset's done, that already kills the scalers.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 04/42] drm/i915: use intel_crtc_control everywhere
  2015-05-12 13:16       ` Daniel Vetter
@ 2015-05-12 14:38         ` Daniel Stone
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Stone @ 2015-05-12 14:38 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Hi,

On 12 May 2015 at 14:16, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, May 12, 2015 at 02:06:39PM +0200, Maarten Lankhorst wrote:
>> Op 11-05-15 om 19:11 schreef Daniel Vetter:
>> > On Mon, May 11, 2015 at 04:24:40PM +0200, Maarten Lankhorst wrote:
>> >> @@ -6079,26 +6059,29 @@ void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>> >>    enum intel_display_power_domain domain;
>> >>    unsigned long domains;
>> >>
>> >> +  if (enable == intel_crtc->active)
>> >> +          return;
>> >> +
>> >> +  if (enable && !crtc->state->enable)
>> >> +          return;
>> > I think we only need to check for !state->enable here. Changing dpms while
>> > the crtc is fully of is totally legit. And at least -modesetting loves to
>> > do just that iirc.
>> >
>> > I'll will be caught by state->active implying state->enable, but that's
>> > hard to read imo.
>> > -Daniel
>> As discussed on irc it's not. :-)
>
> Hm there's actually a bug in drm_atomic_helper_connector_dpms I think ...
> we seem to unconditionally update crtc_state->active.
>
> Oh I'm missing that ->enable == false also implies that no connectors are
> connected to the crtc, so we can't ever end up setting this to true. So
> indeed changing active while enable == false is impossible.

Not the only place we seem to rather carelessly do this, mind:
https://git.collabora.com/cgit/user/daniels/linux.git/commit/?h=wip/4.1.x/unify-flip-modeset&id=132a1d4086e20cac95094c7fd568f992e4a0cb6d

Cheers,
Daniel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-12 13:43       ` Ville Syrjälä
  2015-05-12 13:46         ` Ville Syrjälä
@ 2015-05-12 15:31         ` Daniel Vetter
  1 sibling, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 15:31 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:43:09PM +0300, Ville Syrjälä wrote:
> On Tue, May 12, 2015 at 03:33:12PM +0200, Maarten Lankhorst wrote:
> > Op 12-05-15 om 10:18 schreef Daniel Vetter:
> > > On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
> > >> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
> > >>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
> > >>  	intel_state->clip.x1 = 0;
> > >>  	intel_state->clip.y1 = 0;
> > >> -	intel_state->clip.x2 =
> > >> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
> > >> -	intel_state->clip.y2 =
> > >> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
> > >> -
> > >> -	/*
> > >> -	 * Disabling a plane is always okay; we just need to update
> > >> -	 * fb tracking in a special way since cleanup_fb() won't
> > >> -	 * get called by the plane helpers.
> > >> -	 */
> > >> -	if (state->fb == NULL && plane->state->fb != NULL) {
> > >> -		/*
> > >> -		 * 'prepare' is never called when plane is being disabled, so
> > >> -		 * we need to handle frontbuffer tracking as a special case
> > >> -		 */
> > >> -		intel_crtc->atomic.disabled_planes |=
> > >> -			(1 << drm_plane_index(plane));
> > >> -	}
> > >> +	drm_crtc_get_hv_timing(&crtc_state->mode,
> > >> +			       &intel_state->clip.x2,
> > >> +			       &intel_state->clip.y2);
> > > Imo this is obfuscating things a bit, why not just unconditionally copy
> > > pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
> > > most platforms must match the primary plane window except for gen2 and
> > > gen9+.
> > pipe_src_* is calculated in the same way,
> 
> Except we may end up rounding pipe_src_w down if we have
> double-wide/dual link lvds etc., and we definitely need to clip the
> planes against the real pipe src size.
> 
> > and at the time of plane validation the crtc validation hasn't run yet,
> > so pipe_src_* contains outdated values which break in interesting ways.
> 
> Just check crtc first. Or actually we probably need pre + post crtc
> checks since we want to do wm compute and such after the planes have
> been handled.

Yeah in the end the sequence should be:
1. compute pipe_config for modeset changes on any crtcs where mode_changed
   is set.
2. call helper_check_planes which should use the values computed in step
   1. to compute the nuclear plane flip states. It's important that the
   depencies flow one-way since only then can we skip all the modeset
   state recomputation (and possible serialization because we need more
   crtc states) for pure plane flips.

Where exactly do the pipe_src_w/h values get out of sync here? Imo better
to patch them up someplace in the legacy modeset code than add hacks to
plane atomic functions.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 10/42] drm/i915: make plane helpers fully atomic
  2015-05-12 13:33     ` Maarten Lankhorst
  2015-05-12 13:43       ` Ville Syrjälä
@ 2015-05-12 16:00       ` Daniel Vetter
  1 sibling, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 16:00 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 03:33:12PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 10:18 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:24:46PM +0200, Maarten Lankhorst wrote:
> >> This kills off most of the transitional helpers and uses atomic plane updates
> >> in the modeset path to update everything.
> >>
> >> Getting rid of the transitional plane helpers meant that planes had to be added
> >> in the crtc check function. On modeset a connector can be moved to a different
> >> crtc, and this is not handled correctly otherwise.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Ok pile of comments on this one. I don't yet fully grasp it all, but at
> > the very bottom I've jotted down a list of ideas for how to move forward
> > with this one.
> >
> >> ---
> >>  drivers/gpu/drm/i915/intel_atomic_plane.c |  59 ++-
> >>  drivers/gpu/drm/i915/intel_display.c      | 655 ++++++++++++++++++------------
> >>  drivers/gpu/drm/i915/intel_drv.h          |   2 +-
> >>  drivers/gpu/drm/i915/intel_sprite.c       |  80 +---
> >>  4 files changed, 441 insertions(+), 355 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> index 86ba4b2c3a65..85b87e4d4b6e 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
> >> @@ -110,32 +110,40 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
> >>  				    struct drm_plane_state *state)
> >>  {
> >>  	struct drm_crtc *crtc = state->crtc;
> >> -	struct intel_crtc *intel_crtc;
> >> -	struct intel_crtc_state *crtc_state;
> >> +	struct drm_crtc_state *crtc_state;
> >>  	struct intel_plane *intel_plane = to_intel_plane(plane);
> >>  	struct intel_plane_state *intel_state = to_intel_plane_state(state);
> >>  
> >> -	crtc = crtc ? crtc : plane->crtc;
> >> -	intel_crtc = to_intel_crtc(crtc);
> >> -
> >> +	intel_state->visible = false;
> >>  	/*
> >>  	 * Both crtc and plane->crtc could be NULL if we're updating a
> >>  	 * property while the plane is disabled.  We don't actually have
> >>  	 * anything driver-specific we need to test in that case, so
> >>  	 * just return success.
> >>  	 */
> >> -	if (!crtc)
> >> +	if (!crtc) {
> >> +		DRM_DEBUG_ATOMIC("Invisible: no crtc\n");
> >>  		return 0;
> >> +	}
> >> +
> >> +	crtc_state = state->state->crtc_states[drm_crtc_index(crtc)];
> > Please reuse drm_atomic_get_crtc_state, this deref magic is hard to read.
> > Maybe we should have a nofail variant of those to encode the below WARN_ON
> > even ...
> Yeah, there are a few places where I use it like this, because in those cases the relevant state should already exist.

Imo get_foo_state + WARN_ON(IS_ERR) is better than open-coding it. It's a
tricky deref chain and I've gotten it wrong multiple times when writing
atomic helpers.

> >> +	if (WARN_ON(!crtc_state))
> >> +		return 0;
> >> +
> >> +	if (!crtc_state->enable) {
> >> +		DRM_DEBUG_ATOMIC("Invisible: crtc off\n");
> >>  
> >> -	/* FIXME: temporary hack necessary while we still use the plane update
> >> -	 * helper. */
> >> -	if (state->state) {
> >> -		crtc_state =
> >> -			intel_atomic_get_crtc_state(state->state, intel_crtc);
> >> -		if (IS_ERR(crtc_state))
> >> -			return PTR_ERR(crtc_state);
> >> -	} else {
> >> -		crtc_state = intel_crtc->config;
> >> +		/*
> >> +		 * Probably allowed after converting to atomic. Right
> >> +		 * now it probably means we have the state confused.
> >> +		 */
> >> +		I915_STATE_WARN_ON(plane->type == DRM_PLANE_TYPE_PRIMARY);
> > This is already possible with the primary plane support - you can disable
> > it (though not change the mode at the same time).
> That explains a few warnings, thanks. :-)
> >> +		return 0;
> >> +	}
> >> +
> >> +	if (!crtc_state->active) {
> >> +		DRM_DEBUG_ATOMIC("Invisible: dpms off\n");
> >> +		return 0;
> >>  	}
> >>  
> >>  	/*
> >> @@ -155,24 +163,9 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
> >>  	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
> >>  	intel_state->clip.x1 = 0;
> >>  	intel_state->clip.y1 = 0;
> >> -	intel_state->clip.x2 =
> >> -		crtc_state->base.active ? crtc_state->pipe_src_w : 0;
> >> -	intel_state->clip.y2 =
> >> -		crtc_state->base.active ? crtc_state->pipe_src_h : 0;
> >> -
> >> -	/*
> >> -	 * Disabling a plane is always okay; we just need to update
> >> -	 * fb tracking in a special way since cleanup_fb() won't
> >> -	 * get called by the plane helpers.
> >> -	 */
> >> -	if (state->fb == NULL && plane->state->fb != NULL) {
> >> -		/*
> >> -		 * 'prepare' is never called when plane is being disabled, so
> >> -		 * we need to handle frontbuffer tracking as a special case
> >> -		 */
> >> -		intel_crtc->atomic.disabled_planes |=
> >> -			(1 << drm_plane_index(plane));
> >> -	}
> >> +	drm_crtc_get_hv_timing(&crtc_state->mode,
> >> +			       &intel_state->clip.x2,
> >> +			       &intel_state->clip.y2);
> > Imo this is obfuscating things a bit, why not just unconditionally copy
> > pipe_src_w/h to clip.x/y2? get_hv_timing is for the pipe size, which on
> > most platforms must match the primary plane window except for gen2 and
> > gen9+.
> pipe_src_* is calculated in the same way, and at the time of plane validation the crtc validation hasn't run yet,
> so pipe_src_* contains outdated values which break in interesting ways.

See my comment in reply to Ville's mail - we need to track this down and
paper over (if needed) somewhere else than the atomic plane code.

> 
> >>  
> >>  	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
> >>  		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 956c9964275d..9610f76a2489 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -100,14 +100,16 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
> >>  			    const struct intel_crtc_state *pipe_config);
> >>  static void chv_prepare_pll(struct intel_crtc *crtc,
> >>  			    const struct intel_crtc_state *pipe_config);
> >> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
> >> +				   struct drm_crtc_state *crtc_state);
> > I consider forward declarations evil, but given how much of a mess
> > intel_display.c is it doesn't really matter much ;-)
> >
> >>  static void intel_begin_crtc_commit(struct drm_crtc *crtc);
> >>  static void intel_finish_crtc_commit(struct drm_crtc *crtc);
> >>  static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_crtc,
> >>  	struct intel_crtc_state *crtc_state);
> >>  static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> >>  			   int num_connectors);
> >> -static void intel_crtc_enable_planes(struct drm_crtc *crtc);
> >> -static void intel_crtc_disable_planes(struct drm_crtc *crtc);
> >> +static void intel_pre_disable_primary(struct drm_crtc *crtc);
> >> +static void intel_post_enable_primary(struct drm_crtc *crtc);
> >>  
> >>  static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe)
> >>  {
> >> @@ -2220,28 +2222,6 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
> >>  	POSTING_READ(reg);
> >>  }
> >>  
> >> -/**
> >> - * intel_enable_primary_hw_plane - enable the primary plane on a given pipe
> >> - * @plane:  plane to be enabled
> >> - * @crtc: crtc for the plane
> >> - *
> >> - * Enable @plane on @crtc, making sure that the pipe is running first.
> >> - */
> >> -static void intel_enable_primary_hw_plane(struct drm_plane *plane,
> >> -					  struct drm_crtc *crtc)
> >> -{
> >> -	struct drm_device *dev = plane->dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> -
> >> -	/* If the pipe isn't enabled, we can't pump pixels and may hang */
> >> -	assert_pipe_enabled(dev_priv, intel_crtc->pipe);
> >> -	to_intel_plane_state(plane->state)->visible = true;
> >> -
> >> -	dev_priv->display.update_primary_plane(crtc, plane->fb,
> >> -					       crtc->x, crtc->y);
> >> -}
> >> -
> >>  static bool need_vtd_wa(struct drm_device *dev)
> >>  {
> >>  #ifdef CONFIG_INTEL_IOMMU
> >> @@ -3161,11 +3141,20 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> >>  {
> >>  	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> +	struct intel_plane_state *plane_state =
> >> +		to_intel_plane_state(crtc->primary->state);
> >> +	bool was_visible = plane_state->visible;
> >>  
> >> -	if (dev_priv->display.disable_fbc)
> >> +	/* Not supported right now by the helper, but lets be thorough. */
> >> +	if (was_visible && !fb)
> >> +		intel_pre_disable_primary(crtc);
> >> +	else if (was_visible && dev_priv->display.disable_fbc)
> >>  		dev_priv->display.disable_fbc(dev);
> >>  
> >> +	plane_state->visible = !!fb;
> >>  	dev_priv->display.update_primary_plane(crtc, fb, x, y);
> >> +	if (!was_visible && fb)
> >> +		intel_post_enable_primary(crtc);
> > This contains a vblank_wait (at least for broadwell) which is a no-go in
> > set_base_atomic. Given that this is only used by kgdb and I'm not aware of
> > anyone using that and we also don't have any testcase for this code I
> > think the best would be to just not touch this and let it keep on
> > bitrotting ...
> Ok, I'll drop this hunk.
> 
> >>  
> >>  	return 0;
> >>  }
> >> @@ -3192,16 +3181,17 @@ static void intel_update_primary_planes(struct drm_device *dev)
> >>  		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >>  
> >>  		drm_modeset_lock(&crtc->mutex, NULL);
> >> -		/*
> >> -		 * FIXME: Once we have proper support for primary planes (and
> >> -		 * disabling them without disabling the entire crtc) allow again
> >> -		 * a NULL crtc->primary->fb.
> >> -		 */
> >> -		if (intel_crtc->active && crtc->primary->fb)
> >> +
> >> +		if (intel_crtc->active) {
> >> +			const struct intel_plane_state *state =
> >> +				to_intel_plane_state(crtc->primary->state);
> >> +
> >>  			dev_priv->display.update_primary_plane(crtc,
> >> -							       crtc->primary->fb,
> >> -							       crtc->x,
> >> -							       crtc->y);
> >> +							state->base.fb,
> >> +							state->src.x1 >> 16,
> >> +							state->src.y1 >> 16);
> >> +		}
> > I think the above hunk could be split out. And I'm not sure it's required
> > really, this is just to catch up on CS flips. Which won't be used any more
> > once we have atomic, but until then the legacy state stuff used here
> > should be good enough.
> ?

This is the gpu reset code - CS based flips can get lost if the gpu gets
reset, which means we need to do them manually. By re-running
update_primary_plane with the current state.

But CS based flips don't work for atomic, which means as soon as we've
hooked up the pageflip atomic helper we won't ever see an a CS based flip
when using atomic. Which means using the legacy state objects meanwhile
(until that transition is done and we can just outright nuke this code)
should be perfectly safe.

> >> +
> >>  		drm_modeset_unlock(&crtc->mutex);
> >>  	}
> >>  }
> >> @@ -4572,20 +4562,6 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc)
> >>  	}
> >>  }
> >>  
> >> -static void intel_enable_sprite_planes(struct drm_crtc *crtc)
> >> -{
> >> -	struct drm_device *dev = crtc->dev;
> >> -	enum pipe pipe = to_intel_crtc(crtc)->pipe;
> >> -	struct drm_plane *plane;
> >> -	struct intel_plane *intel_plane;
> >> -
> >> -	drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
> >> -		intel_plane = to_intel_plane(plane);
> >> -		if (intel_plane->pipe == pipe)
> >> -			intel_plane_restore(&intel_plane->base);
> >> -	}
> >> -}
> >> -
> >>  void hsw_enable_ips(struct intel_crtc *crtc)
> >>  {
> >>  	struct drm_device *dev = crtc->base.dev;
> >> @@ -4815,44 +4791,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
> >>  	hsw_disable_ips(intel_crtc);
> >>  }
> >>  
> >> -static void intel_crtc_enable_planes(struct drm_crtc *crtc)
> >> -{
> >> -	intel_enable_primary_hw_plane(crtc->primary, crtc);
> >> -	intel_enable_sprite_planes(crtc);
> >> -	intel_crtc_update_cursor(crtc, true);
> >> -
> >> -	intel_post_enable_primary(crtc);
> >> -}
> >> -
> >> -static void intel_crtc_disable_planes(struct drm_crtc *crtc)
> >> -{
> >> -	struct drm_device *dev = crtc->dev;
> >> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> -	struct intel_plane *intel_plane;
> >> -	int pipe = intel_crtc->pipe;
> >> -
> >> -	intel_crtc_wait_for_pending_flips(crtc);
> >> -
> >> -	intel_pre_disable_primary(crtc);
> >> -
> >> -	intel_crtc_dpms_overlay_disable(intel_crtc);
> >> -	for_each_intel_plane(dev, intel_plane) {
> >> -		if (intel_plane->pipe == pipe) {
> >> -			struct drm_crtc *from = intel_plane->base.crtc;
> >> -
> >> -			intel_plane->disable_plane(&intel_plane->base,
> >> -						   from ?: crtc, true);
> >> -		}
> >> -	}
> >> -
> >> -	/*
> >> -	 * FIXME: Once we grow proper nuclear flip support out of this we need
> >> -	 * to compute the mask of flip planes precisely. For the time being
> >> -	 * consider this a flip to a NULL plane.
> >> -	 */
> >> -	intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
> >> -}
> >> -
> >>  static void ironlake_crtc_enable(struct drm_crtc *crtc)
> >>  {
> >>  	struct drm_device *dev = crtc->dev;
> >> @@ -11061,6 +10999,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
> >>  	.load_lut = intel_crtc_load_lut,
> >>  	.atomic_begin = intel_begin_crtc_commit,
> >>  	.atomic_flush = intel_finish_crtc_commit,
> >> +	.atomic_check = intel_atomic_check_crtc,
> >>  };
> >>  
> >>  /* Transitional helper to copy current connector/encoder state to
> >> @@ -11426,16 +11365,6 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> >>  	int i;
> >>  	bool retry = true;
> >>  
> >> -	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
> >> -		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> >> -		return -EINVAL;
> >> -	}
> >> -
> >> -	if (!check_digital_port_conflicts(state)) {
> >> -		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
> >> -		return -EINVAL;
> >> -	}
> >> -
> > I think it would help if you'd split out the addition of the crtc_check
> > function into a separate prep patch. At least I don't see a depency here
> > ...
> Yeah but that would be the only thing put in there, oh well got to start somewhere...

Yeah that's kinda what I mean. This patch's subject talks about reworking
the plane update handling, this clearly isn't part of that. So imo a good
(small) prep patch to split out.

> >
> >> @@ -12275,7 +12333,7 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
> >>  	struct drm_atomic_state *state = pipe_config->base.state;
> >>  	struct drm_crtc *crtc;
> >>  	struct drm_crtc_state *crtc_state;
> >> -	int ret = 0;
> >> +	int ret;
> >>  	int i;
> >>  
> >>  	ret = __intel_set_mode_checks(state);
> >> @@ -12286,14 +12344,14 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
> >>  	if (ret)
> >>  		return ret;
> >>  
> >> +	__intel_set_mode_update_planes(dev, state);
> > This calls crtc->atomic_begin, which does an irq_disable ...
> Yeah I tried to handle it by fixing all previous places to prevent atomic evading on modeset,
> which means it is mostly safe to do it like this.

Hm, we want to do the flip to black before disables and the flip form
black on enabling as nuclear flips too. Dropping the vblank evade isn't a
good idea imo since we'll need to resurrect it. And failing to bring up
all planes on the very first frame torpedoes the "all frames are perfect"
goal.

And there's a lot more special cases than just the evade I think, so I'm
not sure whether the reuse is worth it.

> 
> >
> >> +
> >>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> >>  		if (!needs_modeset(crtc_state))
> >>  			continue;
> >>  
> >> -		intel_crtc_disable_planes(crtc);
> >> +		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
> >>  		dev_priv->display.crtc_disable(crtc);
> >> -		if (!crtc_state->enable)
> >> -			drm_plane_helper_disable(crtc->primary);
> >>  	}
> >>  
> >>  	/* Only after disabling all output pipelines that will be changed can we
> >> @@ -12305,8 +12363,6 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
> >>  
> >>  	modeset_update_crtc_power_domains(state);
> >>  
> >> -	drm_atomic_helper_commit_planes(dev, state);
> >> -
> >>  	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
> >>  	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> >>  		if (!crtc->state->active)
> >> @@ -12314,13 +12370,13 @@ static int __intel_set_mode(struct drm_crtc *modeset_crtc,
> >>  
> >>  		update_scanline_offset(to_intel_crtc(crtc));
> >>  
> >> -		dev_priv->display.crtc_enable(crtc);
> >> -		intel_crtc_enable_planes(crtc);
> >> +		if (needs_modeset(crtc->state))
> >> +			dev_priv->display.crtc_enable(crtc);
> >>  	}
> >>  
> >> -	/* FIXME: add subpixel order */
> >> +	__intel_set_mode_cleanup_planes(dev, state);
> > which is only cleared in atomic_flush here. We need both of these at the
> > bottom here. In atomic-helpers-speak the sequence should be
> >
> > drm_atomic_helper_commit_modeset_disables();
> > drm_atomic_helper_commit_modeset_enables();
> > drm_atomic_helper_commit_planes();
> >
> > with the note that our crtc_disable must do the unconditional plane
> > disabling itself. I.e. you can't just remove disable_planes without
> > replacement, that one needs to be open-coded (using plane->atomic_disable
> > if possible).
> >
> > Doing things this way would also alleviate any need to split up swap_state
> > as you do in this patch here.
> You're right it could be done like this, but doing commit_planes around the modesets allows
> us to test the same code for calculating disable planes during modeset as when togging planes
> separately. For example this is useful when a connector moves to a different crtc.

Moving connectors will force a full modeset on both crtcs (at least with
atomic helpers, current i915 code isn't fully there yet without your
series here). So I'm not sure how much this helps.

And I don't think code reuse is that useful really since crtc disabling is
a special case anyway.

> In any case this is cosmetic, and done for bisecting. I can move the swap_states in this commit,
> but chose to do it 2 commits later for easier bisection.
> 
> I can't move it to before this commit because calling the plane helpers messes up the state.

Yeah that direction is clear. But I'm not too clear on why we have to move
things now already? It won't work with your approach, but with my idea of
a special-purpose disable_planes function only used for crtc_disable we
only need the full atomic state in crtc_enable. And with the current
position of swap_states that's the right one already.

Then we can still move swap_states up in the sequence in a later patch
like you do, but without the big intermediate split. That's my other
reason for doing the special_disable_planes + commit_planes after modeset
is all done.

> >> -	drm_atomic_helper_cleanup_planes(dev, state);
> > Please keep this separate and don't hide it in another function, it's a
> > distinct step from the hw update (which is now done in the misnamed
> > intel_set_mode_cleanup_planes).
> Ok.
> >
> >> +	/* FIXME: add subpixel order */
> >>  
> >>  	drm_atomic_state_free(state);
> >>  
> >> @@ -12568,20 +12624,11 @@ intel_modeset_stage_output_state(struct drm_device *dev,
> >>  	return 0;
> >>  }
> >>  
> >> -static bool primary_plane_visible(struct drm_crtc *crtc)
> >> -{
> >> -	struct intel_plane_state *plane_state =
> >> -		to_intel_plane_state(crtc->primary->state);
> >> -
> >> -	return plane_state->visible;
> >> -}
> >> -
> >>  static int intel_crtc_set_config(struct drm_mode_set *set)
> >>  {
> >>  	struct drm_device *dev;
> >>  	struct drm_atomic_state *state = NULL;
> >>  	struct intel_crtc_state *pipe_config;
> >> -	bool primary_plane_was_visible;
> >>  	int ret;
> >>  
> >>  	BUG_ON(!set);
> >> @@ -12620,38 +12667,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
> >>  
> >>  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> >>  
> >> -	primary_plane_was_visible = primary_plane_visible(set->crtc);
> >> -
> >>  	ret = intel_set_mode_with_config(set->crtc, pipe_config);
> >> -
> >> -	if (ret == 0 &&
> >> -	    pipe_config->base.enable &&
> >> -	    pipe_config->base.planes_changed &&
> >> -	    !needs_modeset(&pipe_config->base)) {
> >> -		struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
> >> -
> >> -		/*
> >> -		 * We need to make sure the primary plane is re-enabled if it
> >> -		 * has previously been turned off.
> >> -		 */
> >> -		if (ret == 0 && !primary_plane_was_visible &&
> >> -		    primary_plane_visible(set->crtc)) {
> >> -			WARN_ON(!intel_crtc->active);
> >> -			intel_post_enable_primary(set->crtc);
> >> -		}
> >> -
> >> -		/*
> >> -		 * In the fastboot case this may be our only check of the
> >> -		 * state after boot.  It would be better to only do it on
> >> -		 * the first update, but we don't have a nice way of doing that
> >> -		 * (and really, set_config isn't used much for high freq page
> >> -		 * flipping, so increasing its cost here shouldn't be a big
> >> -		 * deal).
> >> -		 */
> >> -		if (i915.fastboot && ret == 0)
> >> -			intel_modeset_check_state(set->crtc->dev);
> >> -	}
> >> -
> >>  	if (ret) {
> >>  		DRM_DEBUG_KMS("failed to set mode on [CRTC:%d], err = %d\n",
> >>  			      set->crtc->base.id, ret);
> >> @@ -12791,6 +12807,9 @@ bool intel_wm_need_update(struct drm_plane *plane,
> >>  	    plane->state->rotation != state->rotation)
> >>  		return true;
> >>  
> >> +	if (plane->state->crtc_w != state->crtc_w)
> >> +		return true;
> >> +
> >>  	return false;
> >>  }
> >>  
> >> @@ -12819,6 +12838,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
> >>  	unsigned frontbuffer_bits = 0;
> >>  	int ret = 0;
> >>  
> >> +	if (!to_intel_plane_state(plane->state)->visible)
> >> +		old_obj = NULL;
> >> +
> >>  	if (!obj)
> >>  		return 0;
> >>  
> >> @@ -12915,10 +12937,8 @@ intel_check_primary_plane(struct drm_plane *plane,
> >>  			  struct intel_plane_state *state)
> >>  {
> >>  	struct drm_device *dev = plane->dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct drm_crtc *crtc = state->base.crtc;
> >>  	struct intel_crtc *intel_crtc;
> >> -	struct intel_crtc_state *crtc_state;
> >>  	struct drm_framebuffer *fb = state->base.fb;
> >>  	struct drm_rect *dest = &state->dst;
> >>  	struct drm_rect *src = &state->src;
> >> @@ -12926,90 +12946,46 @@ intel_check_primary_plane(struct drm_plane *plane,
> >>  	bool can_position = false;
> >>  	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
> >>  	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
> >> -	int ret;
> >>  
> >> -	crtc = crtc ? crtc : plane->crtc;
> >>  	intel_crtc = to_intel_crtc(crtc);
> >> -	crtc_state = state->base.state ?
> >> -		intel_atomic_get_crtc_state(state->base.state, intel_crtc) : NULL;
> >>  
> >>  	if (INTEL_INFO(dev)->gen >= 9) {
> >> +		struct intel_crtc_state *crtc_state =
> >> +			intel_atomic_get_crtc_state(state->base.state, intel_crtc);
> >> +
> >>  		min_scale = 1;
> >>  		max_scale = skl_max_scale(intel_crtc, crtc_state);
> >>  		can_position = true;
> >>  	}
> >>  
> >> -	ret = drm_plane_helper_check_update(plane, crtc, fb,
> >> -					    src, dest, clip,
> >> -					    min_scale,
> >> -					    max_scale,
> >> -					    can_position, true,
> >> -					    &state->visible);
> >> -	if (ret)
> >> -		return ret;
> >> -
> >> -	if (intel_crtc->active) {
> >> -		struct intel_plane_state *old_state =
> >> -			to_intel_plane_state(plane->state);
> >> -
> >> -		intel_crtc->atomic.wait_for_flips = true;
> >> -
> >> -		/*
> >> -		 * FBC does not work on some platforms for rotated
> >> -		 * planes, so disable it when rotation is not 0 and
> >> -		 * update it when rotation is set back to 0.
> >> -		 *
> >> -		 * FIXME: This is redundant with the fbc update done in
> >> -		 * the primary plane enable function except that that
> >> -		 * one is done too late. We eventually need to unify
> >> -		 * this.
> >> -		 */
> >> -		if (state->visible &&
> >> -		    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
> >> -		    dev_priv->fbc.crtc == intel_crtc &&
> >> -		    state->base.rotation != BIT(DRM_ROTATE_0)) {
> >> -			intel_crtc->atomic.disable_fbc = true;
> >> -		}
> >> -
> >> -		if (state->visible && !old_state->visible) {
> >> -			/*
> >> -			 * BDW signals flip done immediately if the plane
> >> -			 * is disabled, even if the plane enable is already
> >> -			 * armed to occur at the next vblank :(
> >> -			 */
> >> -			if (IS_BROADWELL(dev))
> >> -				intel_crtc->atomic.wait_vblank = true;
> >> -		}
> >> -
> >> -		intel_crtc->atomic.fb_bits |=
> >> -			INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
> >> -
> >> -		intel_crtc->atomic.update_fbc = true;
> >> -
> >> -		if (intel_wm_need_update(plane, &state->base))
> >> -			intel_crtc->atomic.update_wm = true;
> >> -	}
> >> +	return drm_plane_helper_check_update(plane, crtc, fb,
> >> +					     src, dest, clip,
> >> +					     min_scale, max_scale,
> >> +					     can_position, true,
> >> +					     &state->visible);
> >> +}
> >>  
> >> -	if (INTEL_INFO(dev)->gen >= 9) {
> >> -		ret = skl_update_scaler_users(intel_crtc, crtc_state,
> >> -			to_intel_plane(plane), state, 0);
> >> -		if (ret)
> >> -			return ret;
> >> -	}
> >> +static void
> >> +intel_disable_primary_plane(struct drm_plane *plane,
> >> +			    struct drm_crtc *crtc,
> >> +			    bool force)
> >> +{
> >> +	struct drm_device *dev = plane->dev;
> >> +	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  
> >> -	return 0;
> >> +	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
> >>  }
> >>  
> >>  static void
> >>  intel_commit_primary_plane(struct drm_plane *plane,
> >> -			   struct intel_plane_state *state)
> >> +			   struct intel_plane_state *new_state)
> >>  {
> >> -	struct drm_crtc *crtc = state->base.crtc;
> >> -	struct drm_framebuffer *fb = state->base.fb;
> >> +	struct drm_crtc *crtc = new_state->base.crtc;
> >> +	struct drm_framebuffer *fb = new_state->base.fb;
> >>  	struct drm_device *dev = plane->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_crtc *intel_crtc;
> >> -	struct drm_rect *src = &state->src;
> >> +	struct drm_rect *src = &new_state->src;
> >>  
> >>  	crtc = crtc ? crtc : plane->crtc;
> >>  	intel_crtc = to_intel_crtc(crtc);
> >> @@ -13018,25 +12994,178 @@ intel_commit_primary_plane(struct drm_plane *plane,
> >>  	crtc->x = src->x1 >> 16;
> >>  	crtc->y = src->y1 >> 16;
> >>  
> >> -	if (intel_crtc->active) {
> >> -		if (state->visible)
> >> -			/* FIXME: kill this fastboot hack */
> >> -			intel_update_pipe_size(intel_crtc);
> >> +	if (!new_state->visible ||
> >> +	    WARN_ON(new_state->visible && !crtc->state->active)) {
> >> +		intel_disable_primary_plane(plane, crtc, false);
> >> +	} else {
> >> +		/* FIXME: kill this fastboot hack */
> >> +		intel_update_pipe_size(intel_crtc);
> >>  
> >> -		dev_priv->display.update_primary_plane(crtc, plane->fb,
> >> -						       crtc->x, crtc->y);
> >> +		dev_priv->display.update_primary_plane(crtc, fb,
> >> +						       src->x1 >> 16,
> >> +						       src->y1 >> 16);
> >>  	}
> >>  }
> >>  
> >> -static void
> >> -intel_disable_primary_plane(struct drm_plane *plane,
> >> -			    struct drm_crtc *crtc,
> >> -			    bool force)
> >> +/* Transitional checking here, mostly for plane updates */
> >> +static int intel_atomic_check_crtc(struct drm_crtc *crtc,
> >> +				   struct drm_crtc_state *crtc_state)
> >>  {
> >> -	struct drm_device *dev = plane->dev;
> >> +	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state);
> >> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> +	struct drm_atomic_state *state = crtc_state->state;
> >> +	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> +	struct drm_plane *plane;
> >> +	unsigned plane_mask;
> >> +	int idx, ret;
> >> +	bool mode_changed = needs_modeset(crtc_state);
> >> +	bool is_crtc_enabled = crtc_state->active;
> >> +	bool was_crtc_enabled = crtc->state->active;
> >>  
> >> -	dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
> >> +	if (!check_encoder_cloning(state, to_intel_crtc(crtc))) {
> >> +		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> >> +		return -EINVAL;
> >> +	}
> > I think we need two have 2 blocks in the crtc_check function: One part
> > that just updates watermarks (when state->plane_changed is set) and one
> > part that deals with the modeset checks (adding planes, checking cloning
> > and all that) when needs_modeset(state) is true.
> Makes sense.
> 
> >> +
> >> +	memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
> >> +	intel_crtc->atomic.update_wm = mode_changed;
> >> +
> >> +	idx = crtc->base.id;
> >> +	I915_STATE_WARN(crtc->state->active != intel_crtc->active,
> >> +		"Crtc %i mismatch between state->active(%i) and crtc->active (%i)\n",
> >> +		idx, crtc->state->active, intel_crtc->active);
> > State computation is async, you cant check this in the atomic_check
> > functions. If you think this is useful then we'd need to check this every
> > time before we update intel_crtc->active. But we have the various WARN_ON
> > all over the place (converted over to crtc->state->active) so I think
> > we're more than covered and can just rip out our own intel_crtc->active
> > eventually. At least that's kinda been my idea with state->active too.
> Yeah, it's a remainder when I had the commits in a different order.
> >> +
> >> +	DRM_DEBUG_ATOMIC("Crtc %i was enabled %i now enabled: %i\n",
> >> +			 idx, was_crtc_enabled, is_crtc_enabled);
> >> +
> >> +	plane_mask = crtc_state->plane_mask | crtc->state->plane_mask;
> >> +	drm_for_each_plane_mask(plane, dev, plane_mask) {
> >> +		int i = drm_plane_index(plane);
> >> +		struct drm_plane_state *plane_state = state->plane_states[i];
> >> +		struct intel_plane_state *old_plane_state;
> >> +		bool turn_off, turn_on, visible, was_visible;
> >> +		struct drm_framebuffer *fb;
> >> +
> >> +		if (!plane_state) {
> >> +			const struct drm_plane_helper_funcs *funcs;
> >> +			int ret;
> >> +
> >> +			if (!mode_changed || !plane->state->fb)
> >> +				continue;
> >> +
> >> +			plane_state = drm_atomic_get_plane_state(state, plane);
> > We need to check for the crtc constrains before acquiring the plane state,
> > otherwise all the locking goes single-threaded. On intel hw we can do that
> > because the plane->crtc links are static, you can look at
> > intel_plane->pipe.
> This code is to make sure all planes are checked when mode_changed && plane->state->fb,
> plane_state->visible needs to be updated in that case.

Yes we need to recompute plane state, which is why modeset check should be
done first (including adding any additional plane states because
mode_changed is true). Then after all that we can call the atomic_check
functions for the plane update. There's more detail in my reply further
down, but see also Ville's reply.

> 
> >> +			if (IS_ERR(plane_state))
> >> +				return PTR_ERR(plane_state);
> >> +
> >> +			funcs = plane->helper_private;
> >> +			ret = funcs->atomic_check(plane, plane_state);
> >> +			if (ret)
> >> +				return ret;
> >> +		}
> >> +		old_plane_state = to_intel_plane_state(plane->state);
> >> +
> >> +		was_visible = was_crtc_enabled && (old_plane_state->visible ||
> >> +			      old_plane_state->hw_enabled);
> >> +		visible = to_intel_plane_state(plane_state)->visible &&
> >> +			      is_crtc_enabled;
> >> +
> >> +		if (plane->state->crtc != crtc)
> >> +			was_visible = false;
> >> +		if (plane_state->crtc != crtc)
> >> +			visible = false;
> >> +
> >> +		if (!was_visible && !visible)
> >> +			continue;
> >> +
> >> +		turn_off = was_visible && (!visible || mode_changed);
> >> +		turn_on = visible && (!was_visible || mode_changed);
> >> +		fb = plane_state->fb;
> >> +
> >> +		DRM_DEBUG_ATOMIC("Crtc %i has plane %i with fb %i\n", idx,
> >> +			plane->base.id, fb ? fb->base.id : -1);
> >> +		DRM_DEBUG_ATOMIC("\tvisible %i -> %i, off %i, on %i, ms %i\n",
> >> +			was_visible, visible, turn_off, turn_on, mode_changed);
> >> +
> >> +		/* plane being turned off as part of modeset or changes? */
> >> +		if (intel_wm_need_update(plane, plane_state))
> >> +			intel_crtc->atomic.update_wm = true;
> >> +
> >> +		if (INTEL_INFO(dev)->gen >= 9 &&
> >> +		    plane->base.type != DRM_PLANE_TYPE_CURSOR) {
> >> +			ret = skl_update_scaler_users(intel_crtc, pipe_config,
> >> +					to_intel_plane(plane),
> >> +					to_intel_plane_state(plane_state), 0);
> >> +			if (ret)
> >> +				return ret;
> >> +		}
> >> +
> >> +		/*
> >> +		 * 'prepare' is never called when plane is being disabled, so
> >> +		 * we need to handle frontbuffer tracking as a special case
> >> +		 */
> >> +		if (old_plane_state->base.fb && !visible)
> >> +			intel_crtc->atomic.disabled_planes |= 1 << i;
> >> +
> >> +		switch (plane->base.type) {
> > We should probably store the frontbuffer tracking mask in intel_plane
> > somewhere.
> 
> Indeed, but this code's already complicated enough so I felt that initially doing
> a 1:1 moving from plane_check to crtc_check would be easier to debug.
> 
> 
> >> <snip>
> > I'm completely lost as to why we need to move all the plane->atomic_check
> > code into a loop in the crtc_check function?
> To calculate what needs to happen during atomic_begin and atomic_flush() on each crtc.

Well we need to run the code, that's clear. But why do we need to move it
out of the plane->atomic_check functions? With the following sequence

1. update modeset states, ensure crtc_state->mode_changed is accurate
2. add all plane_states for a crtc if mode_changed is set
3. call helper_check_planes

plane->atomic_check should always be called, and always with the right
state. Is there some refactor ordering issue I'm missing that prevents us
going for this directly?

> 
> >> <snip>
> >> @@ -13306,20 +13427,26 @@ intel_disable_cursor_plane(struct drm_plane *plane,
> >>  
> >>  static void
> >>  intel_commit_cursor_plane(struct drm_plane *plane,
> >> -			  struct intel_plane_state *state)
> >> +			  struct intel_plane_state *new_state)
> >>  {
> >> -	struct drm_crtc *crtc = state->base.crtc;
> >> +	struct drm_crtc *crtc = new_state->base.crtc;
> >>  	struct drm_device *dev = plane->dev;
> >>  	struct intel_crtc *intel_crtc;
> >> -	struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
> >> +	struct drm_i915_gem_object *obj = intel_fb_obj(new_state->base.fb);
> >>  	uint32_t addr;
> >>  
> >>  	crtc = crtc ? crtc : plane->crtc;
> >>  	intel_crtc = to_intel_crtc(crtc);
> >>  
> >> -	plane->fb = state->base.fb;
> >> -	crtc->cursor_x = state->base.crtc_x;
> >> -	crtc->cursor_y = state->base.crtc_y;
> >> +	plane->fb = new_state->base.fb;
> >> +	crtc->cursor_x = new_state->base.crtc_x;
> >> +	crtc->cursor_y = new_state->base.crtc_y;
> >> +
> >> +	if (!new_state->visible ||
> >> +	    WARN_ON(new_state->visible && !crtc->state->active)) {
> > As an aside: We must move over to compute ->visible irrespective of
> > ->active. I haven't check whether you fix that later on already, but this
> > is important to be able to check wm constraints correctly. The
> > crtc_state->active handling should imo be done in the common code by
> > simply not calling any of the plane or crtc functions hw update if the
> > crtc is off.
> In the crtc_check function I'm setting:
> intel_crtc->atomic.update_wm = mode_changed; ?
> 
> It means recalculating wm on dpms off->on too but is that really such a burden?
> Treating crtc->state->active as the only knob for crtc on/off simplifies things.

Not from the computation pov, just from correctnes. We must reject plane
configs that don't have enough fifo space for watermarks irrespective of
crtc_state->active. My comment was also just meant as a question/hint in
the larger picture of moving all the crtc_state->active checks up in the
layering (since platform plane code shouldn't ever care to make sure
there's no bugs).

> > Of course that means we need to add all planes both for ->mode_changed and
> > for ->active_changed, but needs_modeset(crtc_state) takes care of that
> > already.
> This is exactly why I add all planes in the check function.
> 
> > Aside: The idea behind the split between drm_atomic_helper_check_planes
> > and drm_atomic_helper_check_modeset is that the former handles planes-only
> > updates while the latter handles modeset. We can't fully use
> > check_modesets because we don't use crtc helpers, but I think reusing the
> > same idea still has merit:
> >
> > - We create an intel_check_modeset which calls the helper's check_modeset
> >   plus afterwards all the modeset checks (dpll, cloning checks, adding
> >   plane states and global resources) that we do in crtc_compute_config and
> >   friends right now. That one would also add plane states as needed (but
> >   not call plane->atomic_check). All of this would be skipped if
> >   needs_modeset isn't true.
> Might be doable if we do add planes between check_modeset and check_planes.
> 
> Originally I tried it in intel_modeset_compute_config, but that didn't work when
> the crtc was different from the one that had the argument passed.

Right now that should only be possible (in the legacy modeset code) if we
move a connector, which means the other crtc is guaranteed to get
disabled. If adding plane states for that case doesn't (yet) work we could
do an intermediate step and just force-disable all planes if their current
state indicates their on. Not as pretty as walking over old states in the
disable code, but ok as an intermediate step imo.

Once the multi-crtc patch is done we can then switch over to adding plane
states for this case too and the usual state walking loop.

> > - After that we'd call the helper's plane_check functions which does
> >   exclusively plane-update related checks. crtc/plane->atomic_check
> >   wouldn't contain any modeset related checks (like the encoder cloning or
> >   plane adding you're doing right now).
> I think encoder cloning ought to be part of the crtc check since its done on each crtc.
> >> <snip>
> > Ok I think overall this patch is too big and needs to be split a bit. The
> > following should be doable as prep-patches:
> > - set_base_atomic (if we dare to touch it at all)
> I think I'll drop it.
> > - shuffling the crtc modeset check logic around to add plane states as
> >   needed, making sure we only run that if needs_modeset indicates so.
> I think splitting this out would break the transitional helpers, they
> rely on the plane state not being there so the state is correctly
> updated when the transitional plane helpers run, else we would cause
> stale state to be swapped. :-(

Hm right that's an ugly transition indeed. We could pamper over it by
open-coding the helpers and passing in the plane_state to update. Would
mean even more patches ...

> > - Pushing the checks for intel_crtc->active or crtc->state->active out of
> >   the low-level plane code up into higher level atomic plane code (and the
> >   few legacy entry points for plane updates that we still have maybe, but
> >   those should be covered I think with the universal plane + transitional
> >   helpers).
> I fear this might break the transitional helper calls too, the
> transitional helpers require the transitional state to be mostly in sync
> with the atomic state.

Hm yeah. But if we go with the above intermediate step then
crtc_state->active should be always correct and we can move things around
in the plane code without everything getting out of sync. As long as we've
first switched any usage of crtc->active over to crtc_state->active.

> > Then we can put in the meat of this patch, i.e. replacing the helpers with
> > atomic updates in the modeset code.
> I wish that would work. ;-)

Yeah this is a really tricky one. And it's big enough to really scare me,
so if possible I'd prefer a more gradual transition. We've had some really
crazy regression already with all that atomic work, tbh I don't think I'd
have a clue what breaks if a bisect leads to this patch :(

Not sure what to do here really ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 32/42] drm/i915: Calculate haswell plane workaround.
  2015-05-12 14:05     ` Maarten Lankhorst
@ 2015-05-12 16:54       ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 16:54 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:05:24PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 11:43 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:25:08PM +0200, Maarten Lankhorst wrote:
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_display.c | 109 +++++++++++++++++++++++++----------
> >>  drivers/gpu/drm/i915/intel_drv.h     |   2 +
> >>  2 files changed, 81 insertions(+), 30 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 7bc78b49f9f4..7a79659dca00 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -4848,35 +4848,6 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
> >>  	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
> >>  }
> >>  
> >> -/*
> >> - * This implements the workaround described in the "notes" section of the mode
> >> - * set sequence documentation. When going from no pipes or single pipe to
> >> - * multiple pipes, and planes are enabled after the pipe, we need to wait at
> >> - * least 2 vblanks on the first pipe before enabling planes on the second pipe.
> >> - */
> >> -static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
> >> -{
> >> -	struct drm_device *dev = crtc->base.dev;
> >> -	struct intel_crtc *crtc_it, *other_active_crtc = NULL;
> >> -
> >> -	/* We want to get the other_active_crtc only if there's only 1 other
> >> -	 * active crtc. */
> >> -	for_each_intel_crtc(dev, crtc_it) {
> >> -		if (!crtc_it->active || crtc_it == crtc)
> >> -			continue;
> >> -
> >> -		if (other_active_crtc)
> >> -			return;
> >> -
> >> -		other_active_crtc = crtc_it;
> >> -	}
> >> -	if (!other_active_crtc)
> >> -		return;
> >> -
> >> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
> >> -	intel_wait_for_vblank(dev, other_active_crtc->pipe);
> >> -}
> >> -
> >>  static void haswell_crtc_enable(struct drm_crtc *crtc)
> >>  {
> >>  	struct drm_device *dev = crtc->dev;
> >> @@ -4967,7 +4938,10 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >>  
> >>  	/* If we change the relative order between pipe/planes enabling, we need
> >>  	 * to change the workaround. */
> >> -	haswell_mode_set_planes_workaround(intel_crtc);
> >> +	if (pipe_config->hsw_workaround_pipe != INVALID_PIPE) {
> >> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
> >> +		intel_wait_for_vblank(dev, pipe_config->hsw_workaround_pipe);
> >> +	}
> >>  }
> >>  
> >>  static void ironlake_pfit_disable(struct intel_crtc *crtc)
> >> @@ -12147,6 +12121,74 @@ done:
> >>  	return ret;
> >>  }
> >>  
> >> +/*
> >> + * This implements the workaround described in the "notes" section of the mode
> >> + * set sequence documentation. When going from no pipes or single pipe to
> >> + * multiple pipes, and planes are enabled after the pipe, we need to wait at
> >> + * least 2 vblanks on the first pipe before enabling planes on the second pipe.
> >> + */
> >> +static int haswell_mode_set_planes_workaround(struct drm_atomic_state *state)
> >> +{
> >> +	struct drm_crtc *crtc;
> >> +	struct drm_crtc_state *crtc_state;
> >> +	struct intel_crtc_state *first_crtc_state = NULL, *other_crtc_state = NULL;
> >> +	struct intel_crtc *intel_crtc, *first_crtc = NULL, *enabled_crtc;
> >> +	int enabled_crtcs = 0, ret, i;
> >> +
> >> +	for_each_crtc_in_state(state, crtc, crtc_state, i) {
> >> +		struct intel_crtc_state *pipe_config =
> >> +			to_intel_crtc_state(crtc_state);
> >> +
> >> +		pipe_config->hsw_workaround_pipe = INVALID_PIPE;
> > This kind of state resetting should be done in duplicate_state.
> The v2 of this patch uses intel_crtc->atomic.hsw_workaround pipe, which would work better. :)
> >> +
> >> +		if (!crtc_state->active)
> >> +			continue;
> >> +
> >> +		if (!needs_modeset(crtc_state)) {
> >> +			enabled_crtcs++;
> >> +			enabled_crtc = to_intel_crtc(crtc);
> >> +			continue;
> >> +		}
> >> +
> >> +		if (first_crtc) {
> >> +			other_crtc_state = pipe_config;
> >> +			break;
> >> +		}
> >> +		first_crtc = to_intel_crtc(crtc);
> >> +		first_crtc_state = pipe_config;
> >> +	}
> >> +
> >> +	/* No workaround needed? */
> >> +	if (!first_crtc || enabled_crtcs > 1)
> >> +		return 0;
> >> +
> >> +	for_each_intel_crtc(state->dev, intel_crtc) {
> >> +		if (state->crtcs[drm_crtc_index(&intel_crtc->base)])
> >> +			continue;
> >> +
> >> +		ret = drm_modeset_lock(&intel_crtc->base.mutex,
> >> +				       state->acquire_ctx);
> >> +		if (ret)
> >> +			return ret;
> >> +
> >> +		if (!intel_crtc->base.state->active)
> >> +			continue;
> > Imo just unconditionally acquire the crtc state, there' shouldn't be any
> > harm in that (as long as we leave mode/active/planes_changed untouched).
> Probably.
> >> +
> >> +		/* 2 enabled crtcs means no need for w/a */
> >> +		if (++enabled_crtcs >= 2)
> >> +			return 0;
> >> +
> >> +		enabled_crtc = intel_crtc;
> >> +	}
> >> +
> >> +	if (enabled_crtcs == 1)
> >> +		first_crtc_state->hsw_workaround_pipe = enabled_crtc->pipe;
> > first_crtc_state could be miscomputed if 1 crtc is already on and you add
> > another one. Then first_crtc will point at the other crtc since that's the
> > only one at first in the atomic set. Imo a simpler algo would be:
> No, in that case enabled_crtcs != 0 and enabled_crtc is set to the correct crtc.

Hm right I mixed up first_crtc_state and enabled_crtc. Looks correct on
second pass.

> > 1. Check whether your activating any crtc at all.
> > 2. If so add all crtc states.
> > 3. Same loop as the old one, just using for_each_crtc_in_state.
> >
> > There's other cases with shared resources where we need to grab all crtc
> > locks already anyway (shared dpll), trying to be clever doesn't seem
> > beneficial. And if this indeed becomes a problem then we need a global
> > state ww mutex and use that (instead of crtc locks) for this book-keeping:
> > First enable crtc would set global_state->hsw_wa_pipe, 2nd and later would
> > clear it. We might need this eventually (I've heard rumours about people
> > not liking stalls when unplugging external screens that much), but let's
> > not overcomplicate things while we do this conversion.
> You would still need it when disabling crtc's then. To do it right you would need to keep crtc->active,
> or use a crtc_mask, but that would be abused so I'd rather not. The crtc lock is also needed so the
> other crtc's cannot be disabled or enabled while modesetting, but I guess always taking the
> connector_mutex for that could work too.

Hm yeah connector_mutex is the general "global modeset state" lock. I
guess we could instead acquire that one and make sure that
crtc_state->active is also protected by it. I.e. have a

	for_each_crtc_in_state(crtc_state)
		if (crtc_state->active_changed)
			acquire_connection_mutex();

Maybe even do this in the helper check_modeset function? Well looking at
that one it's kinda guaranteed already, so a WARN_ON(!ww_mutex_locked)
should do the trick too. Plus a comment that crtc_state->active is
protected by the connection_mutex thanks to the helper's logic.

Going with that is fine with me too, I just feel like the current
open-coded locking logic is a bit too clever/complicated for what we want
to do.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-12 14:07     ` Maarten Lankhorst
@ 2015-05-12 16:57       ` Daniel Vetter
  2015-05-12 17:01         ` Daniel Stone
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 16:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:07:14PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 12:03 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 4:25 PM, Maarten Lankhorst
> > <maarten.lankhorst@linux.intel.com> wrote:
> >> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
> >>
> >>                 for_each_intel_crtc(dev, crtc) {
> >>                         if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> >> -                               enabled_crtcs++;
> >> -                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
> >>                                 active_crtcs++;
> >>                 }
> >>                 I915_STATE_WARN(pll->active != active_crtcs,
> >>                      "pll active crtcs mismatch (expected %i, found %i)\n",
> >>                      pll->active, active_crtcs);
> >> -               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
> >> +               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
> >>                      "pll enabled crtcs mismatch (expected %i, found %i)\n",
> >> -                    hweight32(pll->config.crtc_mask), enabled_crtcs);
> >> +                    hweight32(pll->config.crtc_mask), active_crtcs);
> >
> > Missed one: Why do you remove this? Imo that's a fairly crucial
> > consistency check.
> > -Daniel
> It's not removed, but crtc->active is the same as crtc->base.state->active now. The check still works as intended. :-)

Oh there's a confusion (maybe from ealier patches?). You derive
enabled_crtcs from state->active, but it should be derived from
state->enable. That's at least the case in current -nightly.

And active_crtcs should be derived from state->active ofc (currently
looking at intel_crtc->active). If I'm piecing the patches together the
active_crtcs case gets removed and the enabled_crtcs is mixing things up
after your series. We definitely need both of them still I think.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-12 16:57       ` Daniel Vetter
@ 2015-05-12 17:01         ` Daniel Stone
  2015-05-12 17:08           ` Daniel Vetter
  0 siblings, 1 reply; 98+ messages in thread
From: Daniel Stone @ 2015-05-12 17:01 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Ander Conselvan de Oliveira, intel-gfx

Hi,

On 12 May 2015 at 17:57, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, May 12, 2015 at 04:07:14PM +0200, Maarten Lankhorst wrote:
>> Op 12-05-15 om 12:03 schreef Daniel Vetter:
>> > On Mon, May 11, 2015 at 4:25 PM, Maarten Lankhorst
>> > <maarten.lankhorst@linux.intel.com> wrote:
>> >> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
>> >>                 for_each_intel_crtc(dev, crtc) {
>> >>                         if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
>> >> -                               enabled_crtcs++;
>> >> -                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
>> >>                                 active_crtcs++;
>> >>                 }
>> >>                 I915_STATE_WARN(pll->active != active_crtcs,
>> >>                      "pll active crtcs mismatch (expected %i, found %i)\n",
>> >>                      pll->active, active_crtcs);
>> >> -               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
>> >> +               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
>> >>                      "pll enabled crtcs mismatch (expected %i, found %i)\n",
>> >> -                    hweight32(pll->config.crtc_mask), enabled_crtcs);
>> >> +                    hweight32(pll->config.crtc_mask), active_crtcs);
>> >
>> > Missed one: Why do you remove this? Imo that's a fairly crucial
>> > consistency check.
>> > -Daniel
>> It's not removed, but crtc->active is the same as crtc->base.state->active now. The check still works as intended. :-)
>
> Oh there's a confusion (maybe from ealier patches?). You derive
> enabled_crtcs from state->active, but it should be derived from
> state->enable. That's at least the case in current -nightly.
>
> And active_crtcs should be derived from state->active ofc (currently
> looking at intel_crtc->active). If I'm piecing the patches together the
> active_crtcs case gets removed and the enabled_crtcs is mixing things up
> after your series. We definitely need both of them still I think.

I'll freely admit to getting lost in the maze, but is it that
crtc->base.state->active / enabled_crtcs is testing the to-be-enabled
set (pending state), and crtc->active / active_crtcs is testing the
was-previously-enabled set (old state)? If so, these checks are indeed
different, but it's kind of hard to tell. And we'd need to capture the
entire previous state to pass in. Maybe those would be better as two
separate checks; one before we swap the state, and one after?

Cheers,
Daniel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1
  2015-05-12 14:13     ` Maarten Lankhorst
@ 2015-05-12 17:01       ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 17:01 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:13:54PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 12:11 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:25:10PM +0200, Maarten Lankhorst wrote:
> >> Removed some occurences, roughly based on where the errors of
> >> removing crtc->config occured. Because it's used a lot in this
> >> file the changes are done in passes.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_display.c | 205 ++++++++++++++++++-----------------
> >>  drivers/gpu/drm/i915/intel_drv.h     |   4 +-
> >>  drivers/gpu/drm/i915/intel_lvds.c    |   2 +-
> >>  3 files changed, 105 insertions(+), 106 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 004067bd0b6c..fb2ecb65aaaa 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -1141,29 +1141,20 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
> >>  #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
> >>  #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
> >>  
> >> -struct intel_shared_dpll *
> >> -intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
> >> -{
> >> -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> >> -
> >> -	if (crtc->config->shared_dpll < 0)
> >> -		return NULL;
> >> -
> >> -	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
> >> -}
> >> -
> >>  /* For ILK+ */
> >>  void assert_shared_dpll(struct drm_i915_private *dev_priv,
> >> -			struct intel_shared_dpll *pll,
> >> +			enum intel_dpll_id shared_dpll,
> >>  			bool state)
> >>  {
> >> -	bool cur_state;
> >>  	struct intel_dpll_hw_state hw_state;
> >> +	struct intel_shared_dpll *pll;
> >> +	bool cur_state;
> >>  
> >> -	if (WARN (!pll,
> >> +	if (WARN(shared_dpll < 0,
> >>  		  "asserting DPLL %s with no DPLL\n", state_string(state)))
> >>  		return;
> >>  
> >> +	pll = &dev_priv->shared_dplls[shared_dpll];
> >>  	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
> >>  	I915_STATE_WARN(cur_state != state,
> >>  	     "%s assertion failure (expected %s, current %s)\n",
> >> @@ -1691,7 +1682,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
> >>  	struct drm_device *dev = crtc->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	int reg = DPLL(crtc->pipe);
> >> -	u32 dpll = crtc->config->dpll_hw_state.dpll;
> >> +	u32 dpll = pipe_config->dpll_hw_state.dpll;
> > Lots of your patches are sprinkled with unrelated crtc->config ->
> > pipe_config conversions. Or just plain rolling out of a local variable
> > instead of accessing some other pointer. That makes it fairly hard to
> > review them for a given topic (like shared dpll here) since it's never
> > clear whether it really includes everything, and what's the reason for all
> > the other hunks.
> >
> >>  
> >>  	assert_pipe_disabled(dev_priv, pipe_config->cpu_transcoder, crtc->pipe);
> >>  
> >> @@ -1721,7 +1712,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc, struct intel_crtc_state *pi
> >>  
> >>  	if (INTEL_INFO(dev)->gen >= 4) {
> >>  		I915_WRITE(DPLL_MD(crtc->pipe),
> >> -			   crtc->config->dpll_hw_state.dpll_md);
> >> +			   pipe_config->dpll_hw_state.dpll_md);
> >>  	} else {
> >>  		/* The pixel multiplier can only be updated once the
> >>  		 * DPLL is enabled and the clocks are stable.
> >> @@ -1859,20 +1850,19 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
> >>  		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
> >>  }
> >>  
> >> -static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
> >> +static void intel_prepare_shared_dpll(struct drm_i915_private *dev_priv,
> >> +				      enum intel_dpll_id shared_dpll)
> >>  {
> >> -	struct drm_device *dev = crtc->base.dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> >> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
> > Why change anything here? This is called from enable hooks, so can keep on
> > accessing intel_crtc->state ... or not?
> I got rid of intel_crtc_to_shared_dpll, because it only required
> pipe_config->shared_dpll I felt it could be passed as argument instead.

Yeah that makes sense where we need to pass in the right pipe_config. But
in the _enable functions just using to_intel_crtc_state(crtc->state) is
ok, and just doing that would cut down on the overall diff. Same idea as
not passing pipe_config around explicitly for other functions only called
from _enable hooks (and other places where crtc->state is the right
state).

I'm ok with open-coding the dpll lookup in compute/disable/get_config functions.

> 
> >>  
> >> -	if (WARN_ON(pll == NULL))
> >> +	if (WARN_ON(shared_dpll < 0))
> >>  		return;
> >>  
> >>  	WARN_ON(!pll->config.crtc_mask);
> >>  	if (pll->active == 0) {
> >>  		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
> >>  		WARN_ON(pll->on);
> >> -		assert_shared_dpll_disabled(dev_priv, pll);
> >> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
> >>  
> >>  		pll->mode_set(dev_priv, pll);
> >>  	}
> >> @@ -1886,25 +1876,23 @@ static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
> >>   * The PCH PLL needs to be enabled before the PCH transcoder, since it
> >>   * drives the transcoder clock.
> >>   */
> >> -static void intel_enable_shared_dpll(struct intel_crtc *crtc)
> >> +static void intel_enable_shared_dpll(struct drm_i915_private *dev_priv,
> >> +				     enum intel_dpll_id shared_dpll)
> >>  {
> >> -	struct drm_device *dev = crtc->base.dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> >> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
> >>  
> >> -	if (WARN_ON(pll == NULL))
> >> +	if (WARN_ON(shared_dpll < 0))
> >>  		return;
> >>  
> >>  	if (WARN_ON(pll->config.crtc_mask == 0))
> >>  		return;
> >>  
> >> -	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
> >> -		      pll->name, pll->active, pll->on,
> >> -		      crtc->base.base.id);
> >> +	DRM_DEBUG_KMS("enable %s (active %d, on? %d)\n",
> >> +		      pll->name, pll->active, pll->on);
> >>  
> >>  	if (pll->active++) {
> >>  		WARN_ON(!pll->on);
> >> -		assert_shared_dpll_enabled(dev_priv, pll);
> >> +		assert_shared_dpll_enabled(dev_priv, shared_dpll);
> >>  		return;
> >>  	}
> >>  	WARN_ON(pll->on);
> >> @@ -1916,30 +1904,29 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
> >>  	pll->on = true;
> >>  }
> >>  
> >> -static void intel_disable_shared_dpll(struct intel_crtc *crtc)
> >> +static void intel_disable_shared_dpll(struct drm_i915_private *dev_priv,
> >> +				      enum intel_dpll_id shared_dpll)
> >>  {
> >> -	struct drm_device *dev = crtc->base.dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
> >> +	struct intel_shared_dpll *pll = &dev_priv->shared_dplls[shared_dpll];
> >> +
> >> +	if (shared_dpll < 0)
> >> +		return;
> >>  
> >>  	/* PCH only available on ILK+ */
> >> -	BUG_ON(INTEL_INFO(dev)->gen < 5);
> >> -	if (WARN_ON(pll == NULL))
> >> -	       return;
> >> +	BUG_ON(dev_priv->info.gen < 5);
> >>  
> >>  	if (WARN_ON(pll->config.crtc_mask == 0))
> >>  		return;
> >>  
> >> -	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
> >> -		      pll->name, pll->active, pll->on,
> >> -		      crtc->base.base.id);
> >> +	DRM_DEBUG_KMS("disable %s (active %d, on? %d)\n",
> >> +		      pll->name, pll->active, pll->on);
> >>  
> >>  	if (WARN_ON(pll->active == 0)) {
> >> -		assert_shared_dpll_disabled(dev_priv, pll);
> >> +		assert_shared_dpll_disabled(dev_priv, shared_dpll);
> >>  		return;
> >>  	}
> >>  
> >> -	assert_shared_dpll_enabled(dev_priv, pll);
> >> +	assert_shared_dpll_enabled(dev_priv, shared_dpll);
> >>  	WARN_ON(!pll->on);
> >>  	if (--pll->active)
> >>  		return;
> >> @@ -1964,8 +1951,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
> >>  	BUG_ON(!HAS_PCH_SPLIT(dev));
> >>  
> >>  	/* Make sure PCH DPLL is enabled */
> >> -	assert_shared_dpll_enabled(dev_priv,
> >> -				   intel_crtc_to_shared_dpll(intel_crtc));
> >> +	assert_shared_dpll_enabled(dev_priv, pipe_config->shared_dpll);
> >>  
> >>  	/* FDI must be feeding us bits for PCH ports */
> >>  	assert_fdi_tx_enabled(dev_priv, pipe_config->cpu_transcoder, pipe);
> >> @@ -2126,7 +2112,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
> >>  		else
> >>  			assert_pll_enabled(dev_priv, pipe);
> >>  	else {
> >> -		if (crtc->config->has_pch_encoder) {
> >> +		if (pipe_config->has_pch_encoder) {
> >>  			/* if driving the PCH, we need FDI enabled */
> >>  			assert_fdi_rx_pll_enabled(dev_priv, pch_transcoder);
> >>  			assert_fdi_tx_pll_enabled(dev_priv,
> >> @@ -2622,6 +2608,8 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>  	bool visible = to_intel_plane_state(primary->state)->visible;
> >>  	struct drm_i915_gem_object *obj;
> >>  	int plane = intel_crtc->plane;
> >> +	struct intel_crtc_state *pipe_config =
> >> +		to_intel_crtc_state(crtc->state);
> >>  	unsigned long linear_offset;
> >>  	u32 dspcntr;
> >>  	u32 reg = DSPCNTR(plane);
> >> @@ -2655,13 +2643,13 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>  		 * which should always be the user's requested size.
> >>  		 */
> >>  		I915_WRITE(DSPSIZE(plane),
> >> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
> >> -			   (intel_crtc->config->pipe_src_w - 1));
> >> +			   ((pipe_config->pipe_src_h - 1) << 16) |
> >> +			   (pipe_config->pipe_src_w - 1));
> >>  		I915_WRITE(DSPPOS(plane), 0);
> >>  	} else if (IS_CHERRYVIEW(dev) && plane == PLANE_B) {
> >>  		I915_WRITE(PRIMSIZE(plane),
> >> -			   ((intel_crtc->config->pipe_src_h - 1) << 16) |
> >> -			   (intel_crtc->config->pipe_src_w - 1));
> >> +			   ((pipe_config->pipe_src_h - 1) << 16) |
> >> +			   (pipe_config->pipe_src_w - 1));
> >>  		I915_WRITE(PRIMPOS(plane), 0);
> >>  		I915_WRITE(PRIMCNSTALPHA(plane), 0);
> >>  	}
> >> @@ -2719,14 +2707,14 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
> >>  		dspcntr |= DISPPLANE_ROTATE_180;
> >>  
> >> -		x += (intel_crtc->config->pipe_src_w - 1);
> >> -		y += (intel_crtc->config->pipe_src_h - 1);
> >> +		x += (pipe_config->pipe_src_w - 1);
> >> +		y += (pipe_config->pipe_src_h - 1);
> >>  
> >>  		/* Finding the last pixel of the last line of the display
> >>  		data and adding to linear_offset*/
> >>  		linear_offset +=
> >> -			(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
> >> -			(intel_crtc->config->pipe_src_w - 1) * pixel_size;
> >> +			(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
> >> +			(pipe_config->pipe_src_w - 1) * pixel_size;
> > Unrelated changes above, or do I miss something?
> What's unrelated? But yeah I mostly split it up by fixing things up
> until it started compiling again. I should split the display stuff up
> further.

i9xx_update_primary_plane doesn't have any shared dpll code, which means
this s/crtc->config/pipe_config replacement should probably be in a
different patch.

> >>  	}
> >>  
> >>  	I915_WRITE(reg, dspcntr);
> >> @@ -2818,17 +2806,20 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>  					       fb->pitches[0]);
> >>  	linear_offset -= intel_crtc->dspaddr_offset;
> >>  	if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180)) {
> >> +		struct intel_crtc_state *pipe_config =
> >> +			to_intel_crtc_state(crtc->state);
> >> +
> >>  		dspcntr |= DISPPLANE_ROTATE_180;
> >>  
> >>  		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
> >> -			x += (intel_crtc->config->pipe_src_w - 1);
> >> -			y += (intel_crtc->config->pipe_src_h - 1);
> >> +			x += (pipe_config->pipe_src_w - 1);
> >> +			y += (pipe_config->pipe_src_h - 1);
> >>  
> >>  			/* Finding the last pixel of the last line of the display
> >>  			data and adding to linear_offset*/
> >>  			linear_offset +=
> >> -				(intel_crtc->config->pipe_src_h - 1) * fb->pitches[0] +
> >> -				(intel_crtc->config->pipe_src_w - 1) * pixel_size;
> >> +				(pipe_config->pipe_src_h - 1) * fb->pitches[0] +
> >> +				(pipe_config->pipe_src_w - 1) * pixel_size;
> >>  		}
> >>  	}
> >>  
> >> @@ -2901,12 +2892,13 @@ void skl_detach_scalers(struct intel_crtc *intel_crtc)
> >>  	struct intel_crtc_scaler_state *scaler_state;
> >>  	int i;
> >>  
> >> -	if (!intel_crtc || !intel_crtc->config)
> >> +	if (!intel_crtc)
> >>  		return;
> >>  
> >>  	dev = intel_crtc->base.dev;
> >>  	dev_priv = dev->dev_private;
> >> -	scaler_state = &intel_crtc->config->scaler_state;
> >> +	scaler_state =
> >> +		&to_intel_crtc_state(intel_crtc->base.state)->scaler_state;
> >>  
> >>  	/* loop through and disable scalers that aren't in use */
> >>  	for (i = 0; i < intel_crtc->num_scalers; i++) {
> >> @@ -3298,6 +3290,8 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
> >>  	struct drm_device *dev = crtc->base.dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	const struct drm_display_mode *adjusted_mode;
> >> +	struct intel_crtc_state *pipe_config =
> >> +		to_intel_crtc_state(crtc->base.state);
> >>  
> >>  	if (!i915.fastboot)
> >>  		return;
> >> @@ -3316,20 +3310,20 @@ static void intel_update_pipe_size(struct intel_crtc *crtc)
> >>  	 * then update the pipesrc and pfit state, even on the flip path.
> >>  	 */
> >>  
> >> -	adjusted_mode = &crtc->config->base.adjusted_mode;
> >> +	adjusted_mode = &pipe_config->base.adjusted_mode;
> >>  
> >>  	I915_WRITE(PIPESRC(crtc->pipe),
> >>  		   ((adjusted_mode->crtc_hdisplay - 1) << 16) |
> >>  		   (adjusted_mode->crtc_vdisplay - 1));
> >> -	if (!crtc->config->pch_pfit.enabled &&
> >> +	if (!pipe_config->pch_pfit.enabled &&
> >>  	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
> >>  	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
> >>  		I915_WRITE(PF_CTL(crtc->pipe), 0);
> >>  		I915_WRITE(PF_WIN_POS(crtc->pipe), 0);
> >>  		I915_WRITE(PF_WIN_SZ(crtc->pipe), 0);
> >>  	}
> >> -	crtc->config->pipe_src_w = adjusted_mode->crtc_hdisplay;
> >> -	crtc->config->pipe_src_h = adjusted_mode->crtc_vdisplay;
> >> +	pipe_config->pipe_src_w = adjusted_mode->crtc_hdisplay;
> >> +	pipe_config->pipe_src_h = adjusted_mode->crtc_vdisplay;
> >>  }
> >>  
> >>  static void intel_fdi_normal_train(struct drm_crtc *crtc)
> >> @@ -3379,6 +3373,8 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
> >>  	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> +	struct intel_crtc_state *pipe_config =
> >> +		to_intel_crtc_state(crtc->state);
> >>  	int pipe = intel_crtc->pipe;
> >>  	u32 reg, temp, tries;
> >>  
> >> @@ -3396,7 +3392,7 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
> >>  	reg = FDI_TX_CTL(pipe);
> >>  	temp = I915_READ(reg);
> >>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
> >> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> >> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
> >>  	temp &= ~FDI_LINK_TRAIN_NONE;
> >>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
> >>  	I915_WRITE(reg, temp | FDI_TX_ENABLE);
> >> @@ -3476,6 +3472,8 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
> >>  	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> +	struct intel_crtc_state *pipe_config =
> >> +		to_intel_crtc_state(crtc->state);
> >>  	int pipe = intel_crtc->pipe;
> >>  	u32 reg, temp, i, retry;
> >>  
> >> @@ -3494,7 +3492,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
> >>  	reg = FDI_TX_CTL(pipe);
> >>  	temp = I915_READ(reg);
> >>  	temp &= ~FDI_DP_PORT_WIDTH_MASK;
> >> -	temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> >> +	temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
> >>  	temp &= ~FDI_LINK_TRAIN_NONE;
> >>  	temp |= FDI_LINK_TRAIN_PATTERN_1;
> >>  	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> >> @@ -3608,6 +3606,8 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
> >>  	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> +	struct intel_crtc_state *pipe_config =
> >> +		to_intel_crtc_state(crtc->state);
> >>  	int pipe = intel_crtc->pipe;
> >>  	u32 reg, temp, i, j;
> >>  
> >> @@ -3645,7 +3645,7 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
> >>  		reg = FDI_TX_CTL(pipe);
> >>  		temp = I915_READ(reg);
> >>  		temp &= ~FDI_DP_PORT_WIDTH_MASK;
> >> -		temp |= FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
> >> +		temp |= FDI_DP_PORT_WIDTH(pipe_config->fdi_lanes);
> >>  		temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
> >>  		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> >>  		temp |= snb_b_fdi_train_param[j/2];
> >> @@ -3914,11 +3914,10 @@ void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
> >>  }
> >>  
> >>  /* Program iCLKIP clock to the desired frequency */
> >> -static void lpt_program_iclkip(struct drm_crtc *crtc)
> >> +static void lpt_program_iclkip(struct drm_i915_private *dev_priv,
> >> +			       struct intel_crtc_state *pipe_config)
> >>  {
> >> -	struct drm_device *dev = crtc->dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	int clock = to_intel_crtc(crtc)->config->base.adjusted_mode.crtc_clock;
> >> +	int clock = pipe_config->base.adjusted_mode.crtc_clock;
> >>  	u32 divsel, phaseinc, auxdiv, phasedir = 0;
> >>  	u32 temp;
> >>  
> >> @@ -4002,13 +4001,10 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
> >>  	mutex_unlock(&dev_priv->dpio_lock);
> >>  }
> >>  
> >> -static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
> >> +static void ironlake_pch_transcoder_set_timings(struct drm_i915_private *dev_priv,
> >> +						enum transcoder cpu_transcoder,
> >>  						enum pipe pch_transcoder)
> >>  {
> >> -	struct drm_device *dev = crtc->base.dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
> >> -
> >>  	I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder),
> >>  		   I915_READ(HTOTAL(cpu_transcoder)));
> >>  	I915_WRITE(PCH_TRANS_HBLANK(pch_transcoder),
> >> @@ -4026,7 +4022,8 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc,
> >>  		   I915_READ(VSYNCSHIFT(cpu_transcoder)));
> >>  }
> >>  
> >> -static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
> >> +static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev,
> >> +				       bool enable)
> >>  {
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >>  	uint32_t temp;
> >> @@ -4047,15 +4044,15 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable)
> >>  	POSTING_READ(SOUTH_CHICKEN1);
> >>  }
> >>  
> >> -static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
> >> +static void ivybridge_update_fdi_bc_bifurcation(struct drm_device *dev,
> >> +					struct intel_crtc *intel_crtc,
> >> +					struct intel_crtc_state *pipe_config)
> >>  {
> >> -	struct drm_device *dev = intel_crtc->base.dev;
> >> -
> >>  	switch (intel_crtc->pipe) {
> >>  	case PIPE_A:
> >>  		break;
> >>  	case PIPE_B:
> >> -		if (intel_crtc->config->fdi_lanes > 2)
> >> +		if (pipe_config->fdi_lanes > 2)
> >>  			cpt_set_fdi_bc_bifurcation(dev, false);
> >>  		else
> >>  			cpt_set_fdi_bc_bifurcation(dev, true);
> >> @@ -4078,7 +4075,8 @@ static void ivybridge_update_fdi_bc_bifurcation(struct intel_crtc *intel_crtc)
> >>   *   - DP transcoding bits
> >>   *   - transcoder
> >>   */
> >> -static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *pipe_config)
> >> +static void ironlake_pch_enable(struct drm_crtc *crtc,
> >> +				struct intel_crtc_state *pipe_config)
> >>  {
> >>  	struct drm_device *dev = crtc->dev;
> >>  	struct drm_i915_private *dev_priv = dev->dev_private;
> >> @@ -4089,7 +4087,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
> >>  	assert_pch_transcoder_disabled(dev_priv, pipe);
> >>  
> >>  	if (IS_IVYBRIDGE(dev))
> >> -		ivybridge_update_fdi_bc_bifurcation(intel_crtc);
> >> +		ivybridge_update_fdi_bc_bifurcation(dev, intel_crtc,
> >> +						    pipe_config);
> >>  
> >>  	/* Write the TU size bits before fdi link training, so that error
> >>  	 * detection works. */
> >> @@ -4121,11 +4120,12 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
> >>  	 * Note that enable_shared_dpll tries to do the right thing, but
> >>  	 * get_shared_dpll unconditionally resets the pll - we need that to have
> >>  	 * the right LVDS enable sequence. */
> >> -	intel_enable_shared_dpll(intel_crtc);
> >> +	intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
> >>  
> >>  	/* set transcoder timing, panel must allow it */
> >>  	assert_panel_unlocked(dev_priv, pipe);
> >> -	ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
> >> +	ironlake_pch_transcoder_set_timings(dev_priv,
> >> +					    pipe_config->cpu_transcoder, pipe);
> >>  
> >>  	intel_fdi_normal_train(crtc);
> >>  
> >> @@ -4166,19 +4166,17 @@ static void ironlake_pch_enable(struct drm_crtc *crtc, struct intel_crtc_state *
> >>  	ironlake_enable_pch_transcoder(dev_priv, pipe, pipe_config);
> >>  }
> >>  
> >> -static void lpt_pch_enable(struct drm_crtc *crtc)
> >> +static void lpt_pch_enable(struct drm_i915_private *dev_priv,
> >> +			   struct intel_crtc_state *pipe_config)
> >>  {
> >> -	struct drm_device *dev = crtc->dev;
> >> -	struct drm_i915_private *dev_priv = dev->dev_private;
> >> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >> -	enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
> >> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> >>  
> >>  	assert_pch_transcoder_disabled(dev_priv, TRANSCODER_A);
> >>  
> >> -	lpt_program_iclkip(crtc);
> >> +	lpt_program_iclkip(dev_priv, pipe_config);
> >>  
> >>  	/* Set transcoder timing. */
> >> -	ironlake_pch_transcoder_set_timings(intel_crtc, PIPE_A);
> >> +	ironlake_pch_transcoder_set_timings(dev_priv, cpu_transcoder, PIPE_A);
> >>  
> >>  	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
> >>  }
> >> @@ -4781,7 +4779,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
> >>  	pipe_config = to_intel_crtc_state(crtc->state);
> >>  
> >>  	if (pipe_config->has_pch_encoder)
> >> -		intel_prepare_shared_dpll(intel_crtc);
> >> +		intel_prepare_shared_dpll(dev_priv,
> >> +					  pipe_config->shared_dpll);
> >>  
> >>  	if (pipe_config->has_dp_encoder)
> >>  		intel_dp_set_m_n(intel_crtc, M1_N1);
> >> @@ -4854,8 +4853,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >>  	WARN_ON(!crtc->state->enable);
> >>  
> >>  	pipe_config = to_intel_crtc_state(crtc->state);
> >> -	if (intel_crtc_to_shared_dpll(intel_crtc))
> >> -		intel_enable_shared_dpll(intel_crtc);
> >> +	if (pipe_config->shared_dpll >= 0)
> >> +		intel_enable_shared_dpll(dev_priv, pipe_config->shared_dpll);
> >>  
> >>  	if (pipe_config->has_dp_encoder)
> >>  		intel_dp_set_m_n(intel_crtc, M1_N1);
> >> @@ -4910,7 +4909,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >>  	intel_enable_pipe(intel_crtc);
> >>  
> >>  	if (intel_crtc->config->has_pch_encoder)
> >> -		lpt_pch_enable(crtc);
> >> +		lpt_pch_enable(dev_priv, pipe_config);
> >>  
> >>  	if (intel_crtc->config->dp_encoder_is_mst)
> >>  		intel_ddi_set_vc_payload_alloc(crtc,
> >> @@ -11929,7 +11928,8 @@ check_shared_dpll_state(struct drm_device *dev)
> >>  		     pll->on, active);
> >>  
> >>  		for_each_intel_crtc(dev, crtc) {
> >> -			if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> >> +			if (crtc->base.state->active &&
> >> +			    to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
> >>  				active_crtcs++;
> >>  		}
> >>  		I915_STATE_WARN(pll->active != active_crtcs,
> >> @@ -12311,7 +12311,6 @@ static int __intel_set_mode(struct drm_atomic_state *state)
> >>  	__intel_set_mode_update_planes(dev, state);
> >>  
> >>  	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
> >> -		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >>  		struct intel_crtc_state *pipe_config;
> >>  
> >>  		if (!needs_modeset(crtc->state))
> >> @@ -12324,8 +12323,7 @@ static int __intel_set_mode(struct drm_atomic_state *state)
> >>  		intel_crtc_dpms_overlay_disable(to_intel_crtc(crtc));
> >>  		dev_priv->display.crtc_disable(crtc, pipe_config);
> >>  
> >> -		if (intel_crtc_to_shared_dpll(intel_crtc))
> >> -			intel_disable_shared_dpll(intel_crtc);
> >> +		intel_disable_shared_dpll(dev_priv, pipe_config->shared_dpll);
> >>  	}
> >>  
> >>  	/* Only after disabling all output pipelines that will be changed can we
> >> @@ -12719,7 +12717,9 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
> >>  
> >>  	/* Make sure no transcoder isn't still depending on us. */
> >>  	for_each_intel_crtc(dev, crtc) {
> >> -		if (intel_crtc_to_shared_dpll(crtc) == pll)
> >> +		int i = pll - dev_priv->shared_dplls;
> >> +
> >> +		if (to_intel_crtc_state(crtc->base.state)->shared_dpll == i)
> >>  			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
> >>  	}
> > This is called with the with the new config already put in place, but it
> > should check whether any of the _old_ pipe configs that used the dpll are
> > really all shut down. This won't misfire since if we shut it down to use
> > it in some other configuration then those pipes should be ofc off too.
> > Otoh we do check before enabling the pipe that the dpll is running, hence
> > I think this is redundant and maybe we could remove
> > it right away?
> Removing sounds fine.

If you do, separate patch please. Yes I'm asking that a lot, but I'm also
super-scared of all these changes here ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit
  2015-05-12 14:16     ` Maarten Lankhorst
@ 2015-05-12 17:03       ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 17:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 04:16:13PM +0200, Maarten Lankhorst wrote:
> Op 12-05-15 om 15:03 schreef Daniel Vetter:
> > On Mon, May 11, 2015 at 04:25:13PM +0200, Maarten Lankhorst wrote:
> >> crtc->config is gone, swap swap swap. :D
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_atomic.c  | 36 ++----------------------------------
> >>  drivers/gpu/drm/i915/intel_display.c |  7 +++++--
> >>  2 files changed, 7 insertions(+), 36 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> >> index ace6aeeb1359..0315dc44b17a 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> >> @@ -130,7 +130,6 @@ int intel_atomic_commit(struct drm_device *dev,
> >>  			bool async)
> >>  {
> >>  	int ret;
> >> -	int i;
> >>  
> >>  	if (async) {
> >>  		DRM_DEBUG_KMS("i915 does not yet support async commit\n");
> >> @@ -142,48 +141,17 @@ int intel_atomic_commit(struct drm_device *dev,
> >>  		return ret;
> >>  
> >>  	/* Point of no return */
> >> +	drm_atomic_helper_swap_state(dev, state);
> >>  
> >>  	/*
> >>  	 * FIXME:  The proper sequence here will eventually be:
> >>  	 *
> >> -	 * drm_atomic_helper_swap_state(dev, state)
> >>  	 * drm_atomic_helper_commit_modeset_disables(dev, state);
> >>  	 * drm_atomic_helper_commit_planes(dev, state);
> >>  	 * drm_atomic_helper_commit_modeset_enables(dev, state);
> >> -	 * drm_atomic_helper_wait_for_vblanks(dev, state);
> >> -	 * drm_atomic_helper_cleanup_planes(dev, state);
> >> -	 * drm_atomic_state_free(state);
> >> -	 *
> >> -	 * once we have full atomic modeset.  For now, just manually update
> >> -	 * plane states to avoid clobbering good states with dummy states
> >> -	 * while nuclear pageflipping.
> >>  	 */
> >> -	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
> >> -		struct drm_plane *plane = state->planes[i];
> >> -
> >> -		if (!plane)
> >> -			continue;
> >> -
> >> -		plane->state->state = state;
> >> -		swap(state->plane_states[i], plane->state);
> >> -		plane->state->state = NULL;
> >> -	}
> >> -
> >> -	/* swap crtc_scaler_state */
> >> -	for (i = 0; i < dev->mode_config.num_crtc; i++) {
> >> -		struct drm_crtc *crtc = state->crtcs[i];
> >> -		if (!crtc) {
> >> -			continue;
> >> -		}
> >> -
> >> -		to_intel_crtc_state(crtc->state)->scaler_state =
> >> -			to_intel_crtc_state(state->crtc_states[i])->scaler_state;
> >> -
> >> -		if (INTEL_INFO(dev)->gen >= 9)
> >> -			skl_detach_scalers(to_intel_crtc(crtc));
> >> -	}
> >> -
> >>  	drm_atomic_helper_commit_planes(dev, state);
> >> +
> >>  	drm_atomic_helper_wait_for_vblanks(dev, state);
> >>  	drm_atomic_helper_cleanup_planes(dev, state);
> >>  	drm_atomic_state_free(state);
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 65ee2cd0437c..105bdf84e46a 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -13202,11 +13202,14 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc)
> >>  
> >>  	/* Perform vblank evasion around commit operation */
> >>  	if (intel_crtc->atomic.evade &&
> >> -	    !dev_priv->power_domains.init_power_on)
> >> +	    !dev_priv->power_domains.init_power_on) {
> >> +		if (dev_priv->info.gen >= 9)
> >> +			skl_detach_scalers(to_intel_crtc(crtc));
> > Don't we need to update skl_detach_scalers to look at the other config
> > now? Or is this an issue with the patch splitting?
> >
> > Also why is this protected by atomic.evade?
> Mostly to not run if a modeset's done, that already kills the scalers.

As mentioned in another reply we don't really want to disable the evade
logic for modesets. And if this is to be avoided for !modeset then it's
clearer to check for that explicitly.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 33/42] drm/i915: remove crtc->active tracking completely
  2015-05-12 17:01         ` Daniel Stone
@ 2015-05-12 17:08           ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-12 17:08 UTC (permalink / raw)
  To: Daniel Stone; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Tue, May 12, 2015 at 06:01:40PM +0100, Daniel Stone wrote:
> Hi,
> 
> On 12 May 2015 at 17:57, Daniel Vetter <daniel@ffwll.ch> wrote:
> > On Tue, May 12, 2015 at 04:07:14PM +0200, Maarten Lankhorst wrote:
> >> Op 12-05-15 om 12:03 schreef Daniel Vetter:
> >> > On Mon, May 11, 2015 at 4:25 PM, Maarten Lankhorst
> >> > <maarten.lankhorst@linux.intel.com> wrote:
> >> >> @@ -11953,16 +11930,14 @@ check_shared_dpll_state(struct drm_device *dev)
> >> >>                 for_each_intel_crtc(dev, crtc) {
> >> >>                         if (crtc->base.state->active && intel_crtc_to_shared_dpll(crtc) == pll)
> >> >> -                               enabled_crtcs++;
> >> >> -                       if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
> >> >>                                 active_crtcs++;
> >> >>                 }
> >> >>                 I915_STATE_WARN(pll->active != active_crtcs,
> >> >>                      "pll active crtcs mismatch (expected %i, found %i)\n",
> >> >>                      pll->active, active_crtcs);
> >> >> -               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != enabled_crtcs,
> >> >> +               I915_STATE_WARN(hweight32(pll->config.crtc_mask) != active_crtcs,
> >> >>                      "pll enabled crtcs mismatch (expected %i, found %i)\n",
> >> >> -                    hweight32(pll->config.crtc_mask), enabled_crtcs);
> >> >> +                    hweight32(pll->config.crtc_mask), active_crtcs);
> >> >
> >> > Missed one: Why do you remove this? Imo that's a fairly crucial
> >> > consistency check.
> >> > -Daniel
> >> It's not removed, but crtc->active is the same as crtc->base.state->active now. The check still works as intended. :-)
> >
> > Oh there's a confusion (maybe from ealier patches?). You derive
> > enabled_crtcs from state->active, but it should be derived from
> > state->enable. That's at least the case in current -nightly.
> >
> > And active_crtcs should be derived from state->active ofc (currently
> > looking at intel_crtc->active). If I'm piecing the patches together the
> > active_crtcs case gets removed and the enabled_crtcs is mixing things up
> > after your series. We definitely need both of them still I think.
> 
> I'll freely admit to getting lost in the maze, but is it that
> crtc->base.state->active / enabled_crtcs is testing the to-be-enabled
> set (pending state), and crtc->active / active_crtcs is testing the
> was-previously-enabled set (old state)? If so, these checks are indeed
> different, but it's kind of hard to tell. And we'd need to capture the
> entire previous state to pass in. Maybe those would be better as two
> separate checks; one before we swap the state, and one after?

This is state config cross-checks done at the end, so never looks at
transitions but only at snapshots.

enabled = logically enabled, i.e. resources are reserved to make sure dpms
on will succeed
active = hw actually running

And active always implies enabled.

We have that distinction both on the crtc and by necessity also on the
dplls used by them. But somehow that got a bit mixed up in Maarten's
series here. Current -nightly still keeps them nicely separate.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state
  2015-05-11 14:24 ` [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state Maarten Lankhorst
@ 2015-05-13  5:52   ` Daniel Vetter
  0 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-13  5:52 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx, dri-devel

On Mon, May 11, 2015 at 4:24 PM, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
> Drivers may need to store the state of shared resources, such as PLLs
> or FIFO space, into the atomic state. Allow this by making it possible
> to subclass drm_atomic_state.
>
> Cc: dri-devel@lists.freedesktop.org
> Acked-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

A few naming change suggestions below ...
> ---
>  drivers/gpu/drm/drm_atomic.c | 91 ++++++++++++++++++++++++++++++++------------
>  include/drm/drm_atomic.h     |  4 ++
>  include/drm/drm_crtc.h       |  4 ++
>  3 files changed, 74 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 6e3b78ee7d16..f0f914591f1d 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -38,24 +38,19 @@ static void kfree_state(struct drm_atomic_state *state)
>         kfree(state->crtc_states);
>         kfree(state->planes);
>         kfree(state->plane_states);
> -       kfree(state);
>  }
>
>  /**
> - * drm_atomic_state_alloc - allocate atomic state
> + * __drm_atomic_new_state - init new atomic state
>   * @dev: DRM device
> + * @state: atomic state
>   *
> - * This allocates an empty atomic state to track updates.
> + * Default implementation for filling in a new atomic state.
> + * This is useful for drivers that subclass the atomic state.
>   */
> -struct drm_atomic_state *
> -drm_atomic_state_alloc(struct drm_device *dev)
> +int __drm_atomic_new_state(struct drm_device *dev,
> +                          struct drm_atomic_state *state)

Generally the naming pattern is _object_create/alloc for
allocating+initializing an object, and _object_init for just
initializing it. So imo better to call this drm_atomic_state_init
without any __ prefix or similar.

>  {
> -       struct drm_atomic_state *state;
> -
> -       state = kzalloc(sizeof(*state), GFP_KERNEL);
> -       if (!state)
> -               return NULL;
> -
>         /* TODO legacy paths should maybe do a better job about
>          * setting this appropriately?
>          */
> @@ -92,31 +87,50 @@ drm_atomic_state_alloc(struct drm_device *dev)
>
>         state->dev = dev;
>
> -       DRM_DEBUG_ATOMIC("Allocate atomic state %p\n", state);
> +       DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
>
> -       return state;
> +       return 0;
>  fail:
>         kfree_state(state);
> +       return -ENOMEM;
> +}
> +EXPORT_SYMBOL(__drm_atomic_new_state);
>
> -       return NULL;
> +/**
> + * drm_atomic_state_alloc - allocate atomic state
> + * @dev: DRM device
> + *
> + * This allocates an empty atomic state to track updates.
> + */
> +struct drm_atomic_state *
> +drm_atomic_state_alloc(struct drm_device *dev)
> +{
> +       struct drm_mode_config *config = &dev->mode_config;
> +       struct drm_atomic_state *state;
> +
> +       if (!config->funcs->atomic_new_state) {
> +               state = kzalloc(sizeof(*state), GFP_KERNEL);
> +               if (!state)
> +                       return NULL;
> +               if (__drm_atomic_new_state(dev, state) < 0) {
> +                       kfree(state);
> +                       return NULL;
> +               }
> +               return state;
> +       }
> +
> +       return config->funcs->atomic_new_state(dev);

Since this vfunc replaces drm_atomic_state_alloc completely I think it
should be called atomic_state_alloc to match that. And not the
init-only function above.

>  }
>  EXPORT_SYMBOL(drm_atomic_state_alloc);
>
>  /**
> - * drm_atomic_state_clear - clear state object
> + * __drm_atomic_clear_state - clear atomic state
>   * @state: atomic state
>   *
> - * When the w/w mutex algorithm detects a deadlock we need to back off and drop
> - * all locks. So someone else could sneak in and change the current modeset
> - * configuration. Which means that all the state assembled in @state is no
> - * longer an atomic update to the current state, but to some arbitrary earlier
> - * state. Which could break assumptions the driver's ->atomic_check likely
> - * relies on.
> - *
> - * Hence we must clear all cached state and completely start over, using this
> - * function.
> + * Default implementation for clearing atomic state.
> + * This is useful for drivers that subclass the atomic state.
>   */
> -void drm_atomic_state_clear(struct drm_atomic_state *state)
> +void __drm_atomic_clear_state(struct drm_atomic_state *state)

We've gone with __ in the duplicate/destroy functions for lack of any
good names, but here drm_atomic_state_default_clear looks imo good and
is much clearer.

>  {
>         struct drm_device *dev = state->dev;
>         struct drm_mode_config *config = &dev->mode_config;
> @@ -162,6 +176,32 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
>                 state->plane_states[i] = NULL;
>         }
>  }
> +EXPORT_SYMBOL(__drm_atomic_clear_state);
> +
> +/**
> + * drm_atomic_state_clear - clear state object
> + * @state: atomic state
> + *
> + * When the w/w mutex algorithm detects a deadlock we need to back off and drop
> + * all locks. So someone else could sneak in and change the current modeset
> + * configuration. Which means that all the state assembled in @state is no
> + * longer an atomic update to the current state, but to some arbitrary earlier
> + * state. Which could break assumptions the driver's ->atomic_check likely
> + * relies on.
> + *
> + * Hence we must clear all cached state and completely start over, using this
> + * function.
> + */
> +void drm_atomic_state_clear(struct drm_atomic_state *state)
> +{
> +       struct drm_device *dev = state->dev;
> +       struct drm_mode_config *config = &dev->mode_config;
> +
> +       if (config->funcs->atomic_clear_state)
> +               config->funcs->atomic_clear_state(state);

Let's not mix up word order for no reason and call this hook atomic_state_clear.

> +       else
> +               __drm_atomic_clear_state(state);
> +}
>  EXPORT_SYMBOL(drm_atomic_state_clear);
>
>  /**
> @@ -181,6 +221,7 @@ void drm_atomic_state_free(struct drm_atomic_state *state)
>         DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
>
>         kfree_state(state);
> +       kfree(state);

I think the kerneldoc somewhere must mention that if when subclassing
struct drm_atomic_state must be the first member. Or we simply add an
atomic_state_free hook for completeness - the kfree_state could still
be done here.

Actually I think atomic_state_free is required, or how is the driver
supposed to release additional allocations (e.g. for i915 shared dpll
state we probably should just have pointers to the dpll state
objects)?

Cheers, Daniel

>  }
>  EXPORT_SYMBOL(drm_atomic_state_free);
>
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index c157103492b0..6125eec6ad79 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -35,6 +35,10 @@ drm_atomic_state_alloc(struct drm_device *dev);
>  void drm_atomic_state_clear(struct drm_atomic_state *state);
>  void drm_atomic_state_free(struct drm_atomic_state *state);
>
> +int  __must_check
> +__drm_atomic_new_state(struct drm_device *dev, struct drm_atomic_state *state);
> +void __drm_atomic_clear_state(struct drm_atomic_state *state);
> +
>  struct drm_crtc_state * __must_check
>  drm_atomic_get_crtc_state(struct drm_atomic_state *state,
>                           struct drm_crtc *crtc);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 0a4a040d6bb7..e5bea3a45484 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -983,6 +983,8 @@ struct drm_mode_set {
>   * @atomic_check: check whether a given atomic state update is possible
>   * @atomic_commit: commit an atomic state update previously verified with
>   *     atomic_check()
> + * @atomic_clear_state: allocate a new atomic state
> + * @atomic_clear_state: clear the atomic state
>   *
>   * Some global (i.e. not per-CRTC, connector, etc) mode setting functions that
>   * involve drivers.
> @@ -998,6 +1000,8 @@ struct drm_mode_config_funcs {
>         int (*atomic_commit)(struct drm_device *dev,
>                              struct drm_atomic_state *a,
>                              bool async);
> +       struct drm_atomic_state *(*atomic_new_state)(struct drm_device *dev);
> +       void (*atomic_clear_state)(struct drm_atomic_state *state);
>  };
>
>  /**
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH 00/42] drm/i915: Convert to atomic, part 2.
  2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
                   ` (41 preceding siblings ...)
  2015-05-11 14:25 ` [PATCH 42/42] drm/i915: return early in __intel_set_mode_setup_plls without modeset Maarten Lankhorst
@ 2015-05-13  7:04 ` Daniel Vetter
  42 siblings, 0 replies; 98+ messages in thread
From: Daniel Vetter @ 2015-05-13  7:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Ander Conselvan de Oliveira, intel-gfx

On Mon, May 11, 2015 at 4:24 PM, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
> This patch makes this happen by consolidating all modeset paths
> and getting rid of most transitional state.
>
> This happens first by unifying all paths so all code that
> disables a crtc goes through either intel_crtc_toggle or
> __intel_set_mode. After that's done crtc_state->active is
> updated in intel_crtc_toggle, and used to check whether
> the crtc is active or not.
>
> At this point crtc->state is equal to intel_crtc->config and
> crtc->state->active is equal to crtc->config.
>
> This gives us enough information to convert all planes to atomic,
> this had to be done in a single commit because the transitional
> helpers don't call crtc_check and some things have to be moved
> there.
>
> This makes the planes fully atomic, next step is getting rid
> of the transitional intel_crtc->active and intel_crtc->config,
> and replacing it with crtc->state or old_crtc_state.
>
> The last part allows setting multiple crtc's in intel_set_mode,
> and restore the sw state after suspend by calculating the hw
> state in a drm_atomic_state, then swapping it with sw state
> and finally call intel_set_mode with the sw state.

Ok done an inital pass over the entire series. I think there's quite a
bit of polish and detail work to be done still, but overall the patch
series makes senes. For merging I think we should concentrate to get
the first few patches into shape first to get them in sooner (and
avoid too much rebasing). But doesn't have to be, whatever you prefer
wrt branch handling.

A few high-level comments:
- I prefer less terse commit messages. A few months down the road when
git blame or git bisect turns up such a commit it's good to understand
it again without digging out all the others. Which means repetition
(especially in all the patches to remove intel_crtc->config) is
totally ok and often needed. I've also made comments when I think that
some tricky issue should be specifically highlighted.

- Wrt the intel_crtc->config removal I think we should strive to make
it as least invasive as possible. Helps a lot with possible reverts,
conflicts and also makes reviewing a lot easier. I've made comments
where I think changes are unecessary or imo even confusing.

- It's scary and there's lots of little special-cases. Most of my
comments (especially about patch splitting) are to make these special
cases stick out more and so hopefully are easier to review. And also
easier to understand when the inevitable regression points at a patch
in here.

Cheers, Daniel

> Ander Conselvan de Oliveira (6):
>   drm/i915: Set mode_changed for audio in intel_modeset_pipe_config()
>   drm/i915: Make __intel_set_mode() take only atomic state as argument
>   drm/i915: Use global atomic state for staged pll config
>   drm/i915: Support modeset across multiple pipes
>   drm/i915: Move cdclk and pll setup to intel_modeset_compute_config()
>   drm/i915: Read hw state into an atomic state struct
>
> Maarten Lankhorst (36):
>   drm/atomic: Allow drivers to subclass drm_atomic_state
>   drm/i915: get rid of intel_crtc_disable and related code, v2
>   drm/i915: Only update required power domains.
>   drm/i915: use intel_crtc_control everywhere
>   drm/i915: Get rid of new_encoder.
>   drm/i915: get rid of new_crtc
>   drm/i915: Get rid of crtc->new_enabled, v2.
>   drm/i915: Implement intel_crtc_toggle using atomic state
>   drm/i915: Make intel_modeset_fixup_state similar to the atomic helper.
>   drm/i915: make plane helpers fully atomic
>   drm/i915: Update less state during modeset.
>   drm/i915: move swap_state to the right place
>   drm/i915: Use hwmode for vblanks.
>   drm/i915: Remove usage of crtc->config from i915_debugfs.c
>   drm/i915: Remove use of crtc->config from intel_pm.c
>   drm/i915: Remove use of crtc->config from intel_audio.c
>   drm/i915: remove use of crtc->config from intel_fbc.c
>   drm/i915: remove use of crtc->config from intel_atomic.c and
>     intel_sprite.c
>   drm/i915: Remove use of crtc->config from intel_overlay.c
>   drm/i915: Pass old state to crtc_disable and use it.
>   drm/i915: Pass old state to encoder->(post_)disable.
>   drm/i915: Remove use of crtc->config from intel_fbdev.c
>   drm/i915: Remove use of crtc->config from intel_psr.c
>   drm/i915: Remove use of crtc->config from intel_ddi.c
>   drm/i915: Remove use of crtc->config from intel_dp.c
>   drm/i915: Remove use of crtc->config from intel_dp_mst.c
>   drm/i915: Remove use of crtc->config from intel_dsi.c
>   drm/i915: Remove use of crtc->config in intel_hdmi.c
>   drm/i915: Remove use of crtc->config in intel_sdvo.c
>   drm/i915: Calculate haswell plane workaround.
>   drm/i915: remove crtc->active tracking completely
>   drm/i915: get rid of crtc->config in intel_display.c, part 1
>   drm/i915: get rid of crtc->config in intel_display.c, part 2
>   drm/i915: get rid of crtc->config
>   drm/i915: swap state correctly in intel_atomic_commit
>   drm/i915: return early in __intel_set_mode_setup_plls without modeset
>
>  drivers/gpu/drm/drm_atomic.c              |   91 +-
>  drivers/gpu/drm/i915/i915_debugfs.c       |   50 +-
>  drivers/gpu/drm/i915/i915_drv.h           |    5 +-
>  drivers/gpu/drm/i915/i915_irq.c           |   13 +-
>  drivers/gpu/drm/i915/intel_atomic.c       |   93 +-
>  drivers/gpu/drm/i915/intel_atomic_plane.c |   59 +-
>  drivers/gpu/drm/i915/intel_audio.c        |    2 +-
>  drivers/gpu/drm/i915/intel_crt.c          |   21 +-
>  drivers/gpu/drm/i915/intel_ddi.c          |   93 +-
>  drivers/gpu/drm/i915/intel_display.c      | 2639 +++++++++++++++--------------
>  drivers/gpu/drm/i915/intel_dp.c           |   86 +-
>  drivers/gpu/drm/i915/intel_dp_mst.c       |   16 +-
>  drivers/gpu/drm/i915/intel_drv.h          |   72 +-
>  drivers/gpu/drm/i915/intel_dsi.c          |   25 +-
>  drivers/gpu/drm/i915/intel_dvo.c          |   15 +-
>  drivers/gpu/drm/i915/intel_fbc.c          |    8 +-
>  drivers/gpu/drm/i915/intel_fbdev.c        |   19 +-
>  drivers/gpu/drm/i915/intel_hdmi.c         |   78 +-
>  drivers/gpu/drm/i915/intel_lvds.c         |   13 +-
>  drivers/gpu/drm/i915/intel_overlay.c      |    8 +-
>  drivers/gpu/drm/i915/intel_panel.c        |    3 +-
>  drivers/gpu/drm/i915/intel_pm.c           |   96 +-
>  drivers/gpu/drm/i915/intel_psr.c          |   25 +-
>  drivers/gpu/drm/i915/intel_sdvo.c         |   22 +-
>  drivers/gpu/drm/i915/intel_sprite.c       |   84 +-
>  drivers/gpu/drm/i915/intel_tv.c           |    5 +-
>  include/drm/drm_atomic.h                  |    4 +
>  include/drm/drm_crtc.h                    |    4 +
>  28 files changed, 1908 insertions(+), 1741 deletions(-)
>
> --
> 2.1.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2015-05-13  7:04 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-11 14:24 [PATCH 00/42] drm/i915: Convert to atomic, part 2 Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 01/42] drm/atomic: Allow drivers to subclass drm_atomic_state Maarten Lankhorst
2015-05-13  5:52   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 02/42] drm/i915: get rid of intel_crtc_disable and related code, v2 Maarten Lankhorst
2015-05-11 17:08   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 03/42] drm/i915: Only update required power domains Maarten Lankhorst
2015-05-11 17:00   ` Daniel Vetter
2015-05-12 12:05     ` Maarten Lankhorst
2015-05-12 13:13       ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 04/42] drm/i915: use intel_crtc_control everywhere Maarten Lankhorst
2015-05-11 17:11   ` Daniel Vetter
2015-05-12 12:06     ` Maarten Lankhorst
2015-05-12 13:16       ` Daniel Vetter
2015-05-12 14:38         ` Daniel Stone
2015-05-11 14:24 ` [PATCH 05/42] drm/i915: Get rid of new_encoder Maarten Lankhorst
2015-05-11 17:17   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 06/42] drm/i915: get rid of new_crtc Maarten Lankhorst
2015-05-11 17:28   ` Daniel Vetter
2015-05-12 12:07     ` Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 07/42] drm/i915: Get rid of crtc->new_enabled, v2 Maarten Lankhorst
2015-05-11 17:33   ` Daniel Vetter
2015-05-11 17:44     ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 08/42] drm/i915: Implement intel_crtc_toggle using atomic state Maarten Lankhorst
2015-05-11 18:12   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 09/42] drm/i915: Make intel_modeset_fixup_state similar to the atomic helper Maarten Lankhorst
2015-05-12  6:59   ` Daniel Vetter
2015-05-12 12:41     ` Maarten Lankhorst
2015-05-12 13:18       ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 10/42] drm/i915: make plane helpers fully atomic Maarten Lankhorst
2015-05-12  8:18   ` Daniel Vetter
2015-05-12 13:33     ` Maarten Lankhorst
2015-05-12 13:43       ` Ville Syrjälä
2015-05-12 13:46         ` Ville Syrjälä
2015-05-12 15:31         ` Daniel Vetter
2015-05-12 16:00       ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 11/42] drm/i915: Update less state during modeset Maarten Lankhorst
2015-05-12  8:22   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 12/42] drm/i915: move swap_state to the right place Maarten Lankhorst
2015-05-12  8:25   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 13/42] drm/i915: Set mode_changed for audio in intel_modeset_pipe_config() Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 14/42] drm/i915: Make __intel_set_mode() take only atomic state as argument Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 15/42] drm/i915: Use hwmode for vblanks Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 16/42] drm/i915: Remove usage of crtc->config from i915_debugfs.c Maarten Lankhorst
2015-05-12  8:51   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 17/42] drm/i915: Remove use of crtc->config from intel_pm.c Maarten Lankhorst
2015-05-12  8:54   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 18/42] drm/i915: Remove use of crtc->config from intel_audio.c Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 19/42] drm/i915: remove use of crtc->config from intel_fbc.c Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 20/42] drm/i915: remove use of crtc->config from intel_atomic.c and intel_sprite.c Maarten Lankhorst
2015-05-12  9:03   ` Daniel Vetter
2015-05-12 13:36     ` Maarten Lankhorst
2015-05-11 14:24 ` [PATCH 21/42] drm/i915: Remove use of crtc->config from intel_overlay.c Maarten Lankhorst
2015-05-12  9:06   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 22/42] drm/i915: Pass old state to crtc_disable and use it Maarten Lankhorst
2015-05-12  9:13   ` Daniel Vetter
2015-05-11 14:24 ` [PATCH 23/42] drm/i915: Pass old state to encoder->(post_)disable Maarten Lankhorst
2015-05-12  9:16   ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 24/42] drm/i915: Remove use of crtc->config from intel_fbdev.c Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 25/42] drm/i915: Remove use of crtc->config from intel_psr.c Maarten Lankhorst
2015-05-12  9:20   ` Daniel Vetter
2015-05-12 13:41     ` Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 26/42] drm/i915: Remove use of crtc->config from intel_ddi.c Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 27/42] drm/i915: Remove use of crtc->config from intel_dp.c Maarten Lankhorst
2015-05-12  9:22   ` Daniel Vetter
2015-05-12 13:43     ` Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 28/42] drm/i915: Remove use of crtc->config from intel_dp_mst.c Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 29/42] drm/i915: Remove use of crtc->config from intel_dsi.c Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 30/42] drm/i915: Remove use of crtc->config in intel_hdmi.c Maarten Lankhorst
2015-05-12  9:26   ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 31/42] drm/i915: Remove use of crtc->config in intel_sdvo.c Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 32/42] drm/i915: Calculate haswell plane workaround Maarten Lankhorst
2015-05-12  9:43   ` Daniel Vetter
2015-05-12 14:05     ` Maarten Lankhorst
2015-05-12 16:54       ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 33/42] drm/i915: remove crtc->active tracking completely Maarten Lankhorst
2015-05-12  9:55   ` Daniel Vetter
2015-05-12 10:03   ` Daniel Vetter
2015-05-12 14:07     ` Maarten Lankhorst
2015-05-12 16:57       ` Daniel Vetter
2015-05-12 17:01         ` Daniel Stone
2015-05-12 17:08           ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 34/42] drm/i915: get rid of crtc->config in intel_display.c, part 1 Maarten Lankhorst
2015-05-12 10:11   ` Daniel Vetter
2015-05-12 14:13     ` Maarten Lankhorst
2015-05-12 17:01       ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 35/42] drm/i915: get rid of crtc->config in intel_display.c, part 2 Maarten Lankhorst
2015-05-12 10:17   ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 36/42] drm/i915: get rid of crtc->config Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 37/42] drm/i915: swap state correctly in intel_atomic_commit Maarten Lankhorst
2015-05-12 13:03   ` Daniel Vetter
2015-05-12 14:16     ` Maarten Lankhorst
2015-05-12 17:03       ` Daniel Vetter
2015-05-11 14:25 ` [PATCH 38/42] drm/i915: Use global atomic state for staged pll config Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 39/42] drm/i915: Support modeset across multiple pipes Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 40/42] drm/i915: Move cdclk and pll setup to intel_modeset_compute_config() Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 41/42] drm/i915: Read hw state into an atomic state struct Maarten Lankhorst
2015-05-11 14:25 ` [PATCH 42/42] drm/i915: return early in __intel_set_mode_setup_plls without modeset Maarten Lankhorst
2015-05-13  7:04 ` [PATCH 00/42] drm/i915: Convert to atomic, part 2 Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.