All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/19] Remove depencies on staged config for atomic transition
@ 2015-03-13  9:48 Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 01/19] drm/i915: Add intel_atomic_get_crtc_state() helper function Ander Conselvan de Oliveira
                   ` (19 more replies)
  0 siblings, 20 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Here's v2 with most of the comments from Daniel addressed. I didn't change
the zeroing of the crtc_state to the duplicate state function, since it
causes problems when we add the state of a crtc that isn't going through
a modeset. Specifically, this would cause the code that decides whether
pipes B and C can be enabled at the same time to fail, since the number
of fdi lanes would be zero.

The other concerns I raised with v1 are also addressed. I tested this on
IVYBRIDGE using pipes B & C, and the load detect code path using Daniel's
patch that adds the i915.load_detect_test parameter.

Thanks,
Ander

Ander Conselvan de Oliveira (19):
  drm/i915: Add intel_atomic_get_crtc_state() helper function
  drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe()
  drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  drm/i915: Allocate a crtc_state also when the crtc is being disabled
  drm/i915: Update dummy connector atomic state with current config
  drm/i915: Implement connector state duplication
  drm/i915: Copy the staged connector config to the legacy atomic state
  drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config()
  drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp()
  drm/i915: Don't depend on encoder->new_crtc in
    intel_dp_compute_config()
  drm/i915: Don't depend on encoder->new_crtc in
    intel_hdmi_compute_config
  drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder()
  drm/i915: Don't use staged config in intel_dp_mst_compute_config()
  drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config()
  drm/i915: Pass an atomic state to modeset_global_resources() functions
  drm/i915: Check lane sharing between pipes B & C using atomic state
  drm/i915: Convert intel_pipe_will_have_type() to using atomic state
  drm/i915: Don't look at staged config crtc when changing DRRS state
  drm/i915: Remove usage of encoder->new_crtc from clock computations

 drivers/gpu/drm/i915/i915_drv.h      |   4 +-
 drivers/gpu/drm/i915/intel_crt.c     |   3 +-
 drivers/gpu/drm/i915/intel_ddi.c     |  24 +-
 drivers/gpu/drm/i915/intel_display.c | 544 ++++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_dp.c      |   5 +-
 drivers/gpu/drm/i915/intel_dp_mst.c  |  18 +-
 drivers/gpu/drm/i915/intel_drv.h     |  16 +-
 drivers/gpu/drm/i915/intel_dsi.c     |   1 +
 drivers/gpu/drm/i915/intel_dvo.c     |   1 +
 drivers/gpu/drm/i915/intel_hdmi.c    |  22 +-
 drivers/gpu/drm/i915/intel_lvds.c    |   3 +-
 drivers/gpu/drm/i915/intel_sdvo.c    |   1 +
 drivers/gpu/drm/i915/intel_tv.c      |   3 +-
 13 files changed, 484 insertions(+), 161 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] 52+ messages in thread

* [PATCH 01/19] drm/i915: Add intel_atomic_get_crtc_state() helper function
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 02/19] drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe() Ander Conselvan de Oliveira
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

The pattern of getting the crtc state with drm_atomic_get_crtc_state()
and then converting it to intel_crtc_state will repeat quite often in
the following patches, so add a helper function to save some typing.

v2: Fix upcasting so that crtc_state base field could be moved. (Daniel)
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c77128c..5bae4aa 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -35,6 +35,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_dp_mst_helper.h>
 #include <drm/drm_rect.h>
+#include <drm/drm_atomic.h>
 
 #define DIV_ROUND_CLOSEST_ULL(ll, d)	\
 ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; })
@@ -564,6 +565,7 @@ struct cxsr_latency {
 };
 
 #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)
 #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
@@ -1282,6 +1284,17 @@ 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);
+static inline struct intel_crtc_state *
+intel_atomic_get_crtc_state(struct drm_atomic_state *state,
+			    struct intel_crtc *crtc)
+{
+	struct drm_crtc_state *crtc_state;
+	crtc_state = drm_atomic_get_crtc_state(state, &crtc->base);
+	if (IS_ERR(crtc_state))
+		return ERR_PTR(PTR_ERR(crtc_state));
+
+	return to_intel_crtc_state(crtc_state);
+}
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-- 
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] 52+ messages in thread

* [PATCH 02/19] drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 01/19] drm/i915: Add intel_atomic_get_crtc_state() helper function Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code Ander Conselvan de Oliveira
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

For now this is not necessary since intel_set_mode() doesn't acquire any
new locks. However, once that function is converted to atomic, that will
change, since we'll pass an atomic state to it, and that needs to have
the right acquire context set.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_crt.c     | 2 +-
 drivers/gpu/drm/i915/intel_display.c | 5 +++--
 drivers/gpu/drm/i915/intel_drv.h     | 3 ++-
 drivers/gpu/drm/i915/intel_tv.c      | 2 +-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index e66e17a..974534e 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -708,7 +708,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
 			status = connector_status_connected;
 		else
 			status = intel_crt_load_detect(crt);
-		intel_release_load_detect_pipe(connector, &tmp);
+		intel_release_load_detect_pipe(connector, &tmp, &ctx);
 	} else
 		status = connector_status_unknown;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2d3c9d8..78ea122 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8933,7 +8933,8 @@ fail_unlock:
 }
 
 void intel_release_load_detect_pipe(struct drm_connector *connector,
-				    struct intel_load_detect_pipe *old)
+				    struct intel_load_detect_pipe *old,
+				    struct drm_modeset_acquire_ctx *ctx)
 {
 	struct intel_encoder *intel_encoder =
 		intel_attached_encoder(connector);
@@ -13479,7 +13480,7 @@ static void intel_enable_pipe_a(struct drm_device *dev)
 		return;
 
 	if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx))
-		intel_release_load_detect_pipe(crt, &load_detect_temp);
+		intel_release_load_detect_pipe(crt, &load_detect_temp, ctx);
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5bae4aa..ec99046 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -958,7 +958,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 				struct intel_load_detect_pipe *old,
 				struct drm_modeset_acquire_ctx *ctx);
 void intel_release_load_detect_pipe(struct drm_connector *connector,
-				    struct intel_load_detect_pipe *old);
+				    struct intel_load_detect_pipe *old,
+				    struct drm_modeset_acquire_ctx *ctx);
 int intel_pin_and_fence_fb_obj(struct drm_plane *plane,
 			       struct drm_framebuffer *fb,
 			       struct intel_engine_cs *pipelined);
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 892d23c..4e6684e 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1332,7 +1332,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
 
 		if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
 			type = intel_tv_detect_type(intel_tv, connector);
-			intel_release_load_detect_pipe(connector, &tmp);
+			intel_release_load_detect_pipe(connector, &tmp, &ctx);
 			status = type < 0 ?
 				connector_status_disconnected :
 				connector_status_connected;
-- 
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] 52+ messages in thread

* [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 01/19] drm/i915: Add intel_atomic_get_crtc_state() helper function Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 02/19] drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-17  6:46   ` [PATCH v3] " Ander Conselvan de Oliveira
  2015-03-19 21:08   ` [PATCH 03/19] " Konduru, Chandra
  2015-03-13  9:48 ` [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled Ander Conselvan de Oliveira
                   ` (16 subsequent siblings)
  19 siblings, 2 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

For the atomic conversion, the mode set paths need to be changed to rely
on an atomic state instead of using the staged config. By using an
atomic state for the legacy code, we will be able to convert the code
base in small chunks.

v2: Squash patch that adds state argument to intel_set_mode(). (Ander)
    Make every caller of intel_set_mode() allocate state. (Daniel)
    Call drm_atomic_state_clear() in set config's error path. (Daniel)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 168 +++++++++++++++++++++++++++--------
 1 file changed, 133 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 78ea122..b61e3f6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -37,6 +37,7 @@
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_crtc_helper.h>
@@ -82,7 +83,8 @@ 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_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *old_fb);
+			  int x, int y, struct drm_framebuffer *old_fb,
+			  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,
@@ -8802,6 +8804,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 	struct drm_device *dev = encoder->dev;
 	struct drm_framebuffer *fb;
 	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state = NULL;
 	int ret, i = -1;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
@@ -8883,6 +8886,12 @@ retry:
 	old->load_detect_temp = true;
 	old->release_fb = NULL;
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return false;
+
+	state->acquire_ctx = ctx;
+
 	if (!mode)
 		mode = &load_detect_mode;
 
@@ -8905,7 +8914,7 @@ retry:
 		goto fail;
 	}
 
-	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
+	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
@@ -8924,6 +8933,11 @@ retry:
 	else
 		intel_crtc->new_config = NULL;
 fail_unlock:
+	if (state) {
+		drm_atomic_state_free(state);
+		state = NULL;
+	}
+
 	if (ret == -EDEADLK) {
 		drm_modeset_backoff(ctx);
 		goto retry;
@@ -8936,22 +8950,34 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 				    struct intel_load_detect_pipe *old,
 				    struct drm_modeset_acquire_ctx *ctx)
 {
+	struct drm_device *dev = connector->dev;
 	struct intel_encoder *intel_encoder =
 		intel_attached_encoder(connector);
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_atomic_state *state;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
 		      connector->base.id, connector->name,
 		      encoder->base.id, encoder->name);
 
 	if (old->load_detect_temp) {
+		state = drm_atomic_state_alloc(dev);
+		if (!state) {
+			DRM_DEBUG_KMS("can't release load detect pipe\n");
+			return;
+		}
+
+		state->acquire_ctx = ctx;
+
 		to_intel_connector(connector)->new_encoder = NULL;
 		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 		intel_crtc->new_config = NULL;
-		intel_set_mode(crtc, NULL, 0, 0, NULL);
+		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
+
+		drm_atomic_state_free(state);
 
 		if (old->release_fb) {
 			drm_framebuffer_unregister_private(old->release_fb);
@@ -10345,10 +10371,22 @@ static bool check_digital_port_conflicts(struct drm_device *dev)
 	return true;
 }
 
-static struct intel_crtc_state *
+static void
+clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
+{
+	struct drm_crtc_state tmp_state;
+
+	/* Clear only the intel specific part of the crtc state */
+	tmp_state = crtc_state->base;
+	memset(crtc_state, 0, sizeof *crtc_state);
+	crtc_state->base = tmp_state;
+}
+
+static int
 intel_modeset_pipe_config(struct drm_crtc *crtc,
 			  struct drm_framebuffer *fb,
-			  struct drm_display_mode *mode)
+			  struct drm_display_mode *mode,
+			  struct drm_atomic_state *state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct intel_encoder *encoder;
@@ -10358,17 +10396,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 
 	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
 		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	if (!check_digital_port_conflicts(dev)) {
 		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
-	if (!pipe_config)
-		return ERR_PTR(-ENOMEM);
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return PTR_ERR(pipe_config);
+
+	clear_intel_crtc_state(pipe_config);
 
 	pipe_config->base.crtc = crtc;
 	drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
@@ -10463,10 +10503,9 @@ encoder_retry:
 	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
 		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
-	return pipe_config;
+	return 0;
 fail:
-	kfree(pipe_config);
-	return ERR_PTR(ret);
+	return ret;
 }
 
 /* Computes which crtcs are affected and sets the relevant bits in the mask. For
@@ -11144,17 +11183,19 @@ static struct intel_crtc_state *
 intel_modeset_compute_config(struct drm_crtc *crtc,
 			     struct drm_display_mode *mode,
 			     struct drm_framebuffer *fb,
+			     struct drm_atomic_state *state,
 			     unsigned *modeset_pipes,
 			     unsigned *prepare_pipes,
 			     unsigned *disable_pipes)
 {
 	struct intel_crtc_state *pipe_config = NULL;
+	int ret = 0;
 
 	intel_modeset_affected_pipes(crtc, modeset_pipes,
 				     prepare_pipes, disable_pipes);
 
 	if ((*modeset_pipes) == 0)
-		goto out;
+		return NULL;
 
 	/*
 	 * Note this needs changes when we start tracking multiple modes
@@ -11162,14 +11203,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	 * (i.e. one pipe_config for each crtc) rather than just the one
 	 * for this crtc.
 	 */
-	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
-	if (IS_ERR(pipe_config)) {
-		goto out;
-	}
+	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
+	if (ret)
+		return ERR_PTR(ret);
+
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return pipe_config;
+
 	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
 			       "[modeset]");
 
-out:
 	return pipe_config;
 }
 
@@ -11214,6 +11258,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *saved_mode;
+	struct intel_crtc_state *crtc_state_copy = NULL;
 	struct intel_crtc *intel_crtc;
 	int ret = 0;
 
@@ -11221,6 +11266,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	if (!saved_mode)
 		return -ENOMEM;
 
+	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
+	if (!crtc_state_copy) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
 	*saved_mode = crtc->mode;
 
 	if (modeset_pipes)
@@ -11307,6 +11358,19 @@ done:
 	if (ret && crtc->state->enable)
 		crtc->mode = *saved_mode;
 
+	if (ret == 0 && pipe_config) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		/* The pipe_config will be freed with the atomic state, so
+		 * make a copy. */
+		memcpy(crtc_state_copy, intel_crtc->config,
+		       sizeof *crtc_state_copy);
+		intel_crtc->config = intel_crtc->new_config = crtc_state_copy;
+		intel_crtc->base.state = &crtc_state_copy->base;
+	} else {
+		kfree(crtc_state_copy);
+	}
+
 	kfree(saved_mode);
 	return ret;
 }
@@ -11332,27 +11396,51 @@ static int intel_set_mode_pipes(struct drm_crtc *crtc,
 
 static int intel_set_mode(struct drm_crtc *crtc,
 			  struct drm_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *fb)
+			  int x, int y, struct drm_framebuffer *fb,
+			  struct drm_atomic_state *state)
 {
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
+	int ret = 0;
 
-	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
+	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
 
-	if (IS_ERR(pipe_config))
-		return PTR_ERR(pipe_config);
+	if (IS_ERR(pipe_config)) {
+		ret = PTR_ERR(pipe_config);
+		goto out;
+	}
+
+	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
+				   modeset_pipes, prepare_pipes,
+				   disable_pipes);
+	if (ret)
+		goto out;
 
-	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
-				    modeset_pipes, prepare_pipes,
-				    disable_pipes);
+out:
+	return ret;
 }
 
 void intel_crtc_restore_mode(struct drm_crtc *crtc)
 {
-	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
+	struct drm_device *dev = crtc->dev;
+	struct drm_atomic_state *state;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
+			      crtc->base.id);
+		return;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
+	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
+		       state);
+
+	drm_atomic_state_free(state);
 }
 
 #undef for_each_intel_crtc_masked
@@ -11677,6 +11765,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
 	struct drm_mode_set save_set;
+	struct drm_atomic_state *state = NULL;
 	struct intel_set_config *config;
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
@@ -11721,12 +11810,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 	 * such cases. */
 	intel_set_config_compute_mode_changes(set, config);
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto out_config;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
 	ret = intel_modeset_stage_output_state(dev, set, config);
 	if (ret)
 		goto fail;
 
 	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
-						   set->fb,
+						   set->fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
@@ -11746,10 +11843,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 		 */
 	}
 
-	/* set_mode will free it in the mode_changed case */
-	if (!config->mode_changed)
-		kfree(pipe_config);
-
 	intel_update_pipe_size(to_intel_crtc(set->crtc));
 
 	if (config->mode_changed) {
@@ -11795,6 +11888,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 fail:
 		intel_set_config_restore_state(dev, config);
 
+		drm_atomic_state_clear(state);
+
 		/*
 		 * HACK: if the pipe was on, but we didn't have a framebuffer,
 		 * force the pipe off to avoid oopsing in the modeset code
@@ -11807,11 +11902,15 @@ fail:
 		/* Try to restore the config */
 		if (config->mode_changed &&
 		    intel_set_mode(save_set.crtc, save_set.mode,
-				   save_set.x, save_set.y, save_set.fb))
+				   save_set.x, save_set.y, save_set.fb,
+				   state))
 			DRM_ERROR("failed to restore config after modeset failure\n");
 	}
 
 out_config:
+	if (state)
+		drm_atomic_state_free(state);
+
 	intel_set_config_free(config);
 	return ret;
 }
@@ -13852,8 +13951,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 			struct drm_crtc *crtc =
 				dev_priv->pipe_to_crtc_mapping[pipe];
 
-			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
-				       crtc->primary->fb);
+			intel_crtc_restore_mode(crtc);
 		}
 	} else {
 		intel_modeset_update_staged_output_state(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] 52+ messages in thread

* [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (2 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
       [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B41B@fmsmsx101.amr.corp.intel.com>
  2015-03-13  9:48 ` [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config Ander Conselvan de Oliveira
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

For consistency, allocate a new crtc_state for a crtc that is being
disabled. Previously only the enabled value of the current state would
change.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b61e3f6..62b9021 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11188,14 +11188,21 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 			     unsigned *prepare_pipes,
 			     unsigned *disable_pipes)
 {
+	struct drm_device *dev = crtc->dev;
 	struct intel_crtc_state *pipe_config = NULL;
+	struct intel_crtc *intel_crtc;
 	int ret = 0;
 
 	intel_modeset_affected_pipes(crtc, modeset_pipes,
 				     prepare_pipes, disable_pipes);
 
-	if ((*modeset_pipes) == 0)
-		return NULL;
+	for_each_intel_crtc_masked(dev, *disable_pipes, intel_crtc) {
+		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
+		if (IS_ERR(pipe_config))
+			return pipe_config;
+
+		pipe_config->base.enable = false;
+	}
 
 	/*
 	 * Note this needs changes when we start tracking multiple modes
@@ -11203,18 +11210,25 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	 * (i.e. one pipe_config for each crtc) rather than just the one
 	 * for this crtc.
 	 */
-	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
-	if (ret)
-		return ERR_PTR(ret);
+	for_each_intel_crtc_masked(dev, *modeset_pipes, intel_crtc) {
+		/* FIXME: For now we still expect modeset_pipes has at most
+		 * one bit set. */
+		if (WARN_ON(&intel_crtc->base != crtc))
+			continue;
 
-	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
-	if (IS_ERR(pipe_config))
-		return pipe_config;
+		ret = intel_modeset_pipe_config(crtc, fb, mode, state);
+		if (ret)
+			return ERR_PTR(ret);
+
+		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
+		if (IS_ERR(pipe_config))
+			return pipe_config;
 
-	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
-			       "[modeset]");
+		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
+				       "[modeset]");
+	}
 
-	return pipe_config;
+	return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
 }
 
 static int __intel_set_mode_setup_plls(struct drm_device *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] 52+ messages in thread

* [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (3 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-19 20:55   ` Konduru, Chandra
  2015-03-13  9:48 ` [PATCH 06/19] drm/i915: Implement connector state duplication Ander Conselvan de Oliveira
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Keep that state updated so that we can write code that depends on it on
the follow up patches.

v2: Fix BUG() due to stale connector_state->crtc value. (Chandra)
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 41 ++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 62b9021..abdbd0c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10114,6 +10114,27 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev)
 	}
 }
 
+/* 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.
+ */
+static void intel_modeset_update_connector_atomic_state(struct drm_device *dev)
+{
+	struct intel_connector *connector;
+
+	for_each_intel_connector(dev, connector) {
+		if (connector->base.encoder) {
+			connector->base.state->best_encoder =
+				connector->base.encoder;
+			connector->base.state->crtc =
+				connector->base.encoder->crtc;
+		} else {
+			connector->base.state->best_encoder = NULL;
+			connector->base.state->crtc = NULL;
+		}
+	}
+}
+
 /**
  * intel_modeset_commit_output_state
  *
@@ -10137,6 +10158,8 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
 		crtc->base.state->enable = crtc->new_enabled;
 		crtc->base.enabled = crtc->new_enabled;
 	}
+
+	intel_modeset_update_connector_atomic_state(dev);
 }
 
 static void
@@ -12876,15 +12899,13 @@ static void intel_setup_outputs(struct drm_device *dev)
 	 * be removed since we'll be setting up real connector state, which
 	 * will contain Intel-specific properties.
 	 */
-	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
-		list_for_each_entry(connector,
-				    &dev->mode_config.connector_list,
-				    head) {
-			if (!WARN_ON(connector->state)) {
-				connector->state =
-					kzalloc(sizeof(*connector->state),
-						GFP_KERNEL);
-			}
+	/* FIXME: need to update the comment above. */
+	list_for_each_entry(connector,
+			    &dev->mode_config.connector_list,
+			    head) {
+		if (!WARN_ON(connector->state)) {
+			connector->state = kzalloc(sizeof(*connector->state),
+						   GFP_KERNEL);
 		}
 	}
 
@@ -13937,6 +13958,8 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 				       "[setup_hw_state]");
 	}
 
+	intel_modeset_update_connector_atomic_state(dev);
+
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
-- 
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] 52+ messages in thread

* [PATCH 06/19] drm/i915: Implement connector state duplication
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (4 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state Ander Conselvan de Oliveira
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

So that we can add connector states to the drm_atomic_state used in the
legacy modeset.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_crt.c    | 1 +
 drivers/gpu/drm/i915/intel_dp.c     | 1 +
 drivers/gpu/drm/i915/intel_dp_mst.c | 1 +
 drivers/gpu/drm/i915/intel_dsi.c    | 1 +
 drivers/gpu/drm/i915/intel_dvo.c    | 1 +
 drivers/gpu/drm/i915/intel_hdmi.c   | 1 +
 drivers/gpu/drm/i915/intel_lvds.c   | 1 +
 drivers/gpu/drm/i915/intel_sdvo.c   | 1 +
 drivers/gpu/drm/i915/intel_tv.c     | 1 +
 9 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 974534e..573aaff 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -794,6 +794,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
 	.destroy = intel_crt_destroy,
 	.set_property = intel_crt_set_property,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_get_property = intel_connector_atomic_get_property,
 };
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 33d5877..92bfbe6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4545,6 +4545,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.destroy = intel_dp_connector_destroy,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index be12492..5c06a06 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -317,6 +317,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.destroy = intel_dp_mst_connector_destroy,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static int intel_dp_mst_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index c8c8b24..572251e 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -975,6 +975,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 void intel_dsi_init(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index d857951..4ccd6c3 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -393,6 +393,7 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 995c5b2..b13a8be 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1618,6 +1618,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.destroy = intel_hdmi_destroy,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 24e8730..2b008b02 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -535,6 +535,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.destroy = intel_lvds_destroy,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 9e554c2..f5b7e1e 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2194,6 +2194,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.destroy = intel_sdvo_destroy,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 4e6684e..bc1d9d7 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1516,6 +1516,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = {
 	.atomic_get_property = intel_connector_atomic_get_property,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 };
 
 static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
-- 
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] 52+ messages in thread

* [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (5 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 06/19] drm/i915: Implement connector state duplication Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
       [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B6F0@fmsmsx101.amr.corp.intel.com>
  2015-03-13  9:48 ` [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config() Ander Conselvan de Oliveira
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

With this in place, we can start converting pieces of the modeset code
to look at the connector atomic state instead of the staged config.

v2: Handle the load detect staged config changes too. (Ander)
    Remove unnecessary blank line. (Daniel)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 52 +++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index abdbd0c..6465f6d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8805,6 +8805,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 	struct drm_framebuffer *fb;
 	struct drm_mode_config *config = &dev->mode_config;
 	struct drm_atomic_state *state = NULL;
+	struct drm_connector_state *connector_state;
 	int ret, i = -1;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
@@ -8892,6 +8893,15 @@ retry:
 
 	state->acquire_ctx = ctx;
 
+	connector_state = drm_atomic_get_connector_state(state, connector);
+	if (IS_ERR(connector_state)) {
+		ret = PTR_ERR(connector_state);
+		goto fail;
+	}
+
+	connector_state->crtc = crtc;
+	connector_state->best_encoder = &intel_encoder->base;
+
 	if (!mode)
 		mode = &load_detect_mode;
 
@@ -8957,6 +8967,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_atomic_state *state;
+	struct drm_connector_state *connector_state;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
 		      connector->base.id, connector->name,
@@ -8964,17 +8975,23 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 
 	if (old->load_detect_temp) {
 		state = drm_atomic_state_alloc(dev);
-		if (!state) {
-			DRM_DEBUG_KMS("can't release load detect pipe\n");
-			return;
-		}
+		if (!state)
+			goto fail;
 
 		state->acquire_ctx = ctx;
 
+		connector_state = drm_atomic_get_connector_state(state, connector);
+		if (IS_ERR(connector_state))
+			goto fail;
+
 		to_intel_connector(connector)->new_encoder = NULL;
 		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 		intel_crtc->new_config = NULL;
+
+		connector_state->best_encoder = NULL;
+		connector_state->crtc = NULL;
+
 		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
 
 		drm_atomic_state_free(state);
@@ -8990,6 +9007,11 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 	/* Switch crtc and encoder back off if necessary */
 	if (old->dpms_mode != DRM_MODE_DPMS_ON)
 		connector->funcs->dpms(connector, old->dpms_mode);
+
+	return;
+fail:
+	DRM_DEBUG_KMS("Couldn't release load detect pipe.\n");
+	drm_atomic_state_free(state);
 }
 
 static int i9xx_pll_refclk(struct drm_device *dev,
@@ -11646,9 +11668,11 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 static int
 intel_modeset_stage_output_state(struct drm_device *dev,
 				 struct drm_mode_set *set,
-				 struct intel_set_config *config)
+				 struct intel_set_config *config,
+				 struct drm_atomic_state *state)
 {
 	struct intel_connector *connector;
+	struct drm_connector_state *connector_state;
 	struct intel_encoder *encoder;
 	struct intel_crtc *crtc;
 	int ro;
@@ -11712,6 +11736,14 @@ intel_modeset_stage_output_state(struct drm_device *dev,
 		}
 		connector->new_encoder->new_crtc = to_intel_crtc(new_crtc);
 
+		connector_state =
+			drm_atomic_get_connector_state(state, &connector->base);
+		if (IS_ERR(connector_state))
+			return PTR_ERR(connector_state);
+
+		connector_state->crtc = new_crtc;
+		connector_state->best_encoder = &connector->new_encoder->base;
+
 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
 			connector->base.base.id,
 			connector->base.name,
@@ -11744,9 +11776,15 @@ intel_modeset_stage_output_state(struct drm_device *dev,
 	}
 	/* Now we've also updated encoder->new_crtc for all encoders. */
 	for_each_intel_connector(dev, connector) {
-		if (connector->new_encoder)
+		connector_state =
+			drm_atomic_get_connector_state(state, &connector->base);
+
+		if (connector->new_encoder) {
 			if (connector->new_encoder != connector->encoder)
 				connector->encoder = connector->new_encoder;
+		} else {
+			connector_state->crtc = NULL;
+		}
 	}
 	for_each_intel_crtc(dev, crtc) {
 		crtc->new_enabled = false;
@@ -11855,7 +11893,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 
 	state->acquire_ctx = dev->mode_config.acquire_ctx;
 
-	ret = intel_modeset_stage_output_state(dev, set, config);
+	ret = intel_modeset_stage_output_state(dev, set, config, state);
 	if (ret)
 		goto fail;
 
-- 
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] 52+ messages in thread

* [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (6 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-19  0:44   ` Konduru, Chandra
  2015-03-13  9:48 ` [PATCH 09/19] drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp() Ander Conselvan de Oliveira
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

v2: Move call to drm_atomic_add_affected_connectors() to
    intel_modeset_compute_config(). (Daniel)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6465f6d..1609628 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10435,8 +10435,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	struct drm_connector_state *connector_state;
 	struct intel_crtc_state *pipe_config;
 	int plane_bpp, ret = -EINVAL;
+	int i;
 	bool retry = true;
 
 	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
@@ -10510,11 +10513,17 @@ encoder_retry:
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
 	 */
-	for_each_intel_encoder(dev, encoder) {
+	for (i = 0; i < state->num_connector; i++) {
+		connector = to_intel_connector(state->connectors[i]);
+		if (!connector)
+			continue;
 
-		if (&encoder->new_crtc->base != crtc)
+		connector_state = state->connector_states[i];
+		if (connector_state->crtc != crtc)
 			continue;
 
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
 		if (!(encoder->compute_config(encoder, pipe_config))) {
 			DRM_DEBUG_KMS("Encoder config failure\n");
 			goto fail;
@@ -11238,6 +11247,10 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc;
 	int ret = 0;
 
+	ret = drm_atomic_add_affected_connectors(state, crtc);
+	if (ret)
+		return ERR_PTR(ret);
+
 	intel_modeset_affected_pipes(crtc, modeset_pipes,
 				     prepare_pipes, disable_pipes);
 
-- 
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] 52+ messages in thread

* [PATCH 09/19] drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (7 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 10/19] drm/i915: Don't depend on encoder->new_crtc in intel_dp_compute_config() Ander Conselvan de Oliveira
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1609628..f0ae907 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10216,8 +10216,9 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
 			  struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->base.dev;
+	struct drm_atomic_state *state;
 	struct intel_connector *connector;
-	int bpp;
+	int bpp, i;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
@@ -10257,10 +10258,13 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
 
 	pipe_config->pipe_bpp = bpp;
 
+	state = pipe_config->base.state;
+
 	/* Clamp display bpp to EDID value */
-	for_each_intel_connector(dev, connector) {
-		if (!connector->new_encoder ||
-		    connector->new_encoder->new_crtc != crtc)
+	for (i = 0; i < state->num_connector; i++) {
+		connector = to_intel_connector(state->connectors[i]);
+		if (!connector ||
+		    state->connector_states[i]->crtc != &crtc->base)
 			continue;
 
 		connected_sink_compute_bpp(connector, 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] 52+ messages in thread

* [PATCH 10/19] drm/i915: Don't depend on encoder->new_crtc in intel_dp_compute_config()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (8 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 09/19] drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 11/19] drm/i915: Don't depend on encoder->new_crtc in intel_hdmi_compute_config Ander Conselvan de Oliveira
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 92bfbe6..510927e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1265,7 +1265,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	enum port port = dp_to_dig_port(intel_dp)->port;
-	struct intel_crtc *intel_crtc = encoder->new_crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	int lane_count, clock;
 	int min_lane_count = 1;
-- 
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] 52+ messages in thread

* [PATCH 11/19] drm/i915: Don't depend on encoder->new_crtc in intel_hdmi_compute_config
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (9 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 10/19] drm/i915: Don't depend on encoder->new_crtc in intel_dp_compute_config() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 12/19] drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder() Ander Conselvan de Oliveira
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index b13a8be..cacbafd 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -951,19 +951,30 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static bool hdmi_12bpc_possible(struct intel_crtc *crtc)
+static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_atomic_state *state;
 	struct intel_encoder *encoder;
+	struct drm_connector_state *connector_state;
 	int count = 0, count_hdmi = 0;
+	int i;
 
 	if (HAS_GMCH_DISPLAY(dev))
 		return false;
 
-	for_each_intel_encoder(dev, encoder) {
-		if (encoder->new_crtc != crtc)
+	state = crtc_state->base.state;
+
+	for (i = 0; i < state->num_connector; i++) {
+		if (!state->connectors[i])
 			continue;
 
+		connector_state = state->connector_states[i];
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
 		count_hdmi += encoder->type == INTEL_OUTPUT_HDMI;
 		count++;
 	}
@@ -1020,7 +1031,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	 */
 	if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink &&
 	    clock_12bpc <= portclock_limit &&
-	    hdmi_12bpc_possible(encoder->new_crtc)) {
+	    hdmi_12bpc_possible(pipe_config)) {
 		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
 		desired_bpp = 12*3;
 
-- 
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] 52+ messages in thread

* [PATCH 12/19] drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (10 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 11/19] drm/i915: Don't depend on encoder->new_crtc in intel_hdmi_compute_config Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 13/19] drm/i915: Don't use staged config in intel_dp_mst_compute_config() Ander Conselvan de Oliveira
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Instead of using connector->new_encoder, get the same information from
the pipe_config, thus making the function ready for the atomic
conversion.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8aee7d7..47b9307 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -492,17 +492,23 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
 }
 
 static struct intel_encoder *
-intel_ddi_get_crtc_new_encoder(struct intel_crtc *crtc)
+intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = crtc->base.dev;
-	struct intel_encoder *intel_encoder, *ret = NULL;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_encoder *ret = NULL;
+	struct drm_atomic_state *state;
 	int num_encoders = 0;
+	int i;
 
-	for_each_intel_encoder(dev, intel_encoder) {
-		if (intel_encoder->new_crtc == crtc) {
-			ret = intel_encoder;
-			num_encoders++;
-		}
+	state = crtc_state->base.state;
+
+	for (i = 0; i < state->num_connector; i++) {
+		if (!state->connectors[i] ||
+		    state->connector_states[i]->crtc != crtc_state->base.crtc)
+			continue;
+
+		ret = to_intel_encoder(state->connector_states[i]->best_encoder);
+		num_encoders++;
 	}
 
 	WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
@@ -1216,7 +1222,7 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct intel_encoder *intel_encoder =
-		intel_ddi_get_crtc_new_encoder(intel_crtc);
+		intel_ddi_get_crtc_new_encoder(crtc_state);
 	int clock = crtc_state->port_clock;
 
 	if (IS_SKYLAKE(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] 52+ messages in thread

* [PATCH 13/19] drm/i915: Don't use staged config in intel_dp_mst_compute_config()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (11 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 12/19] drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 14/19] drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config() Ander Conselvan de Oliveira
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp_mst.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 5c06a06..b132fe6 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -36,11 +36,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_digital_port *intel_dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
-	struct drm_device *dev = encoder->base.dev;
-	int bpp;
+	struct drm_atomic_state *state;
+	int bpp, i;
 	int lane_count, slots;
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-	struct intel_connector *found = NULL, *intel_connector;
+	struct intel_connector *found = NULL;
 	int mst_pbn;
 
 	pipe_config->dp_encoder_is_mst = true;
@@ -58,9 +58,14 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	pipe_config->pipe_bpp = 24;
 	pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
 
-	for_each_intel_connector(dev, intel_connector) {
-		if (intel_connector->new_encoder == encoder) {
-			found = intel_connector;
+	state = pipe_config->base.state;
+
+	for (i = 0; i < state->num_connector; i++) {
+		if (!state->connectors[i])
+			continue;
+
+		if (state->connector_states[i]->best_encoder == &encoder->base) {
+			found = to_intel_connector(state->connectors[i]);
 			break;
 		}
 	}
-- 
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] 52+ messages in thread

* [PATCH 14/19] drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config()
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (12 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 13/19] drm/i915: Don't use staged config in intel_dp_mst_compute_config() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 15/19] drm/i915: Pass an atomic state to modeset_global_resources() functions Ander Conselvan de Oliveira
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move towards atomic by using the legacy modeset's drm_atomic_state
instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_lvds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 2b008b02..06d2da3 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -286,7 +286,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 	struct intel_connector *intel_connector =
 		&lvds_encoder->attached_connector->base;
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-	struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
 	unsigned int lvds_bpp;
 
 	/* Should never happen!! */
-- 
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] 52+ messages in thread

* [PATCH 15/19] drm/i915: Pass an atomic state to modeset_global_resources() functions
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (13 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 14/19] drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config() Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-13  9:48 ` [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state Ander Conselvan de Oliveira
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Follow up patches will convert some functions called from there to use
the atomic state, instead of directly accessing the new or current
config. This patch just changes the parameters, but shouldn't have any
functional changes.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |  2 +-
 drivers/gpu/drm/i915/intel_display.c | 10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a80b15f..490ab8c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -550,7 +550,7 @@ struct drm_i915_display_funcs {
 				 struct drm_crtc *crtc,
 				 uint32_t sprite_width, uint32_t sprite_height,
 				 int pixel_size, bool enable, bool scaled);
-	void (*modeset_global_resources)(struct drm_device *dev);
+	void (*modeset_global_resources)(struct drm_atomic_state *state);
 	/* Returns the active state of the crtc, and if the crtc is active,
 	 * fills out the pipe-config with the hw state. */
 	bool (*get_pipe_config)(struct intel_crtc *,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f0ae907..e720a48 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4826,8 +4826,9 @@ static unsigned long get_crtc_power_domains(struct drm_crtc *crtc)
 	return mask;
 }
 
-static void modeset_update_crtc_power_domains(struct drm_device *dev)
+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;
@@ -4849,7 +4850,7 @@ static void modeset_update_crtc_power_domains(struct drm_device *dev)
 	}
 
 	if (dev_priv->display.modeset_global_resources)
-		dev_priv->display.modeset_global_resources(dev);
+		dev_priv->display.modeset_global_resources(state);
 
 	for_each_intel_crtc(dev, crtc) {
 		enum intel_display_power_domain domain;
@@ -5097,8 +5098,9 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
 	WARN_ON(I915_READ(GCI_CONTROL) & PFI_CREDIT_RESEND);
 }
 
-static void valleyview_modeset_global_resources(struct drm_device *dev)
+static void valleyview_modeset_global_resources(struct drm_atomic_state *state)
 {
+	struct drm_device *dev = state->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int max_pixclk = intel_mode_max_pixclk(dev_priv);
 	int req_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk);
@@ -11405,7 +11407,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	 * update the the output configuration. */
 	intel_modeset_update_state(dev, prepare_pipes);
 
-	modeset_update_crtc_power_domains(dev);
+	modeset_update_crtc_power_domains(pipe_config->base.state);
 
 	/* Set up the DPLL and any encoders state that needs to adjust or depend
 	 * on the 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] 52+ messages in thread

* [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (14 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 15/19] drm/i915: Pass an atomic state to modeset_global_resources() functions Ander Conselvan de Oliveira
@ 2015-03-13  9:48 ` Ander Conselvan de Oliveira
  2015-03-19 20:58   ` Konduru, Chandra
  2015-03-13  9:49 ` [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to " Ander Conselvan de Oliveira
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Makes that code atomic ready.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 49 ++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e720a48..8c97186 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
 	return encoder->get_hw_state(encoder, &pipe);
 }
 
-static int pipe_required_fdi_lanes(struct drm_device *dev, enum pipe pipe)
+static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
+				   enum pipe pipe)
 {
 	struct intel_crtc *crtc =
-		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, pipe));
+	struct intel_crtc_state *crtc_state;
+
+	crtc_state = intel_atomic_get_crtc_state(state, crtc);
+	if (WARN_ON(IS_ERR(crtc_state))) {
+		/* Cause modeset to fail due to excess lanes. */
+		return 5;
+	}
 
-	if (crtc->base.state->enable &&
-	    crtc->config->has_pch_encoder)
+	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
 		return crtc->config->fdi_lanes;
 
 	return 0;
@@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct drm_device *dev, enum pipe pipe)
 static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
 				     struct intel_crtc_state *pipe_config)
 {
+	struct drm_atomic_state *state = pipe_config->base.state;
+
 	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
 		      pipe_name(pipe), pipe_config->fdi_lanes);
 	if (pipe_config->fdi_lanes > 4) {
@@ -5579,7 +5588,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
 		return true;
 	case PIPE_B:
 		if (pipe_config->fdi_lanes > 2 &&
-		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
+		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
 			DRM_DEBUG_KMS("invalid shared fdi lane config on pipe %c: %i lanes\n",
 				      pipe_name(pipe), pipe_config->fdi_lanes);
 			return false;
@@ -5591,7 +5600,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
 				      pipe_name(pipe), pipe_config->fdi_lanes);
 			return false;
 		}
-		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
+		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
 			DRM_DEBUG_KMS("fdi link B uses too many lanes to enable link C\n");
 			return false;
 		}
@@ -5601,15 +5610,41 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
 	}
 }
 
+static int add_pipe_b_c_to_state(struct drm_atomic_state *state)
+{
+	struct intel_crtc *pipe_B =
+		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_B));
+	struct intel_crtc *pipe_C =
+		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_C));
+	struct intel_crtc_state *crtc_state;
+
+	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	return 0;
+}
+
 #define RETRY 1
 static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 				       struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-	int lane, link_bw, fdi_dotclock;
+	int lane, link_bw, fdi_dotclock, ret;
 	bool setup_ok, needs_recompute = false;
 
+	if (IS_IVYBRIDGE(dev) &&
+	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
+		ret = add_pipe_b_c_to_state(pipe_config->base.state);
+		if (ret < 0)
+			return ret;
+	}
+
 retry:
 	/* FDI is a binary signal running at ~2.7GHz, encoding
 	 * each output octet as 10 bits. The actual frequency
-- 
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] 52+ messages in thread

* [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using atomic state
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (15 preceding siblings ...)
  2015-03-13  9:48 ` [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state Ander Conselvan de Oliveira
@ 2015-03-13  9:49 ` Ander Conselvan de Oliveira
  2015-03-19 19:24   ` Konduru, Chandra
  2015-03-13  9:49 ` [PATCH 18/19] drm/i915: Don't look at staged config crtc when changing DRRS state Ander Conselvan de Oliveira
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Pass a crtc_state to it and find whether the pipe has an encoder of a
given type by looking at the drm_atomic_state the crtc_state points to.

Until recently i9xx_get_refclk() used to be called indirectly from
vlv_force_pll_on() with a dummy crtc_state. That dummy crtc state is not
converted to be part of a full drm atomic state, so add a WARN in case
someone decides to call that again with such a dummy state.

v2: Warn if there is no connectors for a given crtc. (Daniel)
    Replace comment i9xx_get_refclk() with a WARN_ON(). (Ander)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   2 +-
 drivers/gpu/drm/i915/intel_display.c | 133 +++++++++++++++++++++--------------
 2 files changed, 83 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 490ab8c..576e101 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -541,7 +541,7 @@ struct drm_i915_display_funcs {
 	 * Returns true on success, false on failure.
 	 */
 	bool (*find_dpll)(const struct intel_limit *limit,
-			  struct intel_crtc *crtc,
+			  struct intel_crtc_state *crtc_state,
 			  int target, int refclk,
 			  struct dpll *match_clock,
 			  struct dpll *best_clock);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8c97186..be1979e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -431,25 +431,41 @@ bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type)
  * intel_pipe_has_type() but looking at encoder->new_crtc instead of
  * encoder->crtc.
  */
-static bool intel_pipe_will_have_type(struct intel_crtc *crtc, int type)
+static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state,
+				      int type)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector_state *connector_state;
 	struct intel_encoder *encoder;
+	int i, num_connectors = 0;
+
+	for (i = 0; i < state->num_connector; i++) {
+		if (!state->connectors[i])
+			continue;
+
+		connector_state = state->connector_states[i];
+		if (connector_state->crtc != crtc_state->base.crtc)
+			continue;
+
+		num_connectors++;
 
-	for_each_intel_encoder(dev, encoder)
-		if (encoder->new_crtc == crtc && encoder->type == type)
+		encoder = to_intel_encoder(connector_state->best_encoder);
+		if (encoder->type == type)
 			return true;
+	}
+
+	WARN_ON(num_connectors == 0);
 
 	return false;
 }
 
-static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc,
-						int refclk)
+static const intel_limit_t *
+intel_ironlake_limit(struct intel_crtc_state *crtc_state, int refclk)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
 	const intel_limit_t *limit;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		if (intel_is_dual_link_lvds(dev)) {
 			if (refclk == 100000)
 				limit = &intel_limits_ironlake_dual_lvds_100m;
@@ -467,20 +483,21 @@ static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc,
 	return limit;
 }
 
-static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc)
+static const intel_limit_t *
+intel_g4x_limit(struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
 	const intel_limit_t *limit;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		if (intel_is_dual_link_lvds(dev))
 			limit = &intel_limits_g4x_dual_channel_lvds;
 		else
 			limit = &intel_limits_g4x_single_channel_lvds;
-	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI) ||
-		   intel_pipe_will_have_type(crtc, INTEL_OUTPUT_ANALOG)) {
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) ||
+		   intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) {
 		limit = &intel_limits_g4x_hdmi;
-	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO)) {
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
 		limit = &intel_limits_g4x_sdvo;
 	} else /* The option is for other outputs */
 		limit = &intel_limits_i9xx_sdvo;
@@ -488,17 +505,18 @@ static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc)
 	return limit;
 }
 
-static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk)
+static const intel_limit_t *
+intel_limit(struct intel_crtc_state *crtc_state, int refclk)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
 	const intel_limit_t *limit;
 
 	if (HAS_PCH_SPLIT(dev))
-		limit = intel_ironlake_limit(crtc, refclk);
+		limit = intel_ironlake_limit(crtc_state, refclk);
 	else if (IS_G4X(dev)) {
-		limit = intel_g4x_limit(crtc);
+		limit = intel_g4x_limit(crtc_state);
 	} else if (IS_PINEVIEW(dev)) {
-		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
+		if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_pineview_lvds;
 		else
 			limit = &intel_limits_pineview_sdvo;
@@ -507,14 +525,14 @@ static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk)
 	} else if (IS_VALLEYVIEW(dev)) {
 		limit = &intel_limits_vlv;
 	} else if (!IS_GEN2(dev)) {
-		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
+		if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i9xx_lvds;
 		else
 			limit = &intel_limits_i9xx_sdvo;
 	} else {
-		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
+		if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
 			limit = &intel_limits_i8xx_lvds;
-		else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO))
+		else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO))
 			limit = &intel_limits_i8xx_dvo;
 		else
 			limit = &intel_limits_i8xx_dac;
@@ -601,15 +619,17 @@ static bool intel_PLL_is_valid(struct drm_device *dev,
 }
 
 static bool
-i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
+i9xx_find_best_dpll(const intel_limit_t *limit,
+		    struct intel_crtc_state *crtc_state,
 		    int target, int refclk, intel_clock_t *match_clock,
 		    intel_clock_t *best_clock)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	intel_clock_t clock;
 	int err = target;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		/*
 		 * For LVDS just rely on its current settings for dual-channel.
 		 * We haven't figured out how to reliably set up different
@@ -662,15 +682,17 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
 }
 
 static bool
-pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
+pnv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
 		   int target, int refclk, intel_clock_t *match_clock,
 		   intel_clock_t *best_clock)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	intel_clock_t clock;
 	int err = target;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		/*
 		 * For LVDS just rely on its current settings for dual-channel.
 		 * We haven't figured out how to reliably set up different
@@ -721,10 +743,12 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
 }
 
 static bool
-g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
+g4x_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
 		   int target, int refclk, intel_clock_t *match_clock,
 		   intel_clock_t *best_clock)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	intel_clock_t clock;
 	int max_n;
@@ -733,7 +757,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
 	int err_most = (target >> 8) + (target >> 9);
 	found = false;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		if (intel_is_dual_link_lvds(dev))
 			clock.p2 = limit->p2.p2_fast;
 		else
@@ -778,10 +802,12 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
 }
 
 static bool
-vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
+vlv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
 		   int target, int refclk, intel_clock_t *match_clock,
 		   intel_clock_t *best_clock)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	intel_clock_t clock;
 	unsigned int bestppm = 1000000;
@@ -835,10 +861,12 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
 }
 
 static bool
-chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
+chv_find_best_dpll(const intel_limit_t *limit,
+		   struct intel_crtc_state *crtc_state,
 		   int target, int refclk, intel_clock_t *match_clock,
 		   intel_clock_t *best_clock)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	intel_clock_t clock;
 	uint64_t m2;
@@ -5726,7 +5754,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	 * - LVDS dual channel mode
 	 * - Double wide pipe
 	 */
-	if ((intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
+	if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
 	     intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
 		pipe_config->pipe_src_w &= ~1;
 
@@ -5905,15 +5933,18 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
 		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
-static int i9xx_get_refclk(struct intel_crtc *crtc, int num_connectors)
+static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
+			   int num_connectors)
 {
-	struct drm_device *dev = crtc->base.dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int refclk;
 
+	WARN_ON(!crtc_state->base.state);
+
 	if (IS_VALLEYVIEW(dev)) {
 		refclk = 100000;
-	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
+	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
 	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
 		refclk = dev_priv->vbt.lvds_ssc_freq;
 		DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk);
@@ -5956,7 +5987,7 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
 	crtc_state->dpll_hw_state.fp0 = fp;
 
 	crtc->lowfreq_avail = false;
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
 	    reduced_clock && i915.powersave) {
 		crtc_state->dpll_hw_state.fp1 = fp2;
 		crtc->lowfreq_avail = true;
@@ -6314,6 +6345,7 @@ 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 pipe_config = {
+		.base.crtc = &crtc->base,
 		.pixel_multiplier = 1,
 		.dpll = *dpll,
 	};
@@ -6358,12 +6390,12 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
 
 	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
 
-	is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) ||
-		intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI);
+	is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO) ||
+		intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
 
 	dpll = DPLL_VGA_MODE_DIS;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
 		dpll |= DPLLB_MODE_LVDS;
 	else
 		dpll |= DPLLB_MODE_DAC_SERIAL;
@@ -6406,7 +6438,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
 
 	if (crtc_state->sdvo_tv_clock)
 		dpll |= PLL_REF_INPUT_TVCLKINBC;
-	else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
+	else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
 		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 	else
@@ -6436,7 +6468,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
 
 	dpll = DPLL_VGA_MODE_DIS;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
 	} else {
 		if (clock->p1 == 2)
@@ -6447,10 +6479,10 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
 			dpll |= PLL_P2_DIVIDE_BY_4;
 	}
 
-	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO))
+	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO))
 		dpll |= DPLL_DVO_2X_MODE;
 
-	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
+	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
 		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
 		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
 	else
@@ -6687,7 +6719,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
 		return 0;
 
 	if (!crtc_state->clock_set) {
-		refclk = i9xx_get_refclk(crtc, num_connectors);
+		refclk = i9xx_get_refclk(crtc_state, num_connectors);
 
 		/*
 		 * Returns a set of divisors for the desired target clock with
@@ -6695,8 +6727,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
 		 * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
 		 * 2) / p1 / p2.
 		 */
-		limit = intel_limit(crtc, refclk);
-		ok = dev_priv->display.find_dpll(limit, crtc,
+		limit = intel_limit(crtc_state, refclk);
+		ok = dev_priv->display.find_dpll(limit, crtc_state,
 						 crtc_state->port_clock,
 						 refclk, NULL, &clock);
 		if (!ok) {
@@ -6712,7 +6744,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
 			 * we will disable the LVDS downclock feature.
 			 */
 			has_reduced_clock =
-				dev_priv->display.find_dpll(limit, crtc,
+				dev_priv->display.find_dpll(limit, crtc_state,
 							    dev_priv->lvds_downclock,
 							    refclk, &clock,
 							    &reduced_clock);
@@ -7540,12 +7572,11 @@ static bool ironlake_compute_clocks(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);
 	int refclk;
 	const intel_limit_t *limit;
 	bool ret, is_lvds = false;
 
-	is_lvds = intel_pipe_will_have_type(intel_crtc, INTEL_OUTPUT_LVDS);
+	is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
 
 	refclk = ironlake_get_refclk(crtc);
 
@@ -7554,8 +7585,8 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
 	 * refclk, or FALSE.  The returned values represent the clock equation:
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
-	limit = intel_limit(intel_crtc, refclk);
-	ret = dev_priv->display.find_dpll(limit, intel_crtc,
+	limit = intel_limit(crtc_state, refclk);
+	ret = dev_priv->display.find_dpll(limit, crtc_state,
 					  crtc_state->port_clock,
 					  refclk, NULL, clock);
 	if (!ret)
@@ -7569,7 +7600,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
 		 * downclock feature.
 		*/
 		*has_reduced_clock =
-			dev_priv->display.find_dpll(limit, intel_crtc,
+			dev_priv->display.find_dpll(limit, crtc_state,
 						    dev_priv->lvds_downclock,
 						    refclk, clock,
 						    reduced_clock);
-- 
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] 52+ messages in thread

* [PATCH 18/19] drm/i915: Don't look at staged config crtc when changing DRRS state
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (16 preceding siblings ...)
  2015-03-13  9:49 ` [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to " Ander Conselvan de Oliveira
@ 2015-03-13  9:49 ` Ander Conselvan de Oliveira
  2015-03-13  9:49 ` [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations Ander Conselvan de Oliveira
  2015-03-18 23:57 ` [PATCH v2 00/19] Remove depencies on staged config for atomic transition Konduru, Chandra
  19 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

The function intel_dp_set_drrs_state() would decide which pipe to
downclock based on the staged config for the given connector. However,
the result of that function is immediate, and it uses input values from
crtc->config, so it should be looking at the current crtc instead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 510927e..7954302 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -4932,7 +4932,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 = encoder->new_crtc;
+	intel_crtc = to_intel_crtc(encoder->base.crtc);
 
 	if (!intel_crtc) {
 		DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
-- 
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] 52+ messages in thread

* [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (17 preceding siblings ...)
  2015-03-13  9:49 ` [PATCH 18/19] drm/i915: Don't look at staged config crtc when changing DRRS state Ander Conselvan de Oliveira
@ 2015-03-13  9:49 ` Ander Conselvan de Oliveira
  2015-03-14  0:29   ` shuang.he
  2015-03-19 20:39   ` Konduru, Chandra
  2015-03-18 23:57 ` [PATCH v2 00/19] Remove depencies on staged config for atomic transition Konduru, Chandra
  19 siblings, 2 replies; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-13  9:49 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Some of the crtc_compute_clock() still depended on encoder->new_crtc
since they didn't use intel_pipe_will_have_type() and used an open
coded version of that function instead. This patch replaces those with
the appropriate code that checks the atomic state intead.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 45 +++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index be1979e..35ed651 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6696,11 +6696,18 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
 	bool is_lvds = false, is_dsi = false;
 	struct intel_encoder *encoder;
 	const intel_limit_t *limit;
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector_state *connector_state;
+	int i;
 
-	for_each_intel_encoder(dev, encoder) {
-		if (encoder->new_crtc != crtc)
+	for (i = 0; i < state->num_connector; i++) {
+		connector_state = state->connector_states[i];
+		if (!state->connectors[i] ||
+		    connector_state->crtc != &crtc->base)
 			continue;
 
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
 		switch (encoder->type) {
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
@@ -7374,18 +7381,24 @@ void intel_init_pch_refclk(struct drm_device *dev)
 		lpt_init_pch_refclk(dev);
 }
 
-static int ironlake_get_refclk(struct drm_crtc *crtc)
+static int ironlake_get_refclk(struct intel_crtc_state *crtc_state)
 {
-	struct drm_device *dev = crtc->dev;
+	struct drm_device *dev = crtc_state->base.crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector_state *connector_state;
 	struct intel_encoder *encoder;
-	int num_connectors = 0;
+	int num_connectors = 0, i;
 	bool is_lvds = false;
 
-	for_each_intel_encoder(dev, encoder) {
-		if (encoder->new_crtc != to_intel_crtc(crtc))
+	for (i = 0; i < state->num_connector; i++) {
+		connector_state = state->connector_states[i];
+		if (!state->connectors[i] ||
+		    connector_state->crtc != crtc_state->base.crtc)
 			continue;
 
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
 		switch (encoder->type) {
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
@@ -7578,7 +7591,7 @@ static bool ironlake_compute_clocks(struct drm_crtc *crtc,
 
 	is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
 
-	refclk = ironlake_get_refclk(crtc);
+	refclk = ironlake_get_refclk(crtc_state);
 
 	/*
 	 * Returns a set of divisors for the desired target clock with the given
@@ -7633,16 +7646,22 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 	struct drm_crtc *crtc = &intel_crtc->base;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_encoder *intel_encoder;
+	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_connector_state *connector_state;
+	struct intel_encoder *encoder;
 	uint32_t dpll;
-	int factor, num_connectors = 0;
+	int factor, num_connectors = 0, i;
 	bool is_lvds = false, is_sdvo = false;
 
-	for_each_intel_encoder(dev, intel_encoder) {
-		if (intel_encoder->new_crtc != to_intel_crtc(crtc))
+	for (i = 0; i < state->num_connector; i++) {
+		connector_state = state->connector_states[i];
+		if (!state->connectors[i] ||
+		    connector_state->crtc != crtc_state->base.crtc)
 			continue;
 
-		switch (intel_encoder->type) {
+		encoder = to_intel_encoder(connector_state->best_encoder);
+
+		switch (encoder->type) {
 		case INTEL_OUTPUT_LVDS:
 			is_lvds = true;
 			break;
-- 
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] 52+ messages in thread

* Re: [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations
  2015-03-13  9:49 ` [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations Ander Conselvan de Oliveira
@ 2015-03-14  0:29   ` shuang.he
  2015-03-19 20:39   ` Konduru, Chandra
  1 sibling, 0 replies; 52+ messages in thread
From: shuang.he @ 2015-03-14  0:29 UTC (permalink / raw)
  To: shuang.he, ethan.gao, intel-gfx, ander.conselvan.de.oliveira

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
Task id: 5946
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  276/276              276/276
ILK                 -6              303/303              297/303
SNB                                  279/279              279/279
IVB                                  343/343              343/343
BYT                                  287/287              287/287
HSW                 -1              363/363              362/363
BDW                                  308/308              308/308
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
*ILK  igt_drv_suspend_debugfs-reader      PASS(2)      DMESG_WARN(2)
*ILK  igt_drv_suspend_fence-restore-tiled2untiled      PASS(2)      DMESG_WARN(1)
*ILK  igt_drv_suspend_fence-restore-untiled      PASS(2)      DMESG_WARN(2)
*ILK  igt_drv_suspend_forcewake      PASS(2)      DMESG_WARN(2)
*ILK  igt_gem_workarounds_suspend-resume      PASS(2)      DMESG_WARN(2)
*ILK  igt_kms_flip_blocking-absolute-wf_vblank-interruptible      PASS(2)      DMESG_FAIL(2)
*HSW  igt_gem_pwrite_pread_snooped-copy-performance      PASS(2)      DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v3] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-13  9:48 ` [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code Ander Conselvan de Oliveira
@ 2015-03-17  6:46   ` Ander Conselvan de Oliveira
  2015-03-18  7:57     ` [PATCH v4] " Ander Conselvan de Oliveira
  2015-03-19 21:08   ` [PATCH 03/19] " Konduru, Chandra
  1 sibling, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-17  6:46 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

For the atomic conversion, the mode set paths need to be changed to rely
on an atomic state instead of using the staged config. By using an
atomic state for the legacy code, we will be able to convert the code
base in small chunks.

v2: Squash patch that adds stat argument to intel_set_mode(). (Ander)
    Make every caller of intel_set_mode() allocate state. (Daniel)
    Call drm_atomic_state_clear() in set config's error path. (Daniel)

v3: Copy staged config to atomic state in force restore path. (PRTS)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 197 ++++++++++++++++++++++++++++-------
 1 file changed, 162 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8458bf5..3c8f7f4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -83,7 +83,8 @@ 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_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *old_fb);
+			  int x, int y, struct drm_framebuffer *old_fb,
+			  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,
@@ -8802,6 +8803,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 	struct drm_device *dev = encoder->dev;
 	struct drm_framebuffer *fb;
 	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state = NULL;
 	int ret, i = -1;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
@@ -8883,6 +8885,12 @@ retry:
 	old->load_detect_temp = true;
 	old->release_fb = NULL;
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return false;
+
+	state->acquire_ctx = ctx;
+
 	if (!mode)
 		mode = &load_detect_mode;
 
@@ -8905,7 +8913,7 @@ retry:
 		goto fail;
 	}
 
-	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
+	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
@@ -8924,6 +8932,11 @@ retry:
 	else
 		intel_crtc->new_config = NULL;
 fail_unlock:
+	if (state) {
+		drm_atomic_state_free(state);
+		state = NULL;
+	}
+
 	if (ret == -EDEADLK) {
 		drm_modeset_backoff(ctx);
 		goto retry;
@@ -8936,22 +8949,34 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 				    struct intel_load_detect_pipe *old,
 				    struct drm_modeset_acquire_ctx *ctx)
 {
+	struct drm_device *dev = connector->dev;
 	struct intel_encoder *intel_encoder =
 		intel_attached_encoder(connector);
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_atomic_state *state;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
 		      connector->base.id, connector->name,
 		      encoder->base.id, encoder->name);
 
 	if (old->load_detect_temp) {
+		state = drm_atomic_state_alloc(dev);
+		if (!state) {
+			DRM_DEBUG_KMS("can't release load detect pipe\n");
+			return;
+		}
+
+		state->acquire_ctx = ctx;
+
 		to_intel_connector(connector)->new_encoder = NULL;
 		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 		intel_crtc->new_config = NULL;
-		intel_set_mode(crtc, NULL, 0, 0, NULL);
+		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
+
+		drm_atomic_state_free(state);
 
 		if (old->release_fb) {
 			drm_framebuffer_unregister_private(old->release_fb);
@@ -10345,10 +10370,22 @@ static bool check_digital_port_conflicts(struct drm_device *dev)
 	return true;
 }
 
-static struct intel_crtc_state *
+static void
+clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
+{
+	struct drm_crtc_state tmp_state;
+
+	/* Clear only the intel specific part of the crtc state */
+	tmp_state = crtc_state->base;
+	memset(crtc_state, 0, sizeof *crtc_state);
+	crtc_state->base = tmp_state;
+}
+
+static int
 intel_modeset_pipe_config(struct drm_crtc *crtc,
 			  struct drm_framebuffer *fb,
-			  struct drm_display_mode *mode)
+			  struct drm_display_mode *mode,
+			  struct drm_atomic_state *state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct intel_encoder *encoder;
@@ -10358,17 +10395,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 
 	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
 		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	if (!check_digital_port_conflicts(dev)) {
 		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
-	if (!pipe_config)
-		return ERR_PTR(-ENOMEM);
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return PTR_ERR(pipe_config);
+
+	clear_intel_crtc_state(pipe_config);
 
 	pipe_config->base.crtc = crtc;
 	drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
@@ -10463,10 +10502,9 @@ encoder_retry:
 	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
 		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
-	return pipe_config;
+	return 0;
 fail:
-	kfree(pipe_config);
-	return ERR_PTR(ret);
+	return ret;
 }
 
 /* Computes which crtcs are affected and sets the relevant bits in the mask. For
@@ -11144,17 +11182,19 @@ static struct intel_crtc_state *
 intel_modeset_compute_config(struct drm_crtc *crtc,
 			     struct drm_display_mode *mode,
 			     struct drm_framebuffer *fb,
+			     struct drm_atomic_state *state,
 			     unsigned *modeset_pipes,
 			     unsigned *prepare_pipes,
 			     unsigned *disable_pipes)
 {
 	struct intel_crtc_state *pipe_config = NULL;
+	int ret = 0;
 
 	intel_modeset_affected_pipes(crtc, modeset_pipes,
 				     prepare_pipes, disable_pipes);
 
 	if ((*modeset_pipes) == 0)
-		goto out;
+		return NULL;
 
 	/*
 	 * Note this needs changes when we start tracking multiple modes
@@ -11162,14 +11202,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	 * (i.e. one pipe_config for each crtc) rather than just the one
 	 * for this crtc.
 	 */
-	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
-	if (IS_ERR(pipe_config)) {
-		goto out;
-	}
+	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
+	if (ret)
+		return ERR_PTR(ret);
+
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return pipe_config;
+
 	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
 			       "[modeset]");
 
-out:
 	return pipe_config;
 }
 
@@ -11214,6 +11257,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *saved_mode;
+	struct intel_crtc_state *crtc_state_copy = NULL;
 	struct intel_crtc *intel_crtc;
 	int ret = 0;
 
@@ -11221,6 +11265,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	if (!saved_mode)
 		return -ENOMEM;
 
+	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
+	if (!crtc_state_copy) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
 	*saved_mode = crtc->mode;
 
 	if (modeset_pipes)
@@ -11307,6 +11357,19 @@ done:
 	if (ret && crtc->state->enable)
 		crtc->mode = *saved_mode;
 
+	if (ret == 0 && pipe_config) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		/* The pipe_config will be freed with the atomic state, so
+		 * make a copy. */
+		memcpy(crtc_state_copy, intel_crtc->config,
+		       sizeof *crtc_state_copy);
+		intel_crtc->config = intel_crtc->new_config = crtc_state_copy;
+		intel_crtc->base.state = &crtc_state_copy->base;
+	} else {
+		kfree(crtc_state_copy);
+	}
+
 	kfree(saved_mode);
 	return ret;
 }
@@ -11332,27 +11395,81 @@ static int intel_set_mode_pipes(struct drm_crtc *crtc,
 
 static int intel_set_mode(struct drm_crtc *crtc,
 			  struct drm_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *fb)
+			  int x, int y, struct drm_framebuffer *fb,
+			  struct drm_atomic_state *state)
 {
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
+	int ret = 0;
 
-	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
+	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
 
-	if (IS_ERR(pipe_config))
-		return PTR_ERR(pipe_config);
+	if (IS_ERR(pipe_config)) {
+		ret = PTR_ERR(pipe_config);
+		goto out;
+	}
+
+	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
+				   modeset_pipes, prepare_pipes,
+				   disable_pipes);
+	if (ret)
+		goto out;
 
-	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
-				    modeset_pipes, prepare_pipes,
-				    disable_pipes);
+out:
+	return ret;
 }
 
 void intel_crtc_restore_mode(struct drm_crtc *crtc)
 {
-	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
+	struct drm_device *dev = crtc->dev;
+	struct drm_atomic_state *state;
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	struct drm_connector_state *connector_state;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
+			      crtc->base.id);
+		return;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
+	/* The force restore path in the HW readout code relies on the staged
+	 * config still keeping the user requested config while the actual
+	 * state has been overwritten by the configuration read from HW. We
+	 * 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)
+			continue;
+
+		for_each_intel_connector(dev, connector) {
+			if (connector->new_encoder != encoder)
+				continue;
+
+			connector_state = drm_atomic_get_connector_state(state, &connector->base);
+			if (IS_ERR(connector_state)) {
+				DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
+					      connector->base.base.id,
+					      connector->base.name,
+					      PTR_ERR(connector_state));
+				continue;
+			}
+
+			connector_state->crtc = crtc;
+			connector_state->best_encoder = &encoder->base;
+		}
+	}
+
+	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
+		       state);
+
+	drm_atomic_state_free(state);
 }
 
 #undef for_each_intel_crtc_masked
@@ -11677,6 +11794,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
 	struct drm_mode_set save_set;
+	struct drm_atomic_state *state = NULL;
 	struct intel_set_config *config;
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
@@ -11721,12 +11839,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 	 * such cases. */
 	intel_set_config_compute_mode_changes(set, config);
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto out_config;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
 	ret = intel_modeset_stage_output_state(dev, set, config);
 	if (ret)
 		goto fail;
 
 	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
-						   set->fb,
+						   set->fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
@@ -11746,10 +11872,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 		 */
 	}
 
-	/* set_mode will free it in the mode_changed case */
-	if (!config->mode_changed)
-		kfree(pipe_config);
-
 	intel_update_pipe_size(to_intel_crtc(set->crtc));
 
 	if (config->mode_changed) {
@@ -11795,6 +11917,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 fail:
 		intel_set_config_restore_state(dev, config);
 
+		drm_atomic_state_clear(state);
+
 		/*
 		 * HACK: if the pipe was on, but we didn't have a framebuffer,
 		 * force the pipe off to avoid oopsing in the modeset code
@@ -11807,11 +11931,15 @@ fail:
 		/* Try to restore the config */
 		if (config->mode_changed &&
 		    intel_set_mode(save_set.crtc, save_set.mode,
-				   save_set.x, save_set.y, save_set.fb))
+				   save_set.x, save_set.y, save_set.fb,
+				   state))
 			DRM_ERROR("failed to restore config after modeset failure\n");
 	}
 
 out_config:
+	if (state)
+		drm_atomic_state_free(state);
+
 	intel_set_config_free(config);
 	return ret;
 }
@@ -13852,8 +13980,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 			struct drm_crtc *crtc =
 				dev_priv->pipe_to_crtc_mapping[pipe];
 
-			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
-				       crtc->primary->fb);
+			intel_crtc_restore_mode(crtc);
 		}
 	} else {
 		intel_modeset_update_staged_output_state(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] 52+ messages in thread

* [PATCH v4] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-17  6:46   ` [PATCH v3] " Ander Conselvan de Oliveira
@ 2015-03-18  7:57     ` Ander Conselvan de Oliveira
  2015-03-18 23:57       ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan de Oliveira @ 2015-03-18  7:57 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

For the atomic conversion, the mode set paths need to be changed to rely
on an atomic state instead of using the staged config. By using an
atomic state for the legacy code, we will be able to convert the code
base in small chunks.

v2: Squash patch that adds stat argument to intel_set_mode(). (Ander)
    Make every caller of intel_set_mode() allocate state. (Daniel)
    Call drm_atomic_state_clear() in set config's error path. (Daniel)

v3: Copy staged config to atomic state in force restore path. (Ander)

v4: Don't update ->new_config for disabled pipes in __intel_set_mode(),
    since it is expected to be NULL in that case. (Ander)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 200 +++++++++++++++++++++++++++++------
 1 file changed, 165 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8458bf5..ce35647 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -83,7 +83,8 @@ 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_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *old_fb);
+			  int x, int y, struct drm_framebuffer *old_fb,
+			  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,
@@ -8802,6 +8803,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
 	struct drm_device *dev = encoder->dev;
 	struct drm_framebuffer *fb;
 	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_atomic_state *state = NULL;
 	int ret, i = -1;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
@@ -8883,6 +8885,12 @@ retry:
 	old->load_detect_temp = true;
 	old->release_fb = NULL;
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return false;
+
+	state->acquire_ctx = ctx;
+
 	if (!mode)
 		mode = &load_detect_mode;
 
@@ -8905,7 +8913,7 @@ retry:
 		goto fail;
 	}
 
-	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
+	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
@@ -8924,6 +8932,11 @@ retry:
 	else
 		intel_crtc->new_config = NULL;
 fail_unlock:
+	if (state) {
+		drm_atomic_state_free(state);
+		state = NULL;
+	}
+
 	if (ret == -EDEADLK) {
 		drm_modeset_backoff(ctx);
 		goto retry;
@@ -8936,22 +8949,34 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 				    struct intel_load_detect_pipe *old,
 				    struct drm_modeset_acquire_ctx *ctx)
 {
+	struct drm_device *dev = connector->dev;
 	struct intel_encoder *intel_encoder =
 		intel_attached_encoder(connector);
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = encoder->crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_atomic_state *state;
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
 		      connector->base.id, connector->name,
 		      encoder->base.id, encoder->name);
 
 	if (old->load_detect_temp) {
+		state = drm_atomic_state_alloc(dev);
+		if (!state) {
+			DRM_DEBUG_KMS("can't release load detect pipe\n");
+			return;
+		}
+
+		state->acquire_ctx = ctx;
+
 		to_intel_connector(connector)->new_encoder = NULL;
 		intel_encoder->new_crtc = NULL;
 		intel_crtc->new_enabled = false;
 		intel_crtc->new_config = NULL;
-		intel_set_mode(crtc, NULL, 0, 0, NULL);
+		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
+
+		drm_atomic_state_free(state);
 
 		if (old->release_fb) {
 			drm_framebuffer_unregister_private(old->release_fb);
@@ -10345,10 +10370,22 @@ static bool check_digital_port_conflicts(struct drm_device *dev)
 	return true;
 }
 
-static struct intel_crtc_state *
+static void
+clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
+{
+	struct drm_crtc_state tmp_state;
+
+	/* Clear only the intel specific part of the crtc state */
+	tmp_state = crtc_state->base;
+	memset(crtc_state, 0, sizeof *crtc_state);
+	crtc_state->base = tmp_state;
+}
+
+static int
 intel_modeset_pipe_config(struct drm_crtc *crtc,
 			  struct drm_framebuffer *fb,
-			  struct drm_display_mode *mode)
+			  struct drm_display_mode *mode,
+			  struct drm_atomic_state *state)
 {
 	struct drm_device *dev = crtc->dev;
 	struct intel_encoder *encoder;
@@ -10358,17 +10395,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 
 	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
 		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	if (!check_digital_port_conflicts(dev)) {
 		DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
-	if (!pipe_config)
-		return ERR_PTR(-ENOMEM);
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return PTR_ERR(pipe_config);
+
+	clear_intel_crtc_state(pipe_config);
 
 	pipe_config->base.crtc = crtc;
 	drm_mode_copy(&pipe_config->base.adjusted_mode, mode);
@@ -10463,10 +10502,9 @@ encoder_retry:
 	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
 		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
-	return pipe_config;
+	return 0;
 fail:
-	kfree(pipe_config);
-	return ERR_PTR(ret);
+	return ret;
 }
 
 /* Computes which crtcs are affected and sets the relevant bits in the mask. For
@@ -11144,17 +11182,19 @@ static struct intel_crtc_state *
 intel_modeset_compute_config(struct drm_crtc *crtc,
 			     struct drm_display_mode *mode,
 			     struct drm_framebuffer *fb,
+			     struct drm_atomic_state *state,
 			     unsigned *modeset_pipes,
 			     unsigned *prepare_pipes,
 			     unsigned *disable_pipes)
 {
 	struct intel_crtc_state *pipe_config = NULL;
+	int ret = 0;
 
 	intel_modeset_affected_pipes(crtc, modeset_pipes,
 				     prepare_pipes, disable_pipes);
 
 	if ((*modeset_pipes) == 0)
-		goto out;
+		return NULL;
 
 	/*
 	 * Note this needs changes when we start tracking multiple modes
@@ -11162,14 +11202,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
 	 * (i.e. one pipe_config for each crtc) rather than just the one
 	 * for this crtc.
 	 */
-	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
-	if (IS_ERR(pipe_config)) {
-		goto out;
-	}
+	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
+	if (ret)
+		return ERR_PTR(ret);
+
+	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
+	if (IS_ERR(pipe_config))
+		return pipe_config;
+
 	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
 			       "[modeset]");
 
-out:
 	return pipe_config;
 }
 
@@ -11214,6 +11257,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *saved_mode;
+	struct intel_crtc_state *crtc_state_copy = NULL;
 	struct intel_crtc *intel_crtc;
 	int ret = 0;
 
@@ -11221,6 +11265,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
 	if (!saved_mode)
 		return -ENOMEM;
 
+	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
+	if (!crtc_state_copy) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
 	*saved_mode = crtc->mode;
 
 	if (modeset_pipes)
@@ -11307,6 +11357,22 @@ done:
 	if (ret && crtc->state->enable)
 		crtc->mode = *saved_mode;
 
+	if (ret == 0 && pipe_config) {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+		/* The pipe_config will be freed with the atomic state, so
+		 * make a copy. */
+		memcpy(crtc_state_copy, intel_crtc->config,
+		       sizeof *crtc_state_copy);
+		intel_crtc->config = crtc_state_copy;
+		intel_crtc->base.state = &crtc_state_copy->base;
+
+		if (modeset_pipes)
+			intel_crtc->new_config = intel_crtc->config;
+	} else {
+		kfree(crtc_state_copy);
+	}
+
 	kfree(saved_mode);
 	return ret;
 }
@@ -11332,27 +11398,81 @@ static int intel_set_mode_pipes(struct drm_crtc *crtc,
 
 static int intel_set_mode(struct drm_crtc *crtc,
 			  struct drm_display_mode *mode,
-			  int x, int y, struct drm_framebuffer *fb)
+			  int x, int y, struct drm_framebuffer *fb,
+			  struct drm_atomic_state *state)
 {
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
+	int ret = 0;
 
-	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
+	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
 
-	if (IS_ERR(pipe_config))
-		return PTR_ERR(pipe_config);
+	if (IS_ERR(pipe_config)) {
+		ret = PTR_ERR(pipe_config);
+		goto out;
+	}
+
+	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
+				   modeset_pipes, prepare_pipes,
+				   disable_pipes);
+	if (ret)
+		goto out;
 
-	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
-				    modeset_pipes, prepare_pipes,
-				    disable_pipes);
+out:
+	return ret;
 }
 
 void intel_crtc_restore_mode(struct drm_crtc *crtc)
 {
-	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
+	struct drm_device *dev = crtc->dev;
+	struct drm_atomic_state *state;
+	struct intel_encoder *encoder;
+	struct intel_connector *connector;
+	struct drm_connector_state *connector_state;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of memory",
+			      crtc->base.id);
+		return;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
+	/* The force restore path in the HW readout code relies on the staged
+	 * config still keeping the user requested config while the actual
+	 * state has been overwritten by the configuration read from HW. We
+	 * 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)
+			continue;
+
+		for_each_intel_connector(dev, connector) {
+			if (connector->new_encoder != encoder)
+				continue;
+
+			connector_state = drm_atomic_get_connector_state(state, &connector->base);
+			if (IS_ERR(connector_state)) {
+				DRM_DEBUG_KMS("Failed to add [CONNECTOR:%d:%s] to state: %ld\n",
+					      connector->base.base.id,
+					      connector->base.name,
+					      PTR_ERR(connector_state));
+				continue;
+			}
+
+			connector_state->crtc = crtc;
+			connector_state->best_encoder = &encoder->base;
+		}
+	}
+
+	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
+		       state);
+
+	drm_atomic_state_free(state);
 }
 
 #undef for_each_intel_crtc_masked
@@ -11677,6 +11797,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
 	struct drm_mode_set save_set;
+	struct drm_atomic_state *state = NULL;
 	struct intel_set_config *config;
 	struct intel_crtc_state *pipe_config;
 	unsigned modeset_pipes, prepare_pipes, disable_pipes;
@@ -11721,12 +11842,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 	 * such cases. */
 	intel_set_config_compute_mode_changes(set, config);
 
+	state = drm_atomic_state_alloc(dev);
+	if (!state) {
+		ret = -ENOMEM;
+		goto out_config;
+	}
+
+	state->acquire_ctx = dev->mode_config.acquire_ctx;
+
 	ret = intel_modeset_stage_output_state(dev, set, config);
 	if (ret)
 		goto fail;
 
 	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
-						   set->fb,
+						   set->fb, state,
 						   &modeset_pipes,
 						   &prepare_pipes,
 						   &disable_pipes);
@@ -11746,10 +11875,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 		 */
 	}
 
-	/* set_mode will free it in the mode_changed case */
-	if (!config->mode_changed)
-		kfree(pipe_config);
-
 	intel_update_pipe_size(to_intel_crtc(set->crtc));
 
 	if (config->mode_changed) {
@@ -11795,6 +11920,8 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
 fail:
 		intel_set_config_restore_state(dev, config);
 
+		drm_atomic_state_clear(state);
+
 		/*
 		 * HACK: if the pipe was on, but we didn't have a framebuffer,
 		 * force the pipe off to avoid oopsing in the modeset code
@@ -11807,11 +11934,15 @@ fail:
 		/* Try to restore the config */
 		if (config->mode_changed &&
 		    intel_set_mode(save_set.crtc, save_set.mode,
-				   save_set.x, save_set.y, save_set.fb))
+				   save_set.x, save_set.y, save_set.fb,
+				   state))
 			DRM_ERROR("failed to restore config after modeset failure\n");
 	}
 
 out_config:
+	if (state)
+		drm_atomic_state_free(state);
+
 	intel_set_config_free(config);
 	return ret;
 }
@@ -13852,8 +13983,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
 			struct drm_crtc *crtc =
 				dev_priv->pipe_to_crtc_mapping[pipe];
 
-			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
-				       crtc->primary->fb);
+			intel_crtc_restore_mode(crtc);
 		}
 	} else {
 		intel_modeset_update_staged_output_state(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] 52+ messages in thread

* Re: [PATCH v2 00/19] Remove depencies on staged config for atomic transition
  2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
                   ` (18 preceding siblings ...)
  2015-03-13  9:49 ` [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations Ander Conselvan de Oliveira
@ 2015-03-18 23:57 ` Konduru, Chandra
  2015-03-19 15:20   ` Daniel Vetter
  19 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-18 23:57 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH v2 00/19] Remove depencies on staged config for atomic
> transition
> 
> Here's v2 with most of the comments from Daniel addressed. I didn't change the
> zeroing of the crtc_state to the duplicate state function, since it causes
> problems when we add the state of a crtc that isn't going through a modeset.
> Specifically, this would cause the code that decides whether pipes B and C can
> be enabled at the same time to fail, since the number of fdi lanes would be zero.
> 
> The other concerns I raised with v1 are also addressed. I tested this on
> IVYBRIDGE using pipes B & C, and the load detect code path using Daniel's patch
> that adds the i915.load_detect_test parameter.

Had a chat with Ander to get an overview of his patches. It is helping to 
review the patches. There are still couple questions, so will ask for
clarifications as I go through the changes. 

Also got clarified that this patch series is moving in direction for atomic_crtc
but more work needs to be done to separate out check path, swap states
then commit path. And hook these check and commit paths into 
intel_atomic_check/commit functions.

Also any resources involved in doing internally induced set_mode, 
update_plane needs to be added to incoming nuclear/atomic transaction.
I think this is one of the major todo. In that process need find way to
avoid nested atomic transactions. Also complications can arise if the 
transaction already has crtc state to do a mode change, and requires 
another set mode to do load detect. In these type of scenarios, suspend
calling nuclear transaction and start a freshone? Or do both at same time.
It is not clear how this can be done. Probably Daniel has some ideas
to overcome these.

Current nightly has .update_plane pointing to helper upate instead of 
atomic_helper_update to avoid nested atomic.

> 
> Thanks,
> Ander
> 
> Ander Conselvan de Oliveira (19):
>   drm/i915: Add intel_atomic_get_crtc_state() helper function
>   drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe()
>   drm/i915: Allocate a drm_atomic_state for the legacy modeset code
>   drm/i915: Allocate a crtc_state also when the crtc is being disabled
>   drm/i915: Update dummy connector atomic state with current config
>   drm/i915: Implement connector state duplication
>   drm/i915: Copy the staged connector config to the legacy atomic state
>   drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config()
>   drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp()
>   drm/i915: Don't depend on encoder->new_crtc in
>     intel_dp_compute_config()
>   drm/i915: Don't depend on encoder->new_crtc in
>     intel_hdmi_compute_config
>   drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder()
>   drm/i915: Don't use staged config in intel_dp_mst_compute_config()
>   drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config()
>   drm/i915: Pass an atomic state to modeset_global_resources() functions
>   drm/i915: Check lane sharing between pipes B & C using atomic state
>   drm/i915: Convert intel_pipe_will_have_type() to using atomic state
>   drm/i915: Don't look at staged config crtc when changing DRRS state
>   drm/i915: Remove usage of encoder->new_crtc from clock computations
> 
>  drivers/gpu/drm/i915/i915_drv.h      |   4 +-
>  drivers/gpu/drm/i915/intel_crt.c     |   3 +-
>  drivers/gpu/drm/i915/intel_ddi.c     |  24 +-
>  drivers/gpu/drm/i915/intel_display.c | 544 ++++++++++++++++++++++++++-----
> ----
>  drivers/gpu/drm/i915/intel_dp.c      |   5 +-
>  drivers/gpu/drm/i915/intel_dp_mst.c  |  18 +-
>  drivers/gpu/drm/i915/intel_drv.h     |  16 +-
>  drivers/gpu/drm/i915/intel_dsi.c     |   1 +
>  drivers/gpu/drm/i915/intel_dvo.c     |   1 +
>  drivers/gpu/drm/i915/intel_hdmi.c    |  22 +-
>  drivers/gpu/drm/i915/intel_lvds.c    |   3 +-
>  drivers/gpu/drm/i915/intel_sdvo.c    |   1 +
>  drivers/gpu/drm/i915/intel_tv.c      |   3 +-
>  13 files changed, 484 insertions(+), 161 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] 52+ messages in thread

* Re: [PATCH v4] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-18  7:57     ` [PATCH v4] " Ander Conselvan de Oliveira
@ 2015-03-18 23:57       ` Konduru, Chandra
  2015-03-19  7:50         ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-18 23:57 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Wednesday, March 18, 2015 12:57 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH v4] drm/i915: Allocate a drm_atomic_state for the legacy
> modeset code
> 
> For the atomic conversion, the mode set paths need to be changed to rely on an
> atomic state instead of using the staged config. By using an atomic state for the
> legacy code, we will be able to convert the code base in small chunks.
> 
> v2: Squash patch that adds stat argument to intel_set_mode(). (Ander)
>     Make every caller of intel_set_mode() allocate state. (Daniel)
>     Call drm_atomic_state_clear() in set config's error path. (Daniel)
> 
> v3: Copy staged config to atomic state in force restore path. (Ander)
> 
> v4: Don't update ->new_config for disabled pipes in __intel_set_mode(),
>     since it is expected to be NULL in that case. (Ander)

Can you clarify why it is expected to be NULL?

> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 200 +++++++++++++++++++++++++++++-
> -----
>  1 file changed, 165 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 8458bf5..ce35647 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -83,7 +83,8 @@ 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_display_mode
> *mode,
> -			  int x, int y, struct drm_framebuffer *old_fb);
> +			  int x, int y, struct drm_framebuffer *old_fb,
> +			  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, @@
> -8802,6 +8803,7 @@ bool intel_get_load_detect_pipe(struct drm_connector
> *connector,
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_framebuffer *fb;
>  	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_atomic_state *state = NULL;
>  	int ret, i = -1;
> 
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> -8883,6 +8885,12 @@ retry:
>  	old->load_detect_temp = true;
>  	old->release_fb = NULL;
> 
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state)
> +		return false;
> +
> +	state->acquire_ctx = ctx;
> +
>  	if (!mode)
>  		mode = &load_detect_mode;
> 
> @@ -8905,7 +8913,7 @@ retry:
>  		goto fail;
>  	}
> 
> -	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
> +	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
> @@ -8924,6 +8932,11 @@ retry:
>  	else
>  		intel_crtc->new_config = NULL;
>  fail_unlock:
> +	if (state) {
> +		drm_atomic_state_free(state);
> +		state = NULL;
> +	}
> +
>  	if (ret == -EDEADLK) {
>  		drm_modeset_backoff(ctx);
>  		goto retry;
> @@ -8936,22 +8949,34 @@ void intel_release_load_detect_pipe(struct
> drm_connector *connector,
>  				    struct intel_load_detect_pipe *old,
>  				    struct drm_modeset_acquire_ctx *ctx)  {
> +	struct drm_device *dev = connector->dev;
>  	struct intel_encoder *intel_encoder =
>  		intel_attached_encoder(connector);
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_crtc *crtc = encoder->crtc;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_atomic_state *state;
> 
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
>  		      connector->base.id, connector->name,
>  		      encoder->base.id, encoder->name);
> 
>  	if (old->load_detect_temp) {
> +		state = drm_atomic_state_alloc(dev);
> +		if (!state) {
> +			DRM_DEBUG_KMS("can't release load detect pipe\n");
> +			return;
> +		}
> +
> +		state->acquire_ctx = ctx;
> +
>  		to_intel_connector(connector)->new_encoder = NULL;
>  		intel_encoder->new_crtc = NULL;
>  		intel_crtc->new_enabled = false;
>  		intel_crtc->new_config = NULL;
> -		intel_set_mode(crtc, NULL, 0, 0, NULL);
> +		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> +
> +		drm_atomic_state_free(state);
> 
>  		if (old->release_fb) {
>  			drm_framebuffer_unregister_private(old->release_fb);
> @@ -10345,10 +10370,22 @@ static bool check_digital_port_conflicts(struct
> drm_device *dev)
>  	return true;
>  }
> 
> -static struct intel_crtc_state *
> +static void
> +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) {
> +	struct drm_crtc_state tmp_state;
> +
> +	/* Clear only the intel specific part of the crtc state */
> +	tmp_state = crtc_state->base;
> +	memset(crtc_state, 0, sizeof *crtc_state);
> +	crtc_state->base = tmp_state;
> +}
In scalers patch above function has an update to preserve
scaler_state. Hopefully your patch gets merged first then
scalers patch.

> +
> +static int
>  intel_modeset_pipe_config(struct drm_crtc *crtc,
>  			  struct drm_framebuffer *fb,
> -			  struct drm_display_mode *mode)
> +			  struct drm_display_mode *mode,
> +			  struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct intel_encoder *encoder;
> @@ -10358,17 +10395,19 @@ intel_modeset_pipe_config(struct drm_crtc
> *crtc,
> 
>  	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
>  		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
> 
>  	if (!check_digital_port_conflicts(dev)) {
>  		DRM_DEBUG_KMS("rejecting conflicting digital port
> configuration\n");
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
> 
> -	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> -	if (!pipe_config)
> -		return ERR_PTR(-ENOMEM);
> +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> +	if (IS_ERR(pipe_config))
> +		return PTR_ERR(pipe_config);
> +
> +	clear_intel_crtc_state(pipe_config);
> 
>  	pipe_config->base.crtc = crtc;
>  	drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -
> 10463,10 +10502,9 @@ encoder_retry:
>  	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
>  		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> 
> -	return pipe_config;
> +	return 0;
>  fail:
> -	kfree(pipe_config);
> -	return ERR_PTR(ret);
> +	return ret;
>  }
> 
>  /* Computes which crtcs are affected and sets the relevant bits in the mask. For
> @@ -11144,17 +11182,19 @@ static struct intel_crtc_state *
> intel_modeset_compute_config(struct drm_crtc *crtc,
>  			     struct drm_display_mode *mode,
>  			     struct drm_framebuffer *fb,
> +			     struct drm_atomic_state *state,
>  			     unsigned *modeset_pipes,
>  			     unsigned *prepare_pipes,
>  			     unsigned *disable_pipes)
>  {
>  	struct intel_crtc_state *pipe_config = NULL;
> +	int ret = 0;
> 
>  	intel_modeset_affected_pipes(crtc, modeset_pipes,
>  				     prepare_pipes, disable_pipes);
> 
>  	if ((*modeset_pipes) == 0)
> -		goto out;
> +		return NULL;
> 
>  	/*
>  	 * Note this needs changes when we start tracking multiple modes @@ -
> 11162,14 +11202,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
>  	 * (i.e. one pipe_config for each crtc) rather than just the one
>  	 * for this crtc.
>  	 */
> -	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
> -	if (IS_ERR(pipe_config)) {
> -		goto out;
> -	}
> +	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> +	if (IS_ERR(pipe_config))
> +		return pipe_config;
> +

Why don't intel_modeset_pipe_config() return pipe_config as it used to, 
instead of not returning and then calling intel_atomic_get_crtc_state()?

>  	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
>  			       "[modeset]");
> 
> -out:
>  	return pipe_config;
>  }
> 
> @@ -11214,6 +11257,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_display_mode *saved_mode;
> +	struct intel_crtc_state *crtc_state_copy = NULL;
>  	struct intel_crtc *intel_crtc;
>  	int ret = 0;
> 
> @@ -11221,6 +11265,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>  	if (!saved_mode)
>  		return -ENOMEM;
> 
> +	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
> +	if (!crtc_state_copy) {
> +		ret = -ENOMEM;
> +		goto done;
> +	}
> +
>  	*saved_mode = crtc->mode;
> 
>  	if (modeset_pipes)
> @@ -11307,6 +11357,22 @@ done:
>  	if (ret && crtc->state->enable)
>  		crtc->mode = *saved_mode;
> 
> +	if (ret == 0 && pipe_config) {
> +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
> +		/* The pipe_config will be freed with the atomic state, so
> +		 * make a copy. */
> +		memcpy(crtc_state_copy, intel_crtc->config,
> +		       sizeof *crtc_state_copy);
> +		intel_crtc->config = crtc_state_copy;
> +		intel_crtc->base.state = &crtc_state_copy->base;

Why don't you avoid creating a crtc_state_copy by not freeing intel_crtc->config
and copying pipe_config directly into intel_crtc->config?
This should be fine when drm atomic free function frees crtc_state inside drm_state.

Once atomic_crtc fully done, I guess this copy should go away
and swap of crtc_states should take care of this.

> +
> +		if (modeset_pipes)
> +			intel_crtc->new_config = intel_crtc->config;
> +	} else {
> +		kfree(crtc_state_copy);
> +	}
> +
>  	kfree(saved_mode);
>  	return ret;
>  }
> @@ -11332,27 +11398,81 @@ static int intel_set_mode_pipes(struct drm_crtc
> *crtc,
> 
>  static int intel_set_mode(struct drm_crtc *crtc,
>  			  struct drm_display_mode *mode,
> -			  int x, int y, struct drm_framebuffer *fb)
> +			  int x, int y, struct drm_framebuffer *fb,
> +			  struct drm_atomic_state *state)
>  {
>  	struct intel_crtc_state *pipe_config;
>  	unsigned modeset_pipes, prepare_pipes, disable_pipes;
> +	int ret = 0;
> 
> -	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
> +	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
>  						   &modeset_pipes,
>  						   &prepare_pipes,
>  						   &disable_pipes);
> 
> -	if (IS_ERR(pipe_config))
> -		return PTR_ERR(pipe_config);
> +	if (IS_ERR(pipe_config)) {
> +		ret = PTR_ERR(pipe_config);
> +		goto out;
> +	}
> +
> +	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> +				   modeset_pipes, prepare_pipes,
> +				   disable_pipes);
> +	if (ret)
> +		goto out;
> 
> -	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> -				    modeset_pipes, prepare_pipes,
> -				    disable_pipes);
> +out:
> +	return ret;
>  }
> 
>  void intel_crtc_restore_mode(struct drm_crtc *crtc)  {
> -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_atomic_state *state;
> +	struct intel_encoder *encoder;
> +	struct intel_connector *connector;
> +	struct drm_connector_state *connector_state;
> +
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state) {
> +		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of
> memory",
> +			      crtc->base.id);
> +		return;
> +	}
> +
> +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> +
> +	/* The force restore path in the HW readout code relies on the staged
> +	 * config still keeping the user requested config while the actual
> +	 * state has been overwritten by the configuration read from HW. We
> +	 * need to copy the staged config to the atomic state, otherwise the
> +	 * mode set will just reapply the state the HW is already in. */

We have discussed this in our call that
drm_connector->crtc (state read out from hw)
intel_encoder->new_crtc (that still has the old value)

but can you clarify why  below isn't 
required before?

> +	for_each_intel_encoder(dev, encoder) {
> +		if (&encoder->new_crtc->base != crtc)
> +			continue;
> +
> +		for_each_intel_connector(dev, connector) {
> +			if (connector->new_encoder != encoder)
> +				continue;
> +
> +			connector_state =
> drm_atomic_get_connector_state(state, &connector->base);
> +			if (IS_ERR(connector_state)) {
> +				DRM_DEBUG_KMS("Failed to add
> [CONNECTOR:%d:%s] to state: %ld\n",
> +					      connector->base.base.id,
> +					      connector->base.name,
> +					      PTR_ERR(connector_state));
> +				continue;
> +			}
> +
> +			connector_state->crtc = crtc;
> +			connector_state->best_encoder = &encoder->base;
> +		}
> +	}
> +
> +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
> +		       state);
> +
> +	drm_atomic_state_free(state);
>  }
> 
>  #undef for_each_intel_crtc_masked
> @@ -11677,6 +11797,7 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)  {
>  	struct drm_device *dev;
>  	struct drm_mode_set save_set;
> +	struct drm_atomic_state *state = NULL;
>  	struct intel_set_config *config;
>  	struct intel_crtc_state *pipe_config;
>  	unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11721,12
> +11842,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
>  	 * such cases. */
>  	intel_set_config_compute_mode_changes(set, config);
> 
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state) {
> +		ret = -ENOMEM;
> +		goto out_config;
> +	}
> +
> +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> +
>  	ret = intel_modeset_stage_output_state(dev, set, config);
>  	if (ret)
>  		goto fail;
> 
>  	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
> -						   set->fb,
> +						   set->fb, state,
>  						   &modeset_pipes,
>  						   &prepare_pipes,
>  						   &disable_pipes);
> @@ -11746,10 +11875,6 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)
>  		 */
>  	}
> 
> -	/* set_mode will free it in the mode_changed case */
> -	if (!config->mode_changed)
> -		kfree(pipe_config);
> -
>  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> 
>  	if (config->mode_changed) {
> @@ -11795,6 +11920,8 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)
>  fail:
>  		intel_set_config_restore_state(dev, config);
> 
> +		drm_atomic_state_clear(state);
> +
>  		/*
>  		 * HACK: if the pipe was on, but we didn't have a framebuffer,
>  		 * force the pipe off to avoid oopsing in the modeset code @@
> -11807,11 +11934,15 @@ fail:
>  		/* Try to restore the config */
>  		if (config->mode_changed &&
>  		    intel_set_mode(save_set.crtc, save_set.mode,
> -				   save_set.x, save_set.y, save_set.fb))
> +				   save_set.x, save_set.y, save_set.fb,
> +				   state))
>  			DRM_ERROR("failed to restore config after modeset
> failure\n");
>  	}
> 
>  out_config:
> +	if (state)
> +		drm_atomic_state_free(state);
> +
>  	intel_set_config_free(config);
>  	return ret;
>  }
> @@ -13852,8 +13983,7 @@ void intel_modeset_setup_hw_state(struct
> drm_device *dev,
>  			struct drm_crtc *crtc =
>  				dev_priv->pipe_to_crtc_mapping[pipe];
> 
> -			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> -				       crtc->primary->fb);
> +			intel_crtc_restore_mode(crtc);
I see you are using intel_crtc_restore_mode instead of intel_set_mode()
to acquire 
In the code there is comment before above hunk:
        /*
         * We need to use raw interfaces for restoring state to avoid
         * checking (bogus) intermediate states.
         */
May be this needs some refinement.

>  		}
>  	} else {
>  		intel_modeset_update_staged_output_state(dev);
> --
> 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] 52+ messages in thread

* Re: [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config()
  2015-03-13  9:48 ` [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config() Ander Conselvan de Oliveira
@ 2015-03-19  0:44   ` Konduru, Chandra
  2015-03-19  7:52     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19  0:44 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx


> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in
> intel_modeset_pipe_config()
> 
> Move towards atomic by using the legacy modeset's drm_atomic_state instead.
> 
> v2: Move call to drm_atomic_add_affected_connectors() to
>     intel_modeset_compute_config(). (Daniel)
> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 6465f6d..1609628 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10435,8 +10435,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> {
>  	struct drm_device *dev = crtc->dev;
>  	struct intel_encoder *encoder;
> +	struct intel_connector *connector;
> +	struct drm_connector_state *connector_state;
>  	struct intel_crtc_state *pipe_config;
>  	int plane_bpp, ret = -EINVAL;
> +	int i;
>  	bool retry = true;
> 
>  	if (!check_encoder_cloning(to_intel_crtc(crtc))) { @@ -10510,11
> +10513,17 @@ encoder_retry:
>  	 * adjust it according to limitations or connector properties, and also
>  	 * a chance to reject the mode entirely.
>  	 */
> -	for_each_intel_encoder(dev, encoder) {
> +	for (i = 0; i < state->num_connector; i++) {
> +		connector = to_intel_connector(state->connectors[i]);
> +		if (!connector)
> +			continue;
> 
> -		if (&encoder->new_crtc->base != crtc)
> +		connector_state = state->connector_states[i];
> +		if (connector_state->crtc != crtc)
>  			continue;
> 
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +
>  		if (!(encoder->compute_config(encoder, pipe_config))) {
>  			DRM_DEBUG_KMS("Encoder config failure\n");
>  			goto fail;
> @@ -11238,6 +11247,10 @@ intel_modeset_compute_config(struct drm_crtc
> *crtc,
>  	struct intel_crtc *intel_crtc;
>  	int ret = 0;
> 
> +	ret = drm_atomic_add_affected_connectors(state, crtc);

If the current transaction is started by DRM core, above operation 
will be added by core, right?
And when we move to full atomic_modeset, then above needs
to be deleted?

> +	if (ret)
> +		return ERR_PTR(ret);
> +
>  	intel_modeset_affected_pipes(crtc, modeset_pipes,
>  				     prepare_pipes, disable_pipes);
> 
> --
> 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] 52+ messages in thread

* Re: [PATCH v4] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-18 23:57       ` Konduru, Chandra
@ 2015-03-19  7:50         ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-19  7:50 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Wed, 2015-03-18 at 23:57 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Wednesday, March 18, 2015 12:57 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH v4] drm/i915: Allocate a drm_atomic_state for the legacy
> > modeset code
> > 
> > For the atomic conversion, the mode set paths need to be changed to rely on an
> > atomic state instead of using the staged config. By using an atomic state for the
> > legacy code, we will be able to convert the code base in small chunks.
> > 
> > v2: Squash patch that adds stat argument to intel_set_mode(). (Ander)
> >     Make every caller of intel_set_mode() allocate state. (Daniel)
> >     Call drm_atomic_state_clear() in set config's error path. (Daniel)
> > 
> > v3: Copy staged config to atomic state in force restore path. (Ander)
> > 
> > v4: Don't update ->new_config for disabled pipes in __intel_set_mode(),
> >     since it is expected to be NULL in that case. (Ander)
> 
> Can you clarify why it is expected to be NULL?

This is part of the sanity checking implemented when the
intel_crtc->new_config pointer was introduced. If I understand
correctly, the idea was to reduce the usage of that pointer to only the
brief moment when it pointed at something different than the current
config. That way, if some piece of code relied on that pointer outside
of modeset, it would be easier to catch that bug.

> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 200 +++++++++++++++++++++++++++++-
> > -----
> >  1 file changed, 165 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 8458bf5..ce35647 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -83,7 +83,8 @@ 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_display_mode
> > *mode,
> > -			  int x, int y, struct drm_framebuffer *old_fb);
> > +			  int x, int y, struct drm_framebuffer *old_fb,
> > +			  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, @@
> > -8802,6 +8803,7 @@ bool intel_get_load_detect_pipe(struct drm_connector
> > *connector,
> >  	struct drm_device *dev = encoder->dev;
> >  	struct drm_framebuffer *fb;
> >  	struct drm_mode_config *config = &dev->mode_config;
> > +	struct drm_atomic_state *state = NULL;
> >  	int ret, i = -1;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> > -8883,6 +8885,12 @@ retry:
> >  	old->load_detect_temp = true;
> >  	old->release_fb = NULL;
> > 
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state)
> > +		return false;
> > +
> > +	state->acquire_ctx = ctx;
> > +
> >  	if (!mode)
> >  		mode = &load_detect_mode;
> > 
> > @@ -8905,7 +8913,7 @@ retry:
> >  		goto fail;
> >  	}
> > 
> > -	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
> > +	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
> > @@ -8924,6 +8932,11 @@ retry:
> >  	else
> >  		intel_crtc->new_config = NULL;
> >  fail_unlock:
> > +	if (state) {
> > +		drm_atomic_state_free(state);
> > +		state = NULL;
> > +	}
> > +
> >  	if (ret == -EDEADLK) {
> >  		drm_modeset_backoff(ctx);
> >  		goto retry;
> > @@ -8936,22 +8949,34 @@ void intel_release_load_detect_pipe(struct
> > drm_connector *connector,
> >  				    struct intel_load_detect_pipe *old,
> >  				    struct drm_modeset_acquire_ctx *ctx)  {
> > +	struct drm_device *dev = connector->dev;
> >  	struct intel_encoder *intel_encoder =
> >  		intel_attached_encoder(connector);
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> >  	struct drm_crtc *crtc = encoder->crtc;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct drm_atomic_state *state;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
> >  		      connector->base.id, connector->name,
> >  		      encoder->base.id, encoder->name);
> > 
> >  	if (old->load_detect_temp) {
> > +		state = drm_atomic_state_alloc(dev);
> > +		if (!state) {
> > +			DRM_DEBUG_KMS("can't release load detect pipe\n");
> > +			return;
> > +		}
> > +
> > +		state->acquire_ctx = ctx;
> > +
> >  		to_intel_connector(connector)->new_encoder = NULL;
> >  		intel_encoder->new_crtc = NULL;
> >  		intel_crtc->new_enabled = false;
> >  		intel_crtc->new_config = NULL;
> > -		intel_set_mode(crtc, NULL, 0, 0, NULL);
> > +		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> > +
> > +		drm_atomic_state_free(state);
> > 
> >  		if (old->release_fb) {
> >  			drm_framebuffer_unregister_private(old->release_fb);
> > @@ -10345,10 +10370,22 @@ static bool check_digital_port_conflicts(struct
> > drm_device *dev)
> >  	return true;
> >  }
> > 
> > -static struct intel_crtc_state *
> > +static void
> > +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) {
> > +	struct drm_crtc_state tmp_state;
> > +
> > +	/* Clear only the intel specific part of the crtc state */
> > +	tmp_state = crtc_state->base;
> > +	memset(crtc_state, 0, sizeof *crtc_state);
> > +	crtc_state->base = tmp_state;
> > +}
> In scalers patch above function has an update to preserve
> scaler_state. Hopefully your patch gets merged first then
> scalers patch.
> 
> > +
> > +static int
> >  intel_modeset_pipe_config(struct drm_crtc *crtc,
> >  			  struct drm_framebuffer *fb,
> > -			  struct drm_display_mode *mode)
> > +			  struct drm_display_mode *mode,
> > +			  struct drm_atomic_state *state)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct intel_encoder *encoder;
> > @@ -10358,17 +10395,19 @@ intel_modeset_pipe_config(struct drm_crtc
> > *crtc,
> > 
> >  	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
> >  		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> > -		return ERR_PTR(-EINVAL);
> > +		return -EINVAL;
> >  	}
> > 
> >  	if (!check_digital_port_conflicts(dev)) {
> >  		DRM_DEBUG_KMS("rejecting conflicting digital port
> > configuration\n");
> > -		return ERR_PTR(-EINVAL);
> > +		return -EINVAL;
> >  	}
> > 
> > -	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> > -	if (!pipe_config)
> > -		return ERR_PTR(-ENOMEM);
> > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > +	if (IS_ERR(pipe_config))
> > +		return PTR_ERR(pipe_config);
> > +
> > +	clear_intel_crtc_state(pipe_config);
> > 
> >  	pipe_config->base.crtc = crtc;
> >  	drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -
> > 10463,10 +10502,9 @@ encoder_retry:
> >  	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
> >  		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> > 
> > -	return pipe_config;
> > +	return 0;
> >  fail:
> > -	kfree(pipe_config);
> > -	return ERR_PTR(ret);
> > +	return ret;
> >  }
> > 
> >  /* Computes which crtcs are affected and sets the relevant bits in the mask. For
> > @@ -11144,17 +11182,19 @@ static struct intel_crtc_state *
> > intel_modeset_compute_config(struct drm_crtc *crtc,
> >  			     struct drm_display_mode *mode,
> >  			     struct drm_framebuffer *fb,
> > +			     struct drm_atomic_state *state,
> >  			     unsigned *modeset_pipes,
> >  			     unsigned *prepare_pipes,
> >  			     unsigned *disable_pipes)
> >  {
> >  	struct intel_crtc_state *pipe_config = NULL;
> > +	int ret = 0;
> > 
> >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> >  				     prepare_pipes, disable_pipes);
> > 
> >  	if ((*modeset_pipes) == 0)
> > -		goto out;
> > +		return NULL;
> > 
> >  	/*
> >  	 * Note this needs changes when we start tracking multiple modes @@ -
> > 11162,14 +11202,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
> >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> >  	 * for this crtc.
> >  	 */
> > -	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
> > -	if (IS_ERR(pipe_config)) {
> > -		goto out;
> > -	}
> > +	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > +	if (ret)
> > +		return ERR_PTR(ret);
> > +
> > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > +	if (IS_ERR(pipe_config))
> > +		return pipe_config;
> > +
> 
> Why don't intel_modeset_pipe_config() return pipe_config as it used to, 
> instead of not returning and then calling intel_atomic_get_crtc_state()?

No particular reason. I think it made sense at some intermediate design
step, and I just left it like that.

> >  	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> >  			       "[modeset]");
> > 
> > -out:
> >  	return pipe_config;
> >  }
> > 
> > @@ -11214,6 +11257,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_display_mode *saved_mode;
> > +	struct intel_crtc_state *crtc_state_copy = NULL;
> >  	struct intel_crtc *intel_crtc;
> >  	int ret = 0;
> > 
> > @@ -11221,6 +11265,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  	if (!saved_mode)
> >  		return -ENOMEM;
> > 
> > +	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
> > +	if (!crtc_state_copy) {
> > +		ret = -ENOMEM;
> > +		goto done;
> > +	}
> > +
> >  	*saved_mode = crtc->mode;
> > 
> >  	if (modeset_pipes)
> > @@ -11307,6 +11357,22 @@ done:
> >  	if (ret && crtc->state->enable)
> >  		crtc->mode = *saved_mode;
> > 
> > +	if (ret == 0 && pipe_config) {
> > +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +
> > +		/* The pipe_config will be freed with the atomic state, so
> > +		 * make a copy. */
> > +		memcpy(crtc_state_copy, intel_crtc->config,
> > +		       sizeof *crtc_state_copy);
> > +		intel_crtc->config = crtc_state_copy;
> > +		intel_crtc->base.state = &crtc_state_copy->base;
> 
> Why don't you avoid creating a crtc_state_copy by not freeing intel_crtc->config
> and copying pipe_config directly into intel_crtc->config?
> This should be fine when drm atomic free function frees crtc_state inside drm_state.

Except that intel_crtc->new_config will still point to the freed
pipe_config, so we would have to add logic to fix that too. And on patch
4 make sure the pipe_config is updated even if modeset_pipes is 0.

Since what in the end what we really want is to have a simple swap, I
rather avoid extra churn here, perfecting code that is going to be
deleted.

> Once atomic_crtc fully done, I guess this copy should go away
> and swap of crtc_states should take care of this.
> 
> > +
> > +		if (modeset_pipes)
> > +			intel_crtc->new_config = intel_crtc->config;
> > +	} else {
> > +		kfree(crtc_state_copy);
> > +	}
> > +
> >  	kfree(saved_mode);
> >  	return ret;
> >  }
> > @@ -11332,27 +11398,81 @@ static int intel_set_mode_pipes(struct drm_crtc
> > *crtc,
> > 
> >  static int intel_set_mode(struct drm_crtc *crtc,
> >  			  struct drm_display_mode *mode,
> > -			  int x, int y, struct drm_framebuffer *fb)
> > +			  int x, int y, struct drm_framebuffer *fb,
> > +			  struct drm_atomic_state *state)
> >  {
> >  	struct intel_crtc_state *pipe_config;
> >  	unsigned modeset_pipes, prepare_pipes, disable_pipes;
> > +	int ret = 0;
> > 
> > -	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
> > +	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
> >  						   &modeset_pipes,
> >  						   &prepare_pipes,
> >  						   &disable_pipes);
> > 
> > -	if (IS_ERR(pipe_config))
> > -		return PTR_ERR(pipe_config);
> > +	if (IS_ERR(pipe_config)) {
> > +		ret = PTR_ERR(pipe_config);
> > +		goto out;
> > +	}
> > +
> > +	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > +				   modeset_pipes, prepare_pipes,
> > +				   disable_pipes);
> > +	if (ret)
> > +		goto out;
> > 
> > -	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > -				    modeset_pipes, prepare_pipes,
> > -				    disable_pipes);
> > +out:
> > +	return ret;
> >  }
> > 
> >  void intel_crtc_restore_mode(struct drm_crtc *crtc)  {
> > -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_atomic_state *state;
> > +	struct intel_encoder *encoder;
> > +	struct intel_connector *connector;
> > +	struct drm_connector_state *connector_state;
> > +
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state) {
> > +		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of
> > memory",
> > +			      crtc->base.id);
> > +		return;
> > +	}
> > +
> > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > +
> > +	/* The force restore path in the HW readout code relies on the staged
> > +	 * config still keeping the user requested config while the actual
> > +	 * state has been overwritten by the configuration read from HW. We
> > +	 * need to copy the staged config to the atomic state, otherwise the
> > +	 * mode set will just reapply the state the HW is already in. */
> 
> We have discussed this in our call that
> drm_connector->crtc (state read out from hw)
> intel_encoder->new_crtc (that still has the old value)
> 
> but can you clarify why  below isn't 
> required before?

Before this patch series, the mode set code relies on the staged config,
i.e., intel_crtc->new_enable, intel_connector->new_encoder and
intel_encoder->new_crtc. These values are not changed during HW state
read out. After the series, the same code will look at the crtc and
connector states it gets from the drm_atomic_state.

The atomic state used for this mode set call was just allocated above.
Since the HW readout state replaces the current state
(drm_crtc->enabled; drm_connector->encoder; drm_encoder->crtc), the end
result is that any call to drm_atomic_get_{crtc,connector}_state will
use the *current HW state*. We want to write the old state (the state
requested by the user) to the drm_atomic_struct, so that after this the
HW state is the same as the old user requested state.

> > +	for_each_intel_encoder(dev, encoder) {
> > +		if (&encoder->new_crtc->base != crtc)
> > +			continue;
> > +
> > +		for_each_intel_connector(dev, connector) {
> > +			if (connector->new_encoder != encoder)
> > +				continue;
> > +
> > +			connector_state =
> > drm_atomic_get_connector_state(state, &connector->base);
> > +			if (IS_ERR(connector_state)) {
> > +				DRM_DEBUG_KMS("Failed to add
> > [CONNECTOR:%d:%s] to state: %ld\n",
> > +					      connector->base.base.id,
> > +					      connector->base.name,
> > +					      PTR_ERR(connector_state));
> > +				continue;
> > +			}
> > +
> > +			connector_state->crtc = crtc;
> > +			connector_state->best_encoder = &encoder->base;
> > +		}
> > +	}
> > +
> > +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
> > +		       state);
> > +
> > +	drm_atomic_state_free(state);
> >  }
> > 
> >  #undef for_each_intel_crtc_masked
> > @@ -11677,6 +11797,7 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)  {
> >  	struct drm_device *dev;
> >  	struct drm_mode_set save_set;
> > +	struct drm_atomic_state *state = NULL;
> >  	struct intel_set_config *config;
> >  	struct intel_crtc_state *pipe_config;
> >  	unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11721,12
> > +11842,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
> >  	 * such cases. */
> >  	intel_set_config_compute_mode_changes(set, config);
> > 
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state) {
> > +		ret = -ENOMEM;
> > +		goto out_config;
> > +	}
> > +
> > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > +
> >  	ret = intel_modeset_stage_output_state(dev, set, config);
> >  	if (ret)
> >  		goto fail;
> > 
> >  	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
> > -						   set->fb,
> > +						   set->fb, state,
> >  						   &modeset_pipes,
> >  						   &prepare_pipes,
> >  						   &disable_pipes);
> > @@ -11746,10 +11875,6 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)
> >  		 */
> >  	}
> > 
> > -	/* set_mode will free it in the mode_changed case */
> > -	if (!config->mode_changed)
> > -		kfree(pipe_config);
> > -
> >  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> > 
> >  	if (config->mode_changed) {
> > @@ -11795,6 +11920,8 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)
> >  fail:
> >  		intel_set_config_restore_state(dev, config);
> > 
> > +		drm_atomic_state_clear(state);
> > +
> >  		/*
> >  		 * HACK: if the pipe was on, but we didn't have a framebuffer,
> >  		 * force the pipe off to avoid oopsing in the modeset code @@
> > -11807,11 +11934,15 @@ fail:
> >  		/* Try to restore the config */
> >  		if (config->mode_changed &&
> >  		    intel_set_mode(save_set.crtc, save_set.mode,
> > -				   save_set.x, save_set.y, save_set.fb))
> > +				   save_set.x, save_set.y, save_set.fb,
> > +				   state))
> >  			DRM_ERROR("failed to restore config after modeset
> > failure\n");
> >  	}
> > 
> >  out_config:
> > +	if (state)
> > +		drm_atomic_state_free(state);
> > +
> >  	intel_set_config_free(config);
> >  	return ret;
> >  }
> > @@ -13852,8 +13983,7 @@ void intel_modeset_setup_hw_state(struct
> > drm_device *dev,
> >  			struct drm_crtc *crtc =
> >  				dev_priv->pipe_to_crtc_mapping[pipe];
> > 
> > -			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> > -				       crtc->primary->fb);
> > +			intel_crtc_restore_mode(crtc);
> I see you are using intel_crtc_restore_mode instead of intel_set_mode()
> to acquire 
> In the code there is comment before above hunk:
>         /*
>          * We need to use raw interfaces for restoring state to avoid
>          * checking (bogus) intermediate states.
>          */
> May be this needs some refinement.

We have a separate task to convert this part of the code to atomic. Once
that is done, at this point we'll read the HW state into a
drm_atomic_struct and swap that with the current state. Then, we'll do
an atomic mode set with the swapped out state. This is just an
intermediary step to let us begin the conversion without breaking
things.

Ander

> >  		}
> >  	} else {
> >  		intel_modeset_update_staged_output_state(dev);
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
       [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B41B@fmsmsx101.amr.corp.intel.com>
@ 2015-03-19  7:52     ` Ander Conselvan De Oliveira
  2015-03-19 23:23       ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-19  7:52 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 00:12 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is
> > being disabled
> > 
> > For consistency, allocate a new crtc_state for a crtc that is being disabled.
> > Previously only the enabled value of the current state would change.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 36 +++++++++++++++++++++++++--------
> > ---
> >  1 file changed, 25 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index b61e3f6..62b9021 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -11188,14 +11188,21 @@ intel_modeset_compute_config(struct drm_crtc
> > *crtc,
> >  			     unsigned *prepare_pipes,
> >  			     unsigned *disable_pipes)
> >  {
> > +	struct drm_device *dev = crtc->dev;
> >  	struct intel_crtc_state *pipe_config = NULL;
> > +	struct intel_crtc *intel_crtc;
> >  	int ret = 0;
> > 
> >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> >  				     prepare_pipes, disable_pipes);
> > 
> > -	if ((*modeset_pipes) == 0)
> > -		return NULL;
> > +	for_each_intel_crtc_masked(dev, *disable_pipes, intel_crtc) {
> > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > +		if (IS_ERR(pipe_config))
> > +			return pipe_config;
> > +
> > +		pipe_config->base.enable = false;
> > +	}
> > 
> >  	/*
> >  	 * Note this needs changes when we start tracking multiple modes @@ -
> > 11203,18 +11210,25 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
> >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> >  	 * for this crtc.
> >  	 */
> > -	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > -	if (ret)
> > -		return ERR_PTR(ret);
> > +	for_each_intel_crtc_masked(dev, *modeset_pipes, intel_crtc) {
> > +		/* FIXME: For now we still expect modeset_pipes has at most
> > +		 * one bit set. */
> > +		if (WARN_ON(&intel_crtc->base != crtc))
> > +			continue;
> > 
> > -	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > -	if (IS_ERR(pipe_config))
> > -		return pipe_config;
> > +		ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > +		if (ret)
> > +			return ERR_PTR(ret);
> > +
> > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > +		if (IS_ERR(pipe_config))
> > +			return pipe_config;
> > 
> > -	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > -			       "[modeset]");
> > +		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > +				       "[modeset]");
> > +	}
> > 
> > -	return pipe_config;
> > +	return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> >  }
> 
> Instead of calling 3 separate intel_atomic_get_crtc_state()
> Can you have something like:
> intel_modeset_compute_config()
> {
> 	pipe_config = intel_atomic_get_crtc_state(state, crtc);
> 
> 	for each disabled pipe {
> 		use pipe_config;
> 	}
> 	
> 	for each mode_set pipe {
> 		use pipe_config;
> 	}
> 
> 	return pipe_config;
> }
> 
> 
> Or the way currently done is to cover where disable_pipes != modeset_pipes?
> By the way, when can it happen?

Yep, disable_pipes can be different than modeset_pipes if we the mode
set "steals" a connector. For instance, we could have pipe A driving
HDMI-1 and then mode set to pipe B to drive HDMI-1. Pipe B will steal
the encoder from pipe A, and cause it to be disable. In that case
disable_pipes will have the bit for pipe A set, while modeset_pipes will
have the bit for pipe B set.


Ander

> 
> > 
> >  static int __intel_set_mode_setup_plls(struct drm_device *dev,
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state
       [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B6F0@fmsmsx101.amr.corp.intel.com>
@ 2015-03-19  7:52     ` Ander Conselvan De Oliveira
  2015-03-19 15:15       ` Daniel Vetter
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-19  7:52 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 00:38 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 07/19] drm/i915: Copy the staged connector config to the
> > legacy atomic state
> > 
> > With this in place, we can start converting pieces of the modeset code to look at
> > the connector atomic state instead of the staged config.
> > 
> > v2: Handle the load detect staged config changes too. (Ander)
> >     Remove unnecessary blank line. (Daniel)
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 52
> > +++++++++++++++++++++++++++++++-----
> >  1 file changed, 45 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index abdbd0c..6465f6d 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -8805,6 +8805,7 @@ bool intel_get_load_detect_pipe(struct
> > drm_connector *connector,
> >  	struct drm_framebuffer *fb;
> >  	struct drm_mode_config *config = &dev->mode_config;
> >  	struct drm_atomic_state *state = NULL;
> > +	struct drm_connector_state *connector_state;
> >  	int ret, i = -1;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> > -8892,6 +8893,15 @@ retry:
> > 
> >  	state->acquire_ctx = ctx;
> > 
> > +	connector_state = drm_atomic_get_connector_state(state, connector);
> > +	if (IS_ERR(connector_state)) {
> > +		ret = PTR_ERR(connector_state);
> > +		goto fail;
> > +	}
> > +
> > +	connector_state->crtc = crtc;
> > +	connector_state->best_encoder = &intel_encoder->base;
> > +
> >  	if (!mode)
> >  		mode = &load_detect_mode;
> > 
> > @@ -8957,6 +8967,7 @@ void intel_release_load_detect_pipe(struct
> > drm_connector *connector,
> >  	struct drm_crtc *crtc = encoder->crtc;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >  	struct drm_atomic_state *state;
> > +	struct drm_connector_state *connector_state;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
> >  		      connector->base.id, connector->name, @@ -8964,17
> > +8975,23 @@ void intel_release_load_detect_pipe(struct drm_connector
> > *connector,
> > 
> >  	if (old->load_detect_temp) {
> >  		state = drm_atomic_state_alloc(dev);
> > -		if (!state) {
> > -			DRM_DEBUG_KMS("can't release load detect pipe\n");
> > -			return;
> > -		}
> > +		if (!state)
> > +			goto fail;
> 
> Is the above deletion of lines from code added by another patch in this series or
> from a different series? May be you can squash them into one.

That was added in patch 3, the one that adds the drm_atomic_state
parameter to intel_set_mode(). I chose to do it that way in order to not
complicate that patch unnecessarily. It wasn't possible to convert each
different call to intel_set_mode() separately, since that would create a
state of breakage that prevents bisecting.

So the approach I found most reasonable was to just add the state
parameter in patch number 3, and leave the proper population of the
atomic state to a separate patch. The main idea was to simplify the
review process.

> 
> > 
> >  		state->acquire_ctx = ctx;
> > 
> > +		connector_state = drm_atomic_get_connector_state(state,
> > connector);
> > +		if (IS_ERR(connector_state))
> > +			goto fail;
> > +
> >  		to_intel_connector(connector)->new_encoder = NULL;
> >  		intel_encoder->new_crtc = NULL;
> >  		intel_crtc->new_enabled = false;
> >  		intel_crtc->new_config = NULL;
> > +
> > +		connector_state->best_encoder = NULL;
> > +		connector_state->crtc = NULL;
> > +
> >  		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> > 
> >  		drm_atomic_state_free(state);
> > @@ -8990,6 +9007,11 @@ void intel_release_load_detect_pipe(struct
> > drm_connector *connector,
> >  	/* Switch crtc and encoder back off if necessary */
> >  	if (old->dpms_mode != DRM_MODE_DPMS_ON)
> >  		connector->funcs->dpms(connector, old->dpms_mode);
> > +
> > +	return;
> > +fail:
> > +	DRM_DEBUG_KMS("Couldn't release load detect pipe.\n");
> > +	drm_atomic_state_free(state);
> >  }
> 
> Learning while reviewing connector/encoder side of handling.
> But I think someone also should look at the encoder/connector side or 
> atomic handling.

I think Daniel already did a high level review of this. Perhaps he could
do it again for v2 of this patch.

Ander

> > 
> >  static int i9xx_pll_refclk(struct drm_device *dev, @@ -11646,9 +11668,11 @@
> > intel_set_config_compute_mode_changes(struct drm_mode_set *set,  static int
> > intel_modeset_stage_output_state(struct drm_device *dev,
> >  				 struct drm_mode_set *set,
> > -				 struct intel_set_config *config)
> > +				 struct intel_set_config *config,
> > +				 struct drm_atomic_state *state)
> >  {
> >  	struct intel_connector *connector;
> > +	struct drm_connector_state *connector_state;
> >  	struct intel_encoder *encoder;
> >  	struct intel_crtc *crtc;
> >  	int ro;
> > @@ -11712,6 +11736,14 @@ intel_modeset_stage_output_state(struct
> > drm_device *dev,
> >  		}
> >  		connector->new_encoder->new_crtc = to_intel_crtc(new_crtc);
> > 
> > +		connector_state =
> > +			drm_atomic_get_connector_state(state, &connector-
> > >base);
> > +		if (IS_ERR(connector_state))
> > +			return PTR_ERR(connector_state);
> > +
> > +		connector_state->crtc = new_crtc;
> > +		connector_state->best_encoder = &connector->new_encoder-
> > >base;
> > +
> >  		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n",
> >  			connector->base.base.id,
> >  			connector->base.name,
> > @@ -11744,9 +11776,15 @@ intel_modeset_stage_output_state(struct
> > drm_device *dev,
> >  	}
> >  	/* Now we've also updated encoder->new_crtc for all encoders. */
> >  	for_each_intel_connector(dev, connector) {
> > -		if (connector->new_encoder)
> > +		connector_state =
> > +			drm_atomic_get_connector_state(state, &connector-
> > >base);
> > +
> > +		if (connector->new_encoder) {
> >  			if (connector->new_encoder != connector->encoder)
> >  				connector->encoder = connector-
> > >new_encoder;
> > +		} else {
> > +			connector_state->crtc = NULL;
> > +		}
> >  	}
> >  	for_each_intel_crtc(dev, crtc) {
> >  		crtc->new_enabled = false;
> > @@ -11855,7 +11893,7 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)
> > 
> >  	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > 
> > -	ret = intel_modeset_stage_output_state(dev, set, config);
> > +	ret = intel_modeset_stage_output_state(dev, set, config, state);
> >  	if (ret)
> >  		goto fail;
> > 
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config()
  2015-03-19  0:44   ` Konduru, Chandra
@ 2015-03-19  7:52     ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-19  7:52 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 00:44 +0000, Konduru, Chandra wrote:
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in
> > intel_modeset_pipe_config()
> > 
> > Move towards atomic by using the legacy modeset's drm_atomic_state instead.
> > 
> > v2: Move call to drm_atomic_add_affected_connectors() to
> >     intel_modeset_compute_config(). (Daniel)
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++--
> >  1 file changed, 15 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 6465f6d..1609628 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10435,8 +10435,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> > {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct intel_encoder *encoder;
> > +	struct intel_connector *connector;
> > +	struct drm_connector_state *connector_state;
> >  	struct intel_crtc_state *pipe_config;
> >  	int plane_bpp, ret = -EINVAL;
> > +	int i;
> >  	bool retry = true;
> > 
> >  	if (!check_encoder_cloning(to_intel_crtc(crtc))) { @@ -10510,11
> > +10513,17 @@ encoder_retry:
> >  	 * adjust it according to limitations or connector properties, and also
> >  	 * a chance to reject the mode entirely.
> >  	 */
> > -	for_each_intel_encoder(dev, encoder) {
> > +	for (i = 0; i < state->num_connector; i++) {
> > +		connector = to_intel_connector(state->connectors[i]);
> > +		if (!connector)
> > +			continue;
> > 
> > -		if (&encoder->new_crtc->base != crtc)
> > +		connector_state = state->connector_states[i];
> > +		if (connector_state->crtc != crtc)
> >  			continue;
> > 
> > +		encoder = to_intel_encoder(connector_state->best_encoder);
> > +
> >  		if (!(encoder->compute_config(encoder, pipe_config))) {
> >  			DRM_DEBUG_KMS("Encoder config failure\n");
> >  			goto fail;
> > @@ -11238,6 +11247,10 @@ intel_modeset_compute_config(struct drm_crtc
> > *crtc,
> >  	struct intel_crtc *intel_crtc;
> >  	int ret = 0;
> > 
> > +	ret = drm_atomic_add_affected_connectors(state, crtc);
> 
> If the current transaction is started by DRM core, above operation 
> will be added by core, right?
> And when we move to full atomic_modeset, then above needs
> to be deleted?

That call is done in drm_atomic_helper_check_modeset(), so after the
conversion, we won't need this call there. But calling it twice doesn't
have any ill-effects, so we can leave it there until this is all sorted
out.

Ander


> 
> > +	if (ret)
> > +		return ERR_PTR(ret);
> > +
> >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> >  				     prepare_pipes, disable_pipes);
> > 
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state
  2015-03-19  7:52     ` Ander Conselvan De Oliveira
@ 2015-03-19 15:15       ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2015-03-19 15:15 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx

On Thu, Mar 19, 2015 at 09:52:08AM +0200, Ander Conselvan De Oliveira wrote:
> On Thu, 2015-03-19 at 00:38 +0000, Konduru, Chandra wrote:
> > Learning while reviewing connector/encoder side of handling.
> > But I think someone also should look at the encoder/connector side or 
> > atomic handling.
> 
> I think Daniel already did a high level review of this. Perhaps he could
> do it again for v2 of this patch.

We have a massive pile of JIRA's to fix up interactions between
connectors/encoders and the new atomic code. And I think Ander's patches
here won't cause trouble. So I think we're good for now.

Of course this being atomic there will be some surprises ...
-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] 52+ messages in thread

* Re: [PATCH v2 00/19] Remove depencies on staged config for atomic transition
  2015-03-18 23:57 ` [PATCH v2 00/19] Remove depencies on staged config for atomic transition Konduru, Chandra
@ 2015-03-19 15:20   ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2015-03-19 15:20 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: Conselvan De Oliveira, Ander, intel-gfx

On Wed, Mar 18, 2015 at 11:57:19PM +0000, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH v2 00/19] Remove depencies on staged config for atomic
> > transition
> > 
> > Here's v2 with most of the comments from Daniel addressed. I didn't change the
> > zeroing of the crtc_state to the duplicate state function, since it causes
> > problems when we add the state of a crtc that isn't going through a modeset.
> > Specifically, this would cause the code that decides whether pipes B and C can
> > be enabled at the same time to fail, since the number of fdi lanes would be zero.
> > 
> > The other concerns I raised with v1 are also addressed. I tested this on
> > IVYBRIDGE using pipes B & C, and the load detect code path using Daniel's patch
> > that adds the i915.load_detect_test parameter.
> 
> Had a chat with Ander to get an overview of his patches. It is helping to 
> review the patches. There are still couple questions, so will ask for
> clarifications as I go through the changes. 
> 
> Also got clarified that this patch series is moving in direction for atomic_crtc
> but more work needs to be done to separate out check path, swap states
> then commit path. And hook these check and commit paths into 
> intel_atomic_check/commit functions.
> 
> Also any resources involved in doing internally induced set_mode, 
> update_plane needs to be added to incoming nuclear/atomic transaction.
> I think this is one of the major todo. In that process need find way to
> avoid nested atomic transactions. Also complications can arise if the 
> transaction already has crtc state to do a mode change, and requires 
> another set mode to do load detect. In these type of scenarios, suspend
> calling nuclear transaction and start a freshone? Or do both at same time.
> It is not clear how this can be done. Probably Daniel has some ideas
> to overcome these.
> 
> Current nightly has .update_plane pointing to helper upate instead of 
> atomic_helper_update to avoid nested atomic.

Yeah nested atomic is no-go, so we need to rework that code. Ville has a
few patches in-flight already. Atm we don't have nested atomic sessions,
so this shouldn't be a concern.
-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] 52+ messages in thread

* Re: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using atomic state
  2015-03-13  9:49 ` [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to " Ander Conselvan de Oliveira
@ 2015-03-19 19:24   ` Konduru, Chandra
  2015-03-20  6:28     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 19:24 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using
> atomic state
> 
> Pass a crtc_state to it and find whether the pipe has an encoder of a given type
> by looking at the drm_atomic_state the crtc_state points to.
> 
> Until recently i9xx_get_refclk() used to be called indirectly from
> vlv_force_pll_on() with a dummy crtc_state. That dummy crtc state is not
> converted to be part of a full drm atomic state, so add a WARN in case someone
> decides to call that again with such a dummy state.
> 
> v2: Warn if there is no connectors for a given crtc. (Daniel)
>     Replace comment i9xx_get_refclk() with a WARN_ON(). (Ander)
> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   2 +-
>  drivers/gpu/drm/i915/intel_display.c | 133 +++++++++++++++++++++-------------
> -
>  2 files changed, 83 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 490ab8c..576e101 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -541,7 +541,7 @@ struct drm_i915_display_funcs {
>  	 * Returns true on success, false on failure.
>  	 */
>  	bool (*find_dpll)(const struct intel_limit *limit,
> -			  struct intel_crtc *crtc,
> +			  struct intel_crtc_state *crtc_state,
>  			  int target, int refclk,
>  			  struct dpll *match_clock,
>  			  struct dpll *best_clock);
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 8c97186..be1979e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -431,25 +431,41 @@ bool intel_pipe_has_type(struct intel_crtc *crtc,
> enum intel_output_type type)
>   * intel_pipe_has_type() but looking at encoder->new_crtc instead of
>   * encoder->crtc.
>   */
> -static bool intel_pipe_will_have_type(struct intel_crtc *crtc, int type)
> +static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state,
> +				      int type)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_connector_state *connector_state;
>  	struct intel_encoder *encoder;
> +	int i, num_connectors = 0;
> +
> +	for (i = 0; i < state->num_connector; i++) {
> +		if (!state->connectors[i])
> +			continue;
> +
> +		connector_state = state->connector_states[i];
> +		if (connector_state->crtc != crtc_state->base.crtc)
> +			continue;
> +
> +		num_connectors++;

Above piece of code to loop through state->connectors[] is present in
multiple places, can you have a helper something like below to save
some typing and code reduction?

struct connector_state * intel_crtc_state_connector(crtc_state, crtc);

also similarily for encoder
struct encoder_state *intel_crtc_state_encoder(crtc_state, crtc);

> 
> -	for_each_intel_encoder(dev, encoder)
> -		if (encoder->new_crtc == crtc && encoder->type == type)
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +		if (encoder->type == type)
>  			return true;
> +	}
> +
> +	WARN_ON(num_connectors == 0);
> 
>  	return false;
>  }
> 
> -static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc,
> -						int refclk)
> +static const intel_limit_t *
> +intel_ironlake_limit(struct intel_crtc_state *crtc_state, int refclk)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_device *dev = crtc_state->base.crtc->dev;
>  	const intel_limit_t *limit;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		if (intel_is_dual_link_lvds(dev)) {
>  			if (refclk == 100000)
>  				limit = &intel_limits_ironlake_dual_lvds_100m;
> @@ -467,20 +483,21 @@ static const intel_limit_t *intel_ironlake_limit(struct
> intel_crtc *crtc,
>  	return limit;
>  }
> 
> -static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc)
> +static const intel_limit_t *
> +intel_g4x_limit(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_device *dev = crtc_state->base.crtc->dev;
>  	const intel_limit_t *limit;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		if (intel_is_dual_link_lvds(dev))
>  			limit = &intel_limits_g4x_dual_channel_lvds;
>  		else
>  			limit = &intel_limits_g4x_single_channel_lvds;
> -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI) ||
> -		   intel_pipe_will_have_type(crtc, INTEL_OUTPUT_ANALOG)) {
> +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI)
> ||
> +		   intel_pipe_will_have_type(crtc_state,
> INTEL_OUTPUT_ANALOG)) {
>  		limit = &intel_limits_g4x_hdmi;
> -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO)) {
> +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
>  		limit = &intel_limits_g4x_sdvo;
>  	} else /* The option is for other outputs */
>  		limit = &intel_limits_i9xx_sdvo;
> @@ -488,17 +505,18 @@ static const intel_limit_t *intel_g4x_limit(struct
> intel_crtc *crtc)
>  	return limit;
>  }
> 
> -static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk)
> +static const intel_limit_t *
> +intel_limit(struct intel_crtc_state *crtc_state, int refclk)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_device *dev = crtc_state->base.crtc->dev;
>  	const intel_limit_t *limit;
> 
>  	if (HAS_PCH_SPLIT(dev))
> -		limit = intel_ironlake_limit(crtc, refclk);
> +		limit = intel_ironlake_limit(crtc_state, refclk);
>  	else if (IS_G4X(dev)) {
> -		limit = intel_g4x_limit(crtc);
> +		limit = intel_g4x_limit(crtc_state);
>  	} else if (IS_PINEVIEW(dev)) {
> -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> +		if (intel_pipe_will_have_type(crtc_state,
> INTEL_OUTPUT_LVDS))
>  			limit = &intel_limits_pineview_lvds;
>  		else
>  			limit = &intel_limits_pineview_sdvo; @@ -507,14
> +525,14 @@ static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int
> refclk)
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		limit = &intel_limits_vlv;
>  	} else if (!IS_GEN2(dev)) {
> -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> +		if (intel_pipe_will_have_type(crtc_state,
> INTEL_OUTPUT_LVDS))
>  			limit = &intel_limits_i9xx_lvds;
>  		else
>  			limit = &intel_limits_i9xx_sdvo;
>  	} else {
> -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> +		if (intel_pipe_will_have_type(crtc_state,
> INTEL_OUTPUT_LVDS))
>  			limit = &intel_limits_i8xx_lvds;
> -		else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO))
> +		else if (intel_pipe_will_have_type(crtc_state,
> INTEL_OUTPUT_DVO))
>  			limit = &intel_limits_i8xx_dvo;
>  		else
>  			limit = &intel_limits_i8xx_dac;
> @@ -601,15 +619,17 @@ static bool intel_PLL_is_valid(struct drm_device *dev,
> }
> 
>  static bool
> -i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> +i9xx_find_best_dpll(const intel_limit_t *limit,
> +		    struct intel_crtc_state *crtc_state,
>  		    int target, int refclk, intel_clock_t *match_clock,
>  		    intel_clock_t *best_clock)
>  {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	intel_clock_t clock;
>  	int err = target;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		/*
>  		 * For LVDS just rely on its current settings for dual-channel.
>  		 * We haven't figured out how to reliably set up different @@ -
> 662,15 +682,17 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct
> intel_crtc *crtc,  }
> 
>  static bool
> -pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> +pnv_find_best_dpll(const intel_limit_t *limit,
> +		   struct intel_crtc_state *crtc_state,
>  		   int target, int refclk, intel_clock_t *match_clock,
>  		   intel_clock_t *best_clock)
>  {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	intel_clock_t clock;
>  	int err = target;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		/*
>  		 * For LVDS just rely on its current settings for dual-channel.
>  		 * We haven't figured out how to reliably set up different @@ -
> 721,10 +743,12 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct
> intel_crtc *crtc,  }
> 
>  static bool
> -g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> +g4x_find_best_dpll(const intel_limit_t *limit,
> +		   struct intel_crtc_state *crtc_state,
>  		   int target, int refclk, intel_clock_t *match_clock,
>  		   intel_clock_t *best_clock)
>  {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	intel_clock_t clock;
>  	int max_n;
> @@ -733,7 +757,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct
> intel_crtc *crtc,
>  	int err_most = (target >> 8) + (target >> 9);
>  	found = false;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		if (intel_is_dual_link_lvds(dev))
>  			clock.p2 = limit->p2.p2_fast;
>  		else
> @@ -778,10 +802,12 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct
> intel_crtc *crtc,  }
> 
>  static bool
> -vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> +vlv_find_best_dpll(const intel_limit_t *limit,
> +		   struct intel_crtc_state *crtc_state,
>  		   int target, int refclk, intel_clock_t *match_clock,
>  		   intel_clock_t *best_clock)
>  {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	intel_clock_t clock;
>  	unsigned int bestppm = 1000000;
> @@ -835,10 +861,12 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct
> intel_crtc *crtc,  }
> 
>  static bool
> -chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> +chv_find_best_dpll(const intel_limit_t *limit,
> +		   struct intel_crtc_state *crtc_state,
>  		   int target, int refclk, intel_clock_t *match_clock,
>  		   intel_clock_t *best_clock)
>  {
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	intel_clock_t clock;
>  	uint64_t m2;
> @@ -5726,7 +5754,7 @@ static int intel_crtc_compute_config(struct intel_crtc
> *crtc,
>  	 * - LVDS dual channel mode
>  	 * - Double wide pipe
>  	 */
> -	if ((intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> +	if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
>  	     intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
>  		pipe_config->pipe_src_w &= ~1;
> 
> @@ -5905,15 +5933,18 @@ static inline bool intel_panel_use_ssc(struct
> drm_i915_private *dev_priv)
>  		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);  }
> 
> -static int i9xx_get_refclk(struct intel_crtc *crtc, int num_connectors)
> +static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> +			   int num_connectors)
>  {
> -	struct drm_device *dev = crtc->base.dev;
> +	struct drm_device *dev = crtc_state->base.crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	int refclk;
> 
> +	WARN_ON(!crtc_state->base.state);
> +
>  	if (IS_VALLEYVIEW(dev)) {
>  		refclk = 100000;
> -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)
> &&
>  	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
>  		refclk = dev_priv->vbt.lvds_ssc_freq;
>  		DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
> refclk); @@ -5956,7 +5987,7 @@ static void i9xx_update_pll_dividers(struct
> intel_crtc *crtc,
>  	crtc_state->dpll_hw_state.fp0 = fp;
> 
>  	crtc->lowfreq_avail = false;
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
>  	    reduced_clock && i915.powersave) {
>  		crtc_state->dpll_hw_state.fp1 = fp2;
>  		crtc->lowfreq_avail = true;
> @@ -6314,6 +6345,7 @@ 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 pipe_config = {
> +		.base.crtc = &crtc->base,
>  		.pixel_multiplier = 1,
>  		.dpll = *dpll,
>  	};
> @@ -6358,12 +6390,12 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
> 
>  	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> 
> -	is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) ||
> -		intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI);
> +	is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)
> ||
> +		intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
> 
>  	dpll = DPLL_VGA_MODE_DIS;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
>  		dpll |= DPLLB_MODE_LVDS;
>  	else
>  		dpll |= DPLLB_MODE_DAC_SERIAL;
> @@ -6406,7 +6438,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
> 
>  	if (crtc_state->sdvo_tv_clock)
>  		dpll |= PLL_REF_INPUT_TVCLKINBC;
> -	else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> +	else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
>  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
>  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
>  	else
> @@ -6436,7 +6468,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
> 
>  	dpll = DPLL_VGA_MODE_DIS;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		dpll |= (1 << (clock->p1 - 1)) <<
> DPLL_FPA01_P1_POST_DIV_SHIFT;
>  	} else {
>  		if (clock->p1 == 2)
> @@ -6447,10 +6479,10 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
>  			dpll |= PLL_P2_DIVIDE_BY_4;
>  	}
> 
> -	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc,
> INTEL_OUTPUT_DVO))
> +	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state,
> +INTEL_OUTPUT_DVO))
>  		dpll |= DPLL_DVO_2X_MODE;
> 
> -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
>  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
>  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
>  	else
> @@ -6687,7 +6719,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> *crtc,
>  		return 0;
> 
>  	if (!crtc_state->clock_set) {
> -		refclk = i9xx_get_refclk(crtc, num_connectors);
> +		refclk = i9xx_get_refclk(crtc_state, num_connectors);
> 
>  		/*
>  		 * Returns a set of divisors for the desired target clock with @@
> -6695,8 +6727,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
>  		 * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
>  		 * 2) / p1 / p2.
>  		 */
> -		limit = intel_limit(crtc, refclk);
> -		ok = dev_priv->display.find_dpll(limit, crtc,
> +		limit = intel_limit(crtc_state, refclk);
> +		ok = dev_priv->display.find_dpll(limit, crtc_state,
>  						 crtc_state->port_clock,
>  						 refclk, NULL, &clock);
>  		if (!ok) {
> @@ -6712,7 +6744,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> *crtc,
>  			 * we will disable the LVDS downclock feature.
>  			 */
>  			has_reduced_clock =
> -				dev_priv->display.find_dpll(limit, crtc,
> +				dev_priv->display.find_dpll(limit, crtc_state,
>  							    dev_priv-
> >lvds_downclock,
>  							    refclk, &clock,
>  							    &reduced_clock);
> @@ -7540,12 +7572,11 @@ static bool ironlake_compute_clocks(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);
>  	int refclk;
>  	const intel_limit_t *limit;
>  	bool ret, is_lvds = false;
> 
> -	is_lvds = intel_pipe_will_have_type(intel_crtc, INTEL_OUTPUT_LVDS);
> +	is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
> 
>  	refclk = ironlake_get_refclk(crtc);
> 
> @@ -7554,8 +7585,8 @@ static bool ironlake_compute_clocks(struct drm_crtc
> *crtc,
>  	 * refclk, or FALSE.  The returned values represent the clock equation:
>  	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
>  	 */
> -	limit = intel_limit(intel_crtc, refclk);
> -	ret = dev_priv->display.find_dpll(limit, intel_crtc,
> +	limit = intel_limit(crtc_state, refclk);
> +	ret = dev_priv->display.find_dpll(limit, crtc_state,
>  					  crtc_state->port_clock,
>  					  refclk, NULL, clock);
>  	if (!ret)
> @@ -7569,7 +7600,7 @@ static bool ironlake_compute_clocks(struct drm_crtc
> *crtc,
>  		 * downclock feature.
>  		*/
>  		*has_reduced_clock =
> -			dev_priv->display.find_dpll(limit, intel_crtc,
> +			dev_priv->display.find_dpll(limit, crtc_state,
>  						    dev_priv->lvds_downclock,
>  						    refclk, clock,
>  						    reduced_clock);
> --
> 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] 52+ messages in thread

* Re: [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations
  2015-03-13  9:49 ` [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations Ander Conselvan de Oliveira
  2015-03-14  0:29   ` shuang.he
@ 2015-03-19 20:39   ` Konduru, Chandra
  1 sibling, 0 replies; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 20:39 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from
> clock computations
> 
> Some of the crtc_compute_clock() still depended on encoder->new_crtc since
> they didn't use intel_pipe_will_have_type() and used an open coded version of
> that function instead. This patch replaces those with the appropriate code that
> checks the atomic state intead.
> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 45 +++++++++++++++++++++++++--------
> ---
>  1 file changed, 32 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index be1979e..35ed651 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -6696,11 +6696,18 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> *crtc,
>  	bool is_lvds = false, is_dsi = false;
>  	struct intel_encoder *encoder;
>  	const intel_limit_t *limit;
> +	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_connector_state *connector_state;
> +	int i;
> 
> -	for_each_intel_encoder(dev, encoder) {
> -		if (encoder->new_crtc != crtc)
> +	for (i = 0; i < state->num_connector; i++) {
> +		connector_state = state->connector_states[i];
> +		if (!state->connectors[i] ||
> +		    connector_state->crtc != &crtc->base)
>  			continue;
> 
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +
>  		switch (encoder->type) {
>  		case INTEL_OUTPUT_LVDS:
>  			is_lvds = true;
> @@ -7374,18 +7381,24 @@ void intel_init_pch_refclk(struct drm_device *dev)
>  		lpt_init_pch_refclk(dev);
>  }
> 
> -static int ironlake_get_refclk(struct drm_crtc *crtc)
> +static int ironlake_get_refclk(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_device *dev = crtc->dev;
> +	struct drm_device *dev = crtc_state->base.crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_connector_state *connector_state;
>  	struct intel_encoder *encoder;
> -	int num_connectors = 0;
> +	int num_connectors = 0, i;
>  	bool is_lvds = false;
> 
> -	for_each_intel_encoder(dev, encoder) {
> -		if (encoder->new_crtc != to_intel_crtc(crtc))
> +	for (i = 0; i < state->num_connector; i++) {
> +		connector_state = state->connector_states[i];
> +		if (!state->connectors[i] ||
> +		    connector_state->crtc != crtc_state->base.crtc)
>  			continue;
> 
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +

Couple more occurrences looping through state->connectors[], 
can be replaced with a helper function returning connector_state.

>  		switch (encoder->type) {
>  		case INTEL_OUTPUT_LVDS:
>  			is_lvds = true;
> @@ -7578,7 +7591,7 @@ static bool ironlake_compute_clocks(struct drm_crtc
> *crtc,
> 
>  	is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
> 
> -	refclk = ironlake_get_refclk(crtc);
> +	refclk = ironlake_get_refclk(crtc_state);
> 
>  	/*
>  	 * Returns a set of divisors for the desired target clock with the given
> @@ -7633,16 +7646,22 @@ static uint32_t ironlake_compute_dpll(struct
> intel_crtc *intel_crtc,
>  	struct drm_crtc *crtc = &intel_crtc->base;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_encoder *intel_encoder;
> +	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_connector_state *connector_state;
> +	struct intel_encoder *encoder;
>  	uint32_t dpll;
> -	int factor, num_connectors = 0;
> +	int factor, num_connectors = 0, i;
>  	bool is_lvds = false, is_sdvo = false;
> 
> -	for_each_intel_encoder(dev, intel_encoder) {
> -		if (intel_encoder->new_crtc != to_intel_crtc(crtc))
> +	for (i = 0; i < state->num_connector; i++) {
> +		connector_state = state->connector_states[i];
> +		if (!state->connectors[i] ||
> +		    connector_state->crtc != crtc_state->base.crtc)
>  			continue;
> 
> -		switch (intel_encoder->type) {
> +		encoder = to_intel_encoder(connector_state->best_encoder);
> +
> +		switch (encoder->type) {
>  		case INTEL_OUTPUT_LVDS:
>  			is_lvds = true;
>  			break;
> --
> 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] 52+ messages in thread

* Re: [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config
  2015-03-13  9:48 ` [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config Ander Conselvan de Oliveira
@ 2015-03-19 20:55   ` Konduru, Chandra
  2015-03-20  6:41     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 20:55 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 05/19] drm/i915: Update dummy connector atomic state with
> current config
> 
> Keep that state updated so that we can write code that depends on it on the
> follow up patches.
> 
> v2: Fix BUG() due to stale connector_state->crtc value. (Chandra)
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 41 ++++++++++++++++++++++++++++----
> ----
>  1 file changed, 32 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 62b9021..abdbd0c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -10114,6 +10114,27 @@ static void
> intel_modeset_update_staged_output_state(struct drm_device *dev)
>  	}
>  }
> 
> +/* 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.
> + */
> +static void intel_modeset_update_connector_atomic_state(struct
> +drm_device *dev) {
> +	struct intel_connector *connector;
> +
> +	for_each_intel_connector(dev, connector) {
> +		if (connector->base.encoder) {
> +			connector->base.state->best_encoder =
> +				connector->base.encoder;
> +			connector->base.state->crtc =
> +				connector->base.encoder->crtc;
> +		} else {
> +			connector->base.state->best_encoder = NULL;
> +			connector->base.state->crtc = NULL;
> +		}
> +	}
> +}
> +
>  /**
>   * intel_modeset_commit_output_state
>   *
> @@ -10137,6 +10158,8 @@ static void
> intel_modeset_commit_output_state(struct drm_device *dev)
>  		crtc->base.state->enable = crtc->new_enabled;
>  		crtc->base.enabled = crtc->new_enabled;
>  	}
> +
> +	intel_modeset_update_connector_atomic_state(dev);
>  }
> 
>  static void
> @@ -12876,15 +12899,13 @@ static void intel_setup_outputs(struct
> drm_device *dev)
>  	 * be removed since we'll be setting up real connector state, which
>  	 * will contain Intel-specific properties.
>  	 */
> -	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> -		list_for_each_entry(connector,
> -				    &dev->mode_config.connector_list,
> -				    head) {
> -			if (!WARN_ON(connector->state)) {
> -				connector->state =
> -					kzalloc(sizeof(*connector->state),
> -						GFP_KERNEL);
> -			}
> +	/* FIXME: need to update the comment above. */

Can you fix the comment instead of adding another FIXME to fix it later?

> +	list_for_each_entry(connector,
> +			    &dev->mode_config.connector_list,
> +			    head) {
> +		if (!WARN_ON(connector->state)) {

In intel_modeset_stage_output_state() there is a call to setup
connector state:
	connector_state = drm_atomic_get_connector_state(state, &connector->base);
Is that call is covering modeset via crtc_set_config() but not during init flow, so 
doing it here?  
If that is the case, we probably know that connector->state
is never being set, so why have WARN_ON()?

As lower level compute code is already 
> +			connector->state = kzalloc(sizeof(*connector->state),
> +						   GFP_KERNEL);
>  		}
>  	}
> 
> @@ -13937,6 +13958,8 @@ void intel_modeset_setup_hw_state(struct
> drm_device *dev,
>  				       "[setup_hw_state]");
>  	}
> 
> +	intel_modeset_update_connector_atomic_state(dev);
> +
>  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> 
> --
> 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] 52+ messages in thread

* Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-13  9:48 ` [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state Ander Conselvan de Oliveira
@ 2015-03-19 20:58   ` Konduru, Chandra
  2015-03-20  6:46     ` Conselvan De Oliveira, Ander
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 20:58 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using
> atomic state
> 
> Makes that code atomic ready.
> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 49 ++++++++++++++++++++++++++++++-
> -----
>  1 file changed, 42 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index e720a48..8c97186 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct
> intel_connector *connector)
>  	return encoder->get_hw_state(encoder, &pipe);  }
> 
> -static int pipe_required_fdi_lanes(struct drm_device *dev, enum pipe pipe)
> +static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
> +				   enum pipe pipe)
>  {
>  	struct intel_crtc *crtc =
> -		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, pipe));
> +	struct intel_crtc_state *crtc_state;
> +
> +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> +	if (WARN_ON(IS_ERR(crtc_state))) {
> +		/* Cause modeset to fail due to excess lanes. */
> +		return 5;
> +	}
> 
> -	if (crtc->base.state->enable &&
> -	    crtc->config->has_pch_encoder)
> +	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
>  		return crtc->config->fdi_lanes;
> 
>  	return 0;
> @@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct drm_device
> *dev, enum pipe pipe)  static bool ironlake_check_fdi_lanes(struct drm_device
> *dev, enum pipe pipe,
>  				     struct intel_crtc_state *pipe_config)  {
> +	struct drm_atomic_state *state = pipe_config->base.state;
> +
>  	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
>  		      pipe_name(pipe), pipe_config->fdi_lanes);
>  	if (pipe_config->fdi_lanes > 4) {
> @@ -5579,7 +5588,7 @@ static bool ironlake_check_fdi_lanes(struct
> drm_device *dev, enum pipe pipe,
>  		return true;
>  	case PIPE_B:
>  		if (pipe_config->fdi_lanes > 2 &&
> -		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
> +		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
>  			DRM_DEBUG_KMS("invalid shared fdi lane config on
> pipe %c: %i lanes\n",
>  				      pipe_name(pipe), pipe_config->fdi_lanes);
>  			return false;
> @@ -5591,7 +5600,7 @@ static bool ironlake_check_fdi_lanes(struct
> drm_device *dev, enum pipe pipe,
>  				      pipe_name(pipe), pipe_config->fdi_lanes);
>  			return false;
>  		}
> -		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
> +		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
>  			DRM_DEBUG_KMS("fdi link B uses too many lanes to
> enable link C\n");
>  			return false;
>  		}
> @@ -5601,15 +5610,41 @@ static bool ironlake_check_fdi_lanes(struct
> drm_device *dev, enum pipe pipe,
>  	}
>  }
> 
> +static int add_pipe_b_c_to_state(struct drm_atomic_state *state) {
> +	struct intel_crtc *pipe_B =
> +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_B));
> +	struct intel_crtc *pipe_C =
> +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_C));
> +	struct intel_crtc_state *crtc_state;
> +
> +	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
> +	if (IS_ERR(crtc_state))
> +		return PTR_ERR(crtc_state);
> +
> +	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
> +	if (IS_ERR(crtc_state))
> +		return PTR_ERR(crtc_state);
> +
> +	return 0;
> +}
> +
>  #define RETRY 1
>  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  				       struct intel_crtc_state *pipe_config)  {
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_display_mode *adjusted_mode = &pipe_config-
> >base.adjusted_mode;
> -	int lane, link_bw, fdi_dotclock;
> +	int lane, link_bw, fdi_dotclock, ret;
>  	bool setup_ok, needs_recompute = false;
> 
> +	if (IS_IVYBRIDGE(dev) &&
> +	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
> +		ret = add_pipe_b_c_to_state(pipe_config->base.state);

In this scenario, crtc_states are created for both pipe B & C as an operation
on one can affect the other. I may be missing something here, 
but where is the other crtc_state being used: compute/check flow and/or 
commit flow?

> +		if (ret < 0)
> +			return ret;
> +	}
> +
>  retry:
>  	/* FDI is a binary signal running at ~2.7GHz, encoding
>  	 * each output octet as 10 bits. The actual frequency
> --
> 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] 52+ messages in thread

* Re: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-13  9:48 ` [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code Ander Conselvan de Oliveira
  2015-03-17  6:46   ` [PATCH v3] " Ander Conselvan de Oliveira
@ 2015-03-19 21:08   ` Konduru, Chandra
  2015-03-20  7:00     ` Ander Conselvan De Oliveira
  1 sibling, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 21:08 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander, intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Friday, March 13, 2015 2:49 AM
> To: intel-gfx@lists.freedesktop.org
> Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> Subject: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy
> modeset code
> 
> For the atomic conversion, the mode set paths need to be changed to rely on an
> atomic state instead of using the staged config. By using an atomic state for the
> legacy code, we will be able to convert the code base in small chunks.
> 
> v2: Squash patch that adds state argument to intel_set_mode(). (Ander)
>     Make every caller of intel_set_mode() allocate state. (Daniel)
>     Call drm_atomic_state_clear() in set config's error path. (Daniel)
> 
> Signed-off-by: Ander Conselvan de Oliveira
> <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 168 +++++++++++++++++++++++++++----
> ----
>  1 file changed, 133 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 78ea122..b61e3f6 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -37,6 +37,7 @@
>  #include <drm/i915_drm.h>
>  #include "i915_drv.h"
>  #include "i915_trace.h"
> +#include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drm_crtc_helper.h>
> @@ -82,7 +83,8 @@ 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_display_mode
> *mode,
> -			  int x, int y, struct drm_framebuffer *old_fb);
> +			  int x, int y, struct drm_framebuffer *old_fb,
> +			  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, @@
> -8802,6 +8804,7 @@ bool intel_get_load_detect_pipe(struct drm_connector
> *connector,
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_framebuffer *fb;
>  	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_atomic_state *state = NULL;
>  	int ret, i = -1;
> 
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> -8883,6 +8886,12 @@ retry:
>  	old->load_detect_temp = true;
>  	old->release_fb = NULL;
> 
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state)
> +		return false;
> +
> +	state->acquire_ctx = ctx;
> +
>  	if (!mode)
>  		mode = &load_detect_mode;
> 
> @@ -8905,7 +8914,7 @@ retry:
>  		goto fail;
>  	}
> 
> -	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
> +	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
> @@ -8924,6 +8933,11 @@ retry:
>  	else
>  		intel_crtc->new_config = NULL;

There are still occurrences of new_config, which you indicated killing them.
Will you be sending out another version?

Same applies to any new_xxx variables where they supposed to be in
respective states or take them out.

crtc->new_crtc
crtc->new_config
crtc->new_enabled
encoder->new_encoder
dpll->new_config

In __intel_set_mode_setup_plls() before calling crtc_compute_clock()
it is picking crtc_state from crtc->new_config. I think crtc_state should
be a parameter to __intel_set_mode_setup_plls() and then pass
further it to compute_clocks().


>  fail_unlock:
> +	if (state) {
> +		drm_atomic_state_free(state);
> +		state = NULL;
> +	}
> +
>  	if (ret == -EDEADLK) {
>  		drm_modeset_backoff(ctx);
>  		goto retry;
> @@ -8936,22 +8950,34 @@ void intel_release_load_detect_pipe(struct
> drm_connector *connector,
>  				    struct intel_load_detect_pipe *old,
>  				    struct drm_modeset_acquire_ctx *ctx)  {
> +	struct drm_device *dev = connector->dev;
>  	struct intel_encoder *intel_encoder =
>  		intel_attached_encoder(connector);
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_crtc *crtc = encoder->crtc;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_atomic_state *state;
> 
>  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
>  		      connector->base.id, connector->name,
>  		      encoder->base.id, encoder->name);
> 
>  	if (old->load_detect_temp) {
> +		state = drm_atomic_state_alloc(dev);
> +		if (!state) {
> +			DRM_DEBUG_KMS("can't release load detect pipe\n");
> +			return;
> +		}
> +
> +		state->acquire_ctx = ctx;
> +
>  		to_intel_connector(connector)->new_encoder = NULL;
>  		intel_encoder->new_crtc = NULL;
>  		intel_crtc->new_enabled = false;
>  		intel_crtc->new_config = NULL;
> -		intel_set_mode(crtc, NULL, 0, 0, NULL);
> +		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> +
> +		drm_atomic_state_free(state);
> 
>  		if (old->release_fb) {
>  			drm_framebuffer_unregister_private(old->release_fb);
> @@ -10345,10 +10371,22 @@ static bool check_digital_port_conflicts(struct
> drm_device *dev)
>  	return true;
>  }
> 
> -static struct intel_crtc_state *
> +static void
> +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) {
> +	struct drm_crtc_state tmp_state;
> +
> +	/* Clear only the intel specific part of the crtc state */
> +	tmp_state = crtc_state->base;
> +	memset(crtc_state, 0, sizeof *crtc_state);
> +	crtc_state->base = tmp_state;
> +}
> +
> +static int
>  intel_modeset_pipe_config(struct drm_crtc *crtc,
>  			  struct drm_framebuffer *fb,
> -			  struct drm_display_mode *mode)
> +			  struct drm_display_mode *mode,
> +			  struct drm_atomic_state *state)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct intel_encoder *encoder;
> @@ -10358,17 +10396,19 @@ intel_modeset_pipe_config(struct drm_crtc
> *crtc,
> 
>  	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
>  		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
> 
>  	if (!check_digital_port_conflicts(dev)) {
>  		DRM_DEBUG_KMS("rejecting conflicting digital port
> configuration\n");
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
> 
> -	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> -	if (!pipe_config)
> -		return ERR_PTR(-ENOMEM);
> +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> +	if (IS_ERR(pipe_config))
> +		return PTR_ERR(pipe_config);
> +
> +	clear_intel_crtc_state(pipe_config);
> 
>  	pipe_config->base.crtc = crtc;
>  	drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -
> 10463,10 +10503,9 @@ encoder_retry:
>  	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
>  		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> 
> -	return pipe_config;
> +	return 0;
>  fail:
> -	kfree(pipe_config);
> -	return ERR_PTR(ret);
> +	return ret;
>  }
> 
>  /* Computes which crtcs are affected and sets the relevant bits in the mask. For
> @@ -11144,17 +11183,19 @@ static struct intel_crtc_state *
> intel_modeset_compute_config(struct drm_crtc *crtc,
>  			     struct drm_display_mode *mode,
>  			     struct drm_framebuffer *fb,
> +			     struct drm_atomic_state *state,
>  			     unsigned *modeset_pipes,
>  			     unsigned *prepare_pipes,
>  			     unsigned *disable_pipes)
>  {
>  	struct intel_crtc_state *pipe_config = NULL;
> +	int ret = 0;
> 
>  	intel_modeset_affected_pipes(crtc, modeset_pipes,
>  				     prepare_pipes, disable_pipes);
> 
>  	if ((*modeset_pipes) == 0)
> -		goto out;
> +		return NULL;
> 
>  	/*
>  	 * Note this needs changes when we start tracking multiple modes @@ -
> 11162,14 +11203,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
>  	 * (i.e. one pipe_config for each crtc) rather than just the one
>  	 * for this crtc.
>  	 */
> -	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
> -	if (IS_ERR(pipe_config)) {
> -		goto out;
> -	}
> +	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> +	if (IS_ERR(pipe_config))
> +		return pipe_config;
> +
>  	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
>  			       "[modeset]");
> 
> -out:
>  	return pipe_config;
>  }
> 
> @@ -11214,6 +11258,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct drm_display_mode *saved_mode;
> +	struct intel_crtc_state *crtc_state_copy = NULL;
>  	struct intel_crtc *intel_crtc;
>  	int ret = 0;
> 
> @@ -11221,6 +11266,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>  	if (!saved_mode)
>  		return -ENOMEM;
> 
> +	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
> +	if (!crtc_state_copy) {
> +		ret = -ENOMEM;
> +		goto done;
> +	}
> +
>  	*saved_mode = crtc->mode;
> 
>  	if (modeset_pipes)
> @@ -11307,6 +11358,19 @@ done:
>  	if (ret && crtc->state->enable)
>  		crtc->mode = *saved_mode;
> 
> +	if (ret == 0 && pipe_config) {
> +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
> +		/* The pipe_config will be freed with the atomic state, so
> +		 * make a copy. */
> +		memcpy(crtc_state_copy, intel_crtc->config,
> +		       sizeof *crtc_state_copy);
> +		intel_crtc->config = intel_crtc->new_config = crtc_state_copy;
> +		intel_crtc->base.state = &crtc_state_copy->base;
> +	} else {
> +		kfree(crtc_state_copy);
> +	}
> +
>  	kfree(saved_mode);
>  	return ret;
>  }
> @@ -11332,27 +11396,51 @@ static int intel_set_mode_pipes(struct drm_crtc
> *crtc,
> 
>  static int intel_set_mode(struct drm_crtc *crtc,
>  			  struct drm_display_mode *mode,
> -			  int x, int y, struct drm_framebuffer *fb)
> +			  int x, int y, struct drm_framebuffer *fb,
> +			  struct drm_atomic_state *state)
>  {
>  	struct intel_crtc_state *pipe_config;
>  	unsigned modeset_pipes, prepare_pipes, disable_pipes;
> +	int ret = 0;
> 
> -	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
> +	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
>  						   &modeset_pipes,
>  						   &prepare_pipes,
>  						   &disable_pipes);
> 
> -	if (IS_ERR(pipe_config))
> -		return PTR_ERR(pipe_config);
> +	if (IS_ERR(pipe_config)) {
> +		ret = PTR_ERR(pipe_config);
> +		goto out;
> +	}
> +
> +	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> +				   modeset_pipes, prepare_pipes,
> +				   disable_pipes);
> +	if (ret)
> +		goto out;
> 
> -	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> -				    modeset_pipes, prepare_pipes,
> -				    disable_pipes);
> +out:
> +	return ret;
>  }
> 
>  void intel_crtc_restore_mode(struct drm_crtc *crtc)  {
> -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_atomic_state *state;
> +
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state) {
> +		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of
> memory",
> +			      crtc->base.id);
> +		return;
> +	}
> +
> +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> +
> +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
> +		       state);
> +
> +	drm_atomic_state_free(state);
>  }
> 
>  #undef for_each_intel_crtc_masked
> @@ -11677,6 +11765,7 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)  {
>  	struct drm_device *dev;
>  	struct drm_mode_set save_set;
> +	struct drm_atomic_state *state = NULL;
>  	struct intel_set_config *config;
>  	struct intel_crtc_state *pipe_config;
>  	unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11721,12
> +11810,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
>  	 * such cases. */
>  	intel_set_config_compute_mode_changes(set, config);
> 
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state) {
> +		ret = -ENOMEM;
> +		goto out_config;
> +	}
> +
> +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> +
>  	ret = intel_modeset_stage_output_state(dev, set, config);
>  	if (ret)
>  		goto fail;
> 
>  	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
> -						   set->fb,
> +						   set->fb, state,
>  						   &modeset_pipes,
>  						   &prepare_pipes,
>  						   &disable_pipes);
> @@ -11746,10 +11843,6 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)
>  		 */
>  	}
> 
> -	/* set_mode will free it in the mode_changed case */
> -	if (!config->mode_changed)
> -		kfree(pipe_config);
> -
>  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> 
>  	if (config->mode_changed) {
> @@ -11795,6 +11888,8 @@ static int intel_crtc_set_config(struct
> drm_mode_set *set)
>  fail:
>  		intel_set_config_restore_state(dev, config);
> 
> +		drm_atomic_state_clear(state);
> +
>  		/*
>  		 * HACK: if the pipe was on, but we didn't have a framebuffer,
>  		 * force the pipe off to avoid oopsing in the modeset code @@
> -11807,11 +11902,15 @@ fail:
>  		/* Try to restore the config */
>  		if (config->mode_changed &&
>  		    intel_set_mode(save_set.crtc, save_set.mode,
> -				   save_set.x, save_set.y, save_set.fb))
> +				   save_set.x, save_set.y, save_set.fb,
> +				   state))
>  			DRM_ERROR("failed to restore config after modeset
> failure\n");
>  	}
> 
>  out_config:
> +	if (state)
> +		drm_atomic_state_free(state);
> +
>  	intel_set_config_free(config);
>  	return ret;
>  }
> @@ -13852,8 +13951,7 @@ void intel_modeset_setup_hw_state(struct
> drm_device *dev,
>  			struct drm_crtc *crtc =
>  				dev_priv->pipe_to_crtc_mapping[pipe];
> 
> -			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> -				       crtc->primary->fb);
> +			intel_crtc_restore_mode(crtc);
>  		}
>  	} else {
>  		intel_modeset_update_staged_output_state(dev);
> --
> 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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-19  7:52     ` Ander Conselvan De Oliveira
@ 2015-03-19 23:23       ` Konduru, Chandra
  2015-03-20  8:40         ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-19 23:23 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx



> -----Original Message-----
> From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> Sent: Thursday, March 19, 2015 12:52 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is
> being disabled
> 
> On Thu, 2015-03-19 at 00:12 +0000, Konduru, Chandra wrote:
> >
> > > -----Original Message-----
> > > From: Conselvan De Oliveira, Ander
> > > Sent: Friday, March 13, 2015 2:49 AM
> > > To: intel-gfx@lists.freedesktop.org
> > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > Subject: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the
> > > crtc is being disabled
> > >
> > > For consistency, allocate a new crtc_state for a crtc that is being disabled.
> > > Previously only the enabled value of the current state would change.
> > >
> > > Signed-off-by: Ander Conselvan de Oliveira
> > > <ander.conselvan.de.oliveira@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_display.c | 36
> > > +++++++++++++++++++++++++--------
> > > ---
> > >  1 file changed, 25 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index b61e3f6..62b9021 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -11188,14 +11188,21 @@ intel_modeset_compute_config(struct
> > > drm_crtc *crtc,
> > >  			     unsigned *prepare_pipes,
> > >  			     unsigned *disable_pipes)
> > >  {
> > > +	struct drm_device *dev = crtc->dev;
> > >  	struct intel_crtc_state *pipe_config = NULL;
> > > +	struct intel_crtc *intel_crtc;
> > >  	int ret = 0;
> > >
> > >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> > >  				     prepare_pipes, disable_pipes);
> > >
> > > -	if ((*modeset_pipes) == 0)
> > > -		return NULL;
> > > +	for_each_intel_crtc_masked(dev, *disable_pipes, intel_crtc) {
> > > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > > +		if (IS_ERR(pipe_config))
> > > +			return pipe_config;
> > > +
> > > +		pipe_config->base.enable = false;
> > > +	}
> > >
> > >  	/*
> > >  	 * Note this needs changes when we start tracking multiple modes
> > > @@ -
> > > 11203,18 +11210,25 @@ intel_modeset_compute_config(struct drm_crtc
> *crtc,
> > >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> > >  	 * for this crtc.
> > >  	 */
> > > -	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > -	if (ret)
> > > -		return ERR_PTR(ret);
> > > +	for_each_intel_crtc_masked(dev, *modeset_pipes, intel_crtc) {
> > > +		/* FIXME: For now we still expect modeset_pipes has at most
> > > +		 * one bit set. */
> > > +		if (WARN_ON(&intel_crtc->base != crtc))
> > > +			continue;
> > >
> > > -	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > -	if (IS_ERR(pipe_config))
> > > -		return pipe_config;
> > > +		ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > +		if (ret)
> > > +			return ERR_PTR(ret);
> > > +
> > > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > > +		if (IS_ERR(pipe_config))
> > > +			return pipe_config;
> > >
> > > -	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > > -			       "[modeset]");
> > > +		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > > +				       "[modeset]");
> > > +	}
> > >
> > > -	return pipe_config;
> > > +	return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > >  }
> >
> > Instead of calling 3 separate intel_atomic_get_crtc_state() Can you
> > have something like:
> > intel_modeset_compute_config()
> > {
> > 	pipe_config = intel_atomic_get_crtc_state(state, crtc);
> >
> > 	for each disabled pipe {
> > 		use pipe_config;
> > 	}
> >
> > 	for each mode_set pipe {
> > 		use pipe_config;
> > 	}
> >
> > 	return pipe_config;
> > }
> >
> >
> > Or the way currently done is to cover where disable_pipes != modeset_pipes?
> > By the way, when can it happen?
> 
> Yep, disable_pipes can be different than modeset_pipes if we the mode set
> "steals" a connector. For instance, we could have pipe A driving
> HDMI-1 and then mode set to pipe B to drive HDMI-1. Pipe B will steal the
> encoder from pipe A, and cause it to be disable. In that case disable_pipes will
> have the bit for pipe A set, while modeset_pipes will have the bit for pipe B set.

1) 
Consider two simple scenarios:  
Case1: User code moving HDMI from A to B:
drmModeSetCrtc(crtcA, HDMI);
drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */

Case2: User code turning off HDMI:
drmModeSetCrtc(crtcA, HDMI);
drmModeSetCrtc(crtcA, disable);

In both cases, driver will be disabling crtc for pipe A. 
In case 1, there is no associated crtc_state or compute & commit but 
directly triggering crtc_disable(crtcA).
In case 2, there is associated crtc_state and associated compute and setmode
calls crtc_disable(crtcA);

Won't this cause trouble for low level functions (disable clocks, connectors, 
encoders, planes etc. etc...) acting on variables being computed and staged 
in their respective states?
    where case 1 calls with current crtc->config, 
    and case 2 calls crt->config which is computed crtc_state

2)
For example, to disable a plane differentiate between below two:
plane being called to disable with fb is valid
	vs.
plane being called to disable with fb is null.

There is crtc->active somehow to take care this, but I think this should 
move to crtc_state. Same applies for any such other variables in crtc. 
And respective resource's functions should check its hosting crtc_state 
along with its own conditions to act on its resource.

If not getting into this patch series, these changes should go into next 
series for achieving crtc atomicity.

3)
Also low level enable/disable functions can start causing confusion 
if they aren't read/interpreted correctly. Either we should have resource_commit 
which further calls resource->enable() or resource->disable() depending 
on its own state and its hosting resource state; or have resource_commit 
calling resource->update() where it does either enable or disable based 
on state.

We don't have above for crtc but should be done something like this 
if not in this patch but sometime after in order to achieve crtc atomicity.


> 
> 
> Ander
> 
> >
> > >
> > >  static int __intel_set_mode_setup_plls(struct drm_device *dev,
> > > --
> > > 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] 52+ messages in thread

* Re: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using atomic state
  2015-03-19 19:24   ` Konduru, Chandra
@ 2015-03-20  6:28     ` Ander Conselvan De Oliveira
  2015-03-22 16:14       ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-20  6:28 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 19:24 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using
> > atomic state
> > 
> > Pass a crtc_state to it and find whether the pipe has an encoder of a given type
> > by looking at the drm_atomic_state the crtc_state points to.
> > 
> > Until recently i9xx_get_refclk() used to be called indirectly from
> > vlv_force_pll_on() with a dummy crtc_state. That dummy crtc state is not
> > converted to be part of a full drm atomic state, so add a WARN in case someone
> > decides to call that again with such a dummy state.
> > 
> > v2: Warn if there is no connectors for a given crtc. (Daniel)
> >     Replace comment i9xx_get_refclk() with a WARN_ON(). (Ander)
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h      |   2 +-
> >  drivers/gpu/drm/i915/intel_display.c | 133 +++++++++++++++++++++-------------
> > -
> >  2 files changed, 83 insertions(+), 52 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 490ab8c..576e101 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -541,7 +541,7 @@ struct drm_i915_display_funcs {
> >  	 * Returns true on success, false on failure.
> >  	 */
> >  	bool (*find_dpll)(const struct intel_limit *limit,
> > -			  struct intel_crtc *crtc,
> > +			  struct intel_crtc_state *crtc_state,
> >  			  int target, int refclk,
> >  			  struct dpll *match_clock,
> >  			  struct dpll *best_clock);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 8c97186..be1979e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -431,25 +431,41 @@ bool intel_pipe_has_type(struct intel_crtc *crtc,
> > enum intel_output_type type)
> >   * intel_pipe_has_type() but looking at encoder->new_crtc instead of
> >   * encoder->crtc.
> >   */
> > -static bool intel_pipe_will_have_type(struct intel_crtc *crtc, int type)
> > +static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state,
> > +				      int type)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_atomic_state *state = crtc_state->base.state;
> > +	struct drm_connector_state *connector_state;
> >  	struct intel_encoder *encoder;
> > +	int i, num_connectors = 0;
> > +
> > +	for (i = 0; i < state->num_connector; i++) {
> > +		if (!state->connectors[i])
> > +			continue;
> > +
> > +		connector_state = state->connector_states[i];
> > +		if (connector_state->crtc != crtc_state->base.crtc)
> > +			continue;
> > +
> > +		num_connectors++;
> 
> Above piece of code to loop through state->connectors[] is present in
> multiple places, can you have a helper something like below to save
> some typing and code reduction?
> 
> struct connector_state * intel_crtc_state_connector(crtc_state, crtc);
> 
> also similarily for encoder
> struct encoder_state *intel_crtc_state_encoder(crtc_state, crtc);

This wouldn't work for cloned setups, where we have more than one
connector/encoder in a single pipe. 

Ander

> > 
> > -	for_each_intel_encoder(dev, encoder)
> > -		if (encoder->new_crtc == crtc && encoder->type == type)
> > +		encoder = to_intel_encoder(connector_state->best_encoder);
> > +		if (encoder->type == type)
> >  			return true;
> > +	}
> > +
> > +	WARN_ON(num_connectors == 0);
> > 
> >  	return false;
> >  }
> > 
> > -static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc,
> > -						int refclk)
> > +static const intel_limit_t *
> > +intel_ironlake_limit(struct intel_crtc_state *crtc_state, int refclk)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> >  	const intel_limit_t *limit;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		if (intel_is_dual_link_lvds(dev)) {
> >  			if (refclk == 100000)
> >  				limit = &intel_limits_ironlake_dual_lvds_100m;
> > @@ -467,20 +483,21 @@ static const intel_limit_t *intel_ironlake_limit(struct
> > intel_crtc *crtc,
> >  	return limit;
> >  }
> > 
> > -static const intel_limit_t *intel_g4x_limit(struct intel_crtc *crtc)
> > +static const intel_limit_t *
> > +intel_g4x_limit(struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> >  	const intel_limit_t *limit;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		if (intel_is_dual_link_lvds(dev))
> >  			limit = &intel_limits_g4x_dual_channel_lvds;
> >  		else
> >  			limit = &intel_limits_g4x_single_channel_lvds;
> > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI) ||
> > -		   intel_pipe_will_have_type(crtc, INTEL_OUTPUT_ANALOG)) {
> > +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI)
> > ||
> > +		   intel_pipe_will_have_type(crtc_state,
> > INTEL_OUTPUT_ANALOG)) {
> >  		limit = &intel_limits_g4x_hdmi;
> > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO)) {
> > +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) {
> >  		limit = &intel_limits_g4x_sdvo;
> >  	} else /* The option is for other outputs */
> >  		limit = &intel_limits_i9xx_sdvo;
> > @@ -488,17 +505,18 @@ static const intel_limit_t *intel_g4x_limit(struct
> > intel_crtc *crtc)
> >  	return limit;
> >  }
> > 
> > -static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int refclk)
> > +static const intel_limit_t *
> > +intel_limit(struct intel_crtc_state *crtc_state, int refclk)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> >  	const intel_limit_t *limit;
> > 
> >  	if (HAS_PCH_SPLIT(dev))
> > -		limit = intel_ironlake_limit(crtc, refclk);
> > +		limit = intel_ironlake_limit(crtc_state, refclk);
> >  	else if (IS_G4X(dev)) {
> > -		limit = intel_g4x_limit(crtc);
> > +		limit = intel_g4x_limit(crtc_state);
> >  	} else if (IS_PINEVIEW(dev)) {
> > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > +		if (intel_pipe_will_have_type(crtc_state,
> > INTEL_OUTPUT_LVDS))
> >  			limit = &intel_limits_pineview_lvds;
> >  		else
> >  			limit = &intel_limits_pineview_sdvo; @@ -507,14
> > +525,14 @@ static const intel_limit_t *intel_limit(struct intel_crtc *crtc, int
> > refclk)
> >  	} else if (IS_VALLEYVIEW(dev)) {
> >  		limit = &intel_limits_vlv;
> >  	} else if (!IS_GEN2(dev)) {
> > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > +		if (intel_pipe_will_have_type(crtc_state,
> > INTEL_OUTPUT_LVDS))
> >  			limit = &intel_limits_i9xx_lvds;
> >  		else
> >  			limit = &intel_limits_i9xx_sdvo;
> >  	} else {
> > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > +		if (intel_pipe_will_have_type(crtc_state,
> > INTEL_OUTPUT_LVDS))
> >  			limit = &intel_limits_i8xx_lvds;
> > -		else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO))
> > +		else if (intel_pipe_will_have_type(crtc_state,
> > INTEL_OUTPUT_DVO))
> >  			limit = &intel_limits_i8xx_dvo;
> >  		else
> >  			limit = &intel_limits_i8xx_dac;
> > @@ -601,15 +619,17 @@ static bool intel_PLL_is_valid(struct drm_device *dev,
> > }
> > 
> >  static bool
> > -i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> > +i9xx_find_best_dpll(const intel_limit_t *limit,
> > +		    struct intel_crtc_state *crtc_state,
> >  		    int target, int refclk, intel_clock_t *match_clock,
> >  		    intel_clock_t *best_clock)
> >  {
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> >  	struct drm_device *dev = crtc->base.dev;
> >  	intel_clock_t clock;
> >  	int err = target;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		/*
> >  		 * For LVDS just rely on its current settings for dual-channel.
> >  		 * We haven't figured out how to reliably set up different @@ -
> > 662,15 +682,17 @@ i9xx_find_best_dpll(const intel_limit_t *limit, struct
> > intel_crtc *crtc,  }
> > 
> >  static bool
> > -pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> > +pnv_find_best_dpll(const intel_limit_t *limit,
> > +		   struct intel_crtc_state *crtc_state,
> >  		   int target, int refclk, intel_clock_t *match_clock,
> >  		   intel_clock_t *best_clock)
> >  {
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> >  	struct drm_device *dev = crtc->base.dev;
> >  	intel_clock_t clock;
> >  	int err = target;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		/*
> >  		 * For LVDS just rely on its current settings for dual-channel.
> >  		 * We haven't figured out how to reliably set up different @@ -
> > 721,10 +743,12 @@ pnv_find_best_dpll(const intel_limit_t *limit, struct
> > intel_crtc *crtc,  }
> > 
> >  static bool
> > -g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> > +g4x_find_best_dpll(const intel_limit_t *limit,
> > +		   struct intel_crtc_state *crtc_state,
> >  		   int target, int refclk, intel_clock_t *match_clock,
> >  		   intel_clock_t *best_clock)
> >  {
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> >  	struct drm_device *dev = crtc->base.dev;
> >  	intel_clock_t clock;
> >  	int max_n;
> > @@ -733,7 +757,7 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct
> > intel_crtc *crtc,
> >  	int err_most = (target >> 8) + (target >> 9);
> >  	found = false;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		if (intel_is_dual_link_lvds(dev))
> >  			clock.p2 = limit->p2.p2_fast;
> >  		else
> > @@ -778,10 +802,12 @@ g4x_find_best_dpll(const intel_limit_t *limit, struct
> > intel_crtc *crtc,  }
> > 
> >  static bool
> > -vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> > +vlv_find_best_dpll(const intel_limit_t *limit,
> > +		   struct intel_crtc_state *crtc_state,
> >  		   int target, int refclk, intel_clock_t *match_clock,
> >  		   intel_clock_t *best_clock)
> >  {
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> >  	struct drm_device *dev = crtc->base.dev;
> >  	intel_clock_t clock;
> >  	unsigned int bestppm = 1000000;
> > @@ -835,10 +861,12 @@ vlv_find_best_dpll(const intel_limit_t *limit, struct
> > intel_crtc *crtc,  }
> > 
> >  static bool
> > -chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc *crtc,
> > +chv_find_best_dpll(const intel_limit_t *limit,
> > +		   struct intel_crtc_state *crtc_state,
> >  		   int target, int refclk, intel_clock_t *match_clock,
> >  		   intel_clock_t *best_clock)
> >  {
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> >  	struct drm_device *dev = crtc->base.dev;
> >  	intel_clock_t clock;
> >  	uint64_t m2;
> > @@ -5726,7 +5754,7 @@ static int intel_crtc_compute_config(struct intel_crtc
> > *crtc,
> >  	 * - LVDS dual channel mode
> >  	 * - Double wide pipe
> >  	 */
> > -	if ((intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
> >  	     intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
> >  		pipe_config->pipe_src_w &= ~1;
> > 
> > @@ -5905,15 +5933,18 @@ static inline bool intel_panel_use_ssc(struct
> > drm_i915_private *dev_priv)
> >  		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);  }
> > 
> > -static int i9xx_get_refclk(struct intel_crtc *crtc, int num_connectors)
> > +static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> > +			   int num_connectors)
> >  {
> > -	struct drm_device *dev = crtc->base.dev;
> > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	int refclk;
> > 
> > +	WARN_ON(!crtc_state->base.state);
> > +
> >  	if (IS_VALLEYVIEW(dev)) {
> >  		refclk = 100000;
> > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	} else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)
> > &&
> >  	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
> >  		refclk = dev_priv->vbt.lvds_ssc_freq;
> >  		DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
> > refclk); @@ -5956,7 +5987,7 @@ static void i9xx_update_pll_dividers(struct
> > intel_crtc *crtc,
> >  	crtc_state->dpll_hw_state.fp0 = fp;
> > 
> >  	crtc->lowfreq_avail = false;
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> >  	    reduced_clock && i915.powersave) {
> >  		crtc_state->dpll_hw_state.fp1 = fp2;
> >  		crtc->lowfreq_avail = true;
> > @@ -6314,6 +6345,7 @@ 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 pipe_config = {
> > +		.base.crtc = &crtc->base,
> >  		.pixel_multiplier = 1,
> >  		.dpll = *dpll,
> >  	};
> > @@ -6358,12 +6390,12 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
> > 
> >  	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> > 
> > -	is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) ||
> > -		intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI);
> > +	is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)
> > ||
> > +		intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
> > 
> >  	dpll = DPLL_VGA_MODE_DIS;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
> >  		dpll |= DPLLB_MODE_LVDS;
> >  	else
> >  		dpll |= DPLLB_MODE_DAC_SERIAL;
> > @@ -6406,7 +6438,7 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
> > 
> >  	if (crtc_state->sdvo_tv_clock)
> >  		dpll |= PLL_REF_INPUT_TVCLKINBC;
> > -	else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> >  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> >  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> >  	else
> > @@ -6436,7 +6468,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
> > 
> >  	dpll = DPLL_VGA_MODE_DIS;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> >  		dpll |= (1 << (clock->p1 - 1)) <<
> > DPLL_FPA01_P1_POST_DIV_SHIFT;
> >  	} else {
> >  		if (clock->p1 == 2)
> > @@ -6447,10 +6479,10 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
> >  			dpll |= PLL_P2_DIVIDE_BY_4;
> >  	}
> > 
> > -	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc,
> > INTEL_OUTPUT_DVO))
> > +	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state,
> > +INTEL_OUTPUT_DVO))
> >  		dpll |= DPLL_DVO_2X_MODE;
> > 
> > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> >  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> >  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> >  	else
> > @@ -6687,7 +6719,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> > *crtc,
> >  		return 0;
> > 
> >  	if (!crtc_state->clock_set) {
> > -		refclk = i9xx_get_refclk(crtc, num_connectors);
> > +		refclk = i9xx_get_refclk(crtc_state, num_connectors);
> > 
> >  		/*
> >  		 * Returns a set of divisors for the desired target clock with @@
> > -6695,8 +6727,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc,
> >  		 * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
> >  		 * 2) / p1 / p2.
> >  		 */
> > -		limit = intel_limit(crtc, refclk);
> > -		ok = dev_priv->display.find_dpll(limit, crtc,
> > +		limit = intel_limit(crtc_state, refclk);
> > +		ok = dev_priv->display.find_dpll(limit, crtc_state,
> >  						 crtc_state->port_clock,
> >  						 refclk, NULL, &clock);
> >  		if (!ok) {
> > @@ -6712,7 +6744,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> > *crtc,
> >  			 * we will disable the LVDS downclock feature.
> >  			 */
> >  			has_reduced_clock =
> > -				dev_priv->display.find_dpll(limit, crtc,
> > +				dev_priv->display.find_dpll(limit, crtc_state,
> >  							    dev_priv-
> > >lvds_downclock,
> >  							    refclk, &clock,
> >  							    &reduced_clock);
> > @@ -7540,12 +7572,11 @@ static bool ironlake_compute_clocks(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);
> >  	int refclk;
> >  	const intel_limit_t *limit;
> >  	bool ret, is_lvds = false;
> > 
> > -	is_lvds = intel_pipe_will_have_type(intel_crtc, INTEL_OUTPUT_LVDS);
> > +	is_lvds = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS);
> > 
> >  	refclk = ironlake_get_refclk(crtc);
> > 
> > @@ -7554,8 +7585,8 @@ static bool ironlake_compute_clocks(struct drm_crtc
> > *crtc,
> >  	 * refclk, or FALSE.  The returned values represent the clock equation:
> >  	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> >  	 */
> > -	limit = intel_limit(intel_crtc, refclk);
> > -	ret = dev_priv->display.find_dpll(limit, intel_crtc,
> > +	limit = intel_limit(crtc_state, refclk);
> > +	ret = dev_priv->display.find_dpll(limit, crtc_state,
> >  					  crtc_state->port_clock,
> >  					  refclk, NULL, clock);
> >  	if (!ret)
> > @@ -7569,7 +7600,7 @@ static bool ironlake_compute_clocks(struct drm_crtc
> > *crtc,
> >  		 * downclock feature.
> >  		*/
> >  		*has_reduced_clock =
> > -			dev_priv->display.find_dpll(limit, intel_crtc,
> > +			dev_priv->display.find_dpll(limit, crtc_state,
> >  						    dev_priv->lvds_downclock,
> >  						    refclk, clock,
> >  						    reduced_clock);
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config
  2015-03-19 20:55   ` Konduru, Chandra
@ 2015-03-20  6:41     ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-20  6:41 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 20:55 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 05/19] drm/i915: Update dummy connector atomic state with
> > current config
> > 
> > Keep that state updated so that we can write code that depends on it on the
> > follow up patches.
> > 
> > v2: Fix BUG() due to stale connector_state->crtc value. (Chandra)
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 41 ++++++++++++++++++++++++++++----
> > ----
> >  1 file changed, 32 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 62b9021..abdbd0c 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -10114,6 +10114,27 @@ static void
> > intel_modeset_update_staged_output_state(struct drm_device *dev)
> >  	}
> >  }
> > 
> > +/* 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.
> > + */
> > +static void intel_modeset_update_connector_atomic_state(struct
> > +drm_device *dev) {
> > +	struct intel_connector *connector;
> > +
> > +	for_each_intel_connector(dev, connector) {
> > +		if (connector->base.encoder) {
> > +			connector->base.state->best_encoder =
> > +				connector->base.encoder;
> > +			connector->base.state->crtc =
> > +				connector->base.encoder->crtc;
> > +		} else {
> > +			connector->base.state->best_encoder = NULL;
> > +			connector->base.state->crtc = NULL;
> > +		}
> > +	}
> > +}
> > +
> >  /**
> >   * intel_modeset_commit_output_state
> >   *
> > @@ -10137,6 +10158,8 @@ static void
> > intel_modeset_commit_output_state(struct drm_device *dev)
> >  		crtc->base.state->enable = crtc->new_enabled;
> >  		crtc->base.enabled = crtc->new_enabled;
> >  	}
> > +
> > +	intel_modeset_update_connector_atomic_state(dev);
> >  }
> > 
> >  static void
> > @@ -12876,15 +12899,13 @@ static void intel_setup_outputs(struct
> > drm_device *dev)
> >  	 * be removed since we'll be setting up real connector state, which
> >  	 * will contain Intel-specific properties.
> >  	 */
> > -	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
> > -		list_for_each_entry(connector,
> > -				    &dev->mode_config.connector_list,
> > -				    head) {
> > -			if (!WARN_ON(connector->state)) {
> > -				connector->state =
> > -					kzalloc(sizeof(*connector->state),
> > -						GFP_KERNEL);
> > -			}
> > +	/* FIXME: need to update the comment above. */
> 
> Can you fix the comment instead of adding another FIXME to fix it later?

Oh, I added that FIXME as a note to myself and then let it slip through.
I'll fix and resend.

> 
> > +	list_for_each_entry(connector,
> > +			    &dev->mode_config.connector_list,
> > +			    head) {
> > +		if (!WARN_ON(connector->state)) {
> 
> In intel_modeset_stage_output_state() there is a call to setup
> connector state:
> 	connector_state = drm_atomic_get_connector_state(state, &connector->base);
> Is that call is covering modeset via crtc_set_config() but not during init flow, so 
> doing it here?  
> If that is the case, we probably know that connector->state
> is never being set, so why have WARN_ON()?

The purpose of that WARN_ON is to remind us to remove this whole loop
when we implement connector_states with connector properties. Matt added
this here to avoid a NULL pointer dereference when using nuclear page
flip, but it should go away and be part of connector initialization.

Ander


> As lower level compute code is already 
> > +			connector->state = kzalloc(sizeof(*connector->state),
> > +						   GFP_KERNEL);
> >  		}
> >  	}
> > 
> > @@ -13937,6 +13958,8 @@ void intel_modeset_setup_hw_state(struct
> > drm_device *dev,
> >  				       "[setup_hw_state]");
> >  	}
> > 
> > +	intel_modeset_update_connector_atomic_state(dev);
> > +
> >  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> >  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> > 
> > --
> > 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] 52+ messages in thread

* Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-19 20:58   ` Konduru, Chandra
@ 2015-03-20  6:46     ` Conselvan De Oliveira, Ander
  2015-03-22 16:20       ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Conselvan De Oliveira, Ander @ 2015-03-20  6:46 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 20:58 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using
> > atomic state
> > 
> > Makes that code atomic ready.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 49 ++++++++++++++++++++++++++++++-
> > -----
> >  1 file changed, 42 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index e720a48..8c97186 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct
> > intel_connector *connector)
> >  	return encoder->get_hw_state(encoder, &pipe);  }
> > 
> > -static int pipe_required_fdi_lanes(struct drm_device *dev, enum pipe pipe)
> > +static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
> > +				   enum pipe pipe)
> >  {
> >  	struct intel_crtc *crtc =
> > -		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, pipe));
> > +	struct intel_crtc_state *crtc_state;
> > +
> > +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> > +	if (WARN_ON(IS_ERR(crtc_state))) {
> > +		/* Cause modeset to fail due to excess lanes. */
> > +		return 5;
> > +	}
> > 
> > -	if (crtc->base.state->enable &&
> > -	    crtc->config->has_pch_encoder)
> > +	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
> >  		return crtc->config->fdi_lanes;
> > 
> >  	return 0;
> > @@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct drm_device
> > *dev, enum pipe pipe)  static bool ironlake_check_fdi_lanes(struct drm_device
> > *dev, enum pipe pipe,
> >  				     struct intel_crtc_state *pipe_config)  {
> > +	struct drm_atomic_state *state = pipe_config->base.state;
> > +
> >  	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
> >  		      pipe_name(pipe), pipe_config->fdi_lanes);
> >  	if (pipe_config->fdi_lanes > 4) {
> > @@ -5579,7 +5588,7 @@ static bool ironlake_check_fdi_lanes(struct
> > drm_device *dev, enum pipe pipe,
> >  		return true;
> >  	case PIPE_B:
> >  		if (pipe_config->fdi_lanes > 2 &&
> > -		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
> > +		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
> >  			DRM_DEBUG_KMS("invalid shared fdi lane config on
> > pipe %c: %i lanes\n",
> >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> >  			return false;
> > @@ -5591,7 +5600,7 @@ static bool ironlake_check_fdi_lanes(struct
> > drm_device *dev, enum pipe pipe,
> >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> >  			return false;
> >  		}
> > -		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
> > +		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
> >  			DRM_DEBUG_KMS("fdi link B uses too many lanes to
> > enable link C\n");
> >  			return false;
> >  		}
> > @@ -5601,15 +5610,41 @@ static bool ironlake_check_fdi_lanes(struct
> > drm_device *dev, enum pipe pipe,
> >  	}
> >  }
> > 
> > +static int add_pipe_b_c_to_state(struct drm_atomic_state *state) {
> > +	struct intel_crtc *pipe_B =
> > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_B));
> > +	struct intel_crtc *pipe_C =
> > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_C));
> > +	struct intel_crtc_state *crtc_state;
> > +
> > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
> > +	if (IS_ERR(crtc_state))
> > +		return PTR_ERR(crtc_state);
> > +
> > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
> > +	if (IS_ERR(crtc_state))
> > +		return PTR_ERR(crtc_state);
> > +
> > +	return 0;
> > +}
> > +
> >  #define RETRY 1
> >  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> >  				       struct intel_crtc_state *pipe_config)  {
> >  	struct drm_device *dev = intel_crtc->base.dev;
> >  	struct drm_display_mode *adjusted_mode = &pipe_config-
> > >base.adjusted_mode;
> > -	int lane, link_bw, fdi_dotclock;
> > +	int lane, link_bw, fdi_dotclock, ret;
> >  	bool setup_ok, needs_recompute = false;
> > 
> > +	if (IS_IVYBRIDGE(dev) &&
> > +	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
> > +		ret = add_pipe_b_c_to_state(pipe_config->base.state);
> 
> In this scenario, crtc_states are created for both pipe B & C as an operation
> on one can affect the other. I may be missing something here, 
> but where is the other crtc_state being used: compute/check flow and/or 
> commit flow?

The function pipe_required_fdi_lanes() above is changed in this patch to
use the crtc_state in the drm atomic state to determined FDI lane
availability. At this point we don't yet allow changes to multiple
pipes, so the mode set is rejected if the pipe that is not being mode
set uses too many lanes.

Ander

> 
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> > +
> >  retry:
> >  	/* FDI is a binary signal running at ~2.7GHz, encoding
> >  	 * each output octet as 10 bits. The actual frequency
> > --
> > 2.1.0
> 

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-19 21:08   ` [PATCH 03/19] " Konduru, Chandra
@ 2015-03-20  7:00     ` Ander Conselvan De Oliveira
  2015-03-22 16:28       ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-20  7:00 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 21:08 +0000, Konduru, Chandra wrote:
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Friday, March 13, 2015 2:49 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > Subject: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy
> > modeset code
> > 
> > For the atomic conversion, the mode set paths need to be changed to rely on an
> > atomic state instead of using the staged config. By using an atomic state for the
> > legacy code, we will be able to convert the code base in small chunks.
> > 
> > v2: Squash patch that adds state argument to intel_set_mode(). (Ander)
> >     Make every caller of intel_set_mode() allocate state. (Daniel)
> >     Call drm_atomic_state_clear() in set config's error path. (Daniel)
> > 
> > Signed-off-by: Ander Conselvan de Oliveira
> > <ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 168 +++++++++++++++++++++++++++----
> > ----
> >  1 file changed, 133 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 78ea122..b61e3f6 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -37,6 +37,7 @@
> >  #include <drm/i915_drm.h>
> >  #include "i915_drv.h"
> >  #include "i915_trace.h"
> > +#include <drm/drm_atomic.h>
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_dp_helper.h>
> >  #include <drm/drm_crtc_helper.h>
> > @@ -82,7 +83,8 @@ 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_display_mode
> > *mode,
> > -			  int x, int y, struct drm_framebuffer *old_fb);
> > +			  int x, int y, struct drm_framebuffer *old_fb,
> > +			  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, @@
> > -8802,6 +8804,7 @@ bool intel_get_load_detect_pipe(struct drm_connector
> > *connector,
> >  	struct drm_device *dev = encoder->dev;
> >  	struct drm_framebuffer *fb;
> >  	struct drm_mode_config *config = &dev->mode_config;
> > +	struct drm_atomic_state *state = NULL;
> >  	int ret, i = -1;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> > -8883,6 +8886,12 @@ retry:
> >  	old->load_detect_temp = true;
> >  	old->release_fb = NULL;
> > 
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state)
> > +		return false;
> > +
> > +	state->acquire_ctx = ctx;
> > +
> >  	if (!mode)
> >  		mode = &load_detect_mode;
> > 
> > @@ -8905,7 +8914,7 @@ retry:
> >  		goto fail;
> >  	}
> > 
> > -	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
> > +	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
> > @@ -8924,6 +8933,11 @@ retry:
> >  	else
> >  		intel_crtc->new_config = NULL;
> 
> There are still occurrences of new_config, which you indicated killing them.
> Will you be sending out another version?

I indicated I have the intention of killing crtc->new_config, and I do
have patches in my private branch to that extent. However, I don't think
those patches are needed by this series, so I rather get this in first.

> Same applies to any new_xxx variables where they supposed to be in
> respective states or take them out.
> 
> crtc->new_crtc
> crtc->new_config
> crtc->new_enabled
> encoder->new_encoder
> dpll->new_config

I'm working on removing the usage of all those variables, and I'll
follow up with more patches. But we can't completely remove the staged
config util the hardware state readout code is converted to atomic,
since the force_restore path relies on the staged config containing the
"user requested" state.

This patch series is not all that is needed to remove the staged config,
but a big step in the right direction. The important bit here is not
whether or not the staged config still exists, but the fact that new
code can be written to not rely on it.

> In __intel_set_mode_setup_plls() before calling crtc_compute_clock()
> it is picking crtc_state from crtc->new_config. I think crtc_state should
> be a parameter to __intel_set_mode_setup_plls() and then pass
> further it to compute_clocks().

I have the following patch in a private branch:

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 43d0e43..1f1878f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11403,10 +11403,11 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
        return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
 }
 
-static int __intel_set_mode_setup_plls(struct drm_device *dev,
+static int __intel_set_mode_setup_plls(struct drm_atomic_state *state,
                                       unsigned modeset_pipes,
                                       unsigned disable_pipes)
 {
+       struct drm_device *dev = state->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        unsigned clear_pipes = modeset_pipes | disable_pipes;
        struct intel_crtc *intel_crtc;
@@ -11420,9 +11421,11 @@ static int __intel_set_mode_setup_plls(struct drm_device *dev,
                goto done;
 
        for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
-               struct intel_crtc_state *state = intel_crtc->new_config;
+               struct intel_crtc_state *crtc_state =
+                       intel_atomic_get_crtc_state(state, intel_crtc);
+
                ret = dev_priv->display.crtc_compute_clock(intel_crtc,
-                                                          state);
+                                                          crtc_state);
                if (ret) {
                        intel_shared_dpll_abort_config(dev_priv);
                        goto done;
@@ -11480,7 +11483,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
                prepare_pipes &= ~disable_pipes;
        }
 
-       ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes);
+       ret = __intel_set_mode_setup_plls(state, modeset_pipes, disable_pipes);
        if (ret)
                goto done;

Ander

> 
> 
> >  fail_unlock:
> > +	if (state) {
> > +		drm_atomic_state_free(state);
> > +		state = NULL;
> > +	}
> > +
> >  	if (ret == -EDEADLK) {
> >  		drm_modeset_backoff(ctx);
> >  		goto retry;
> > @@ -8936,22 +8950,34 @@ void intel_release_load_detect_pipe(struct
> > drm_connector *connector,
> >  				    struct intel_load_detect_pipe *old,
> >  				    struct drm_modeset_acquire_ctx *ctx)  {
> > +	struct drm_device *dev = connector->dev;
> >  	struct intel_encoder *intel_encoder =
> >  		intel_attached_encoder(connector);
> >  	struct drm_encoder *encoder = &intel_encoder->base;
> >  	struct drm_crtc *crtc = encoder->crtc;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +	struct drm_atomic_state *state;
> > 
> >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
> >  		      connector->base.id, connector->name,
> >  		      encoder->base.id, encoder->name);
> > 
> >  	if (old->load_detect_temp) {
> > +		state = drm_atomic_state_alloc(dev);
> > +		if (!state) {
> > +			DRM_DEBUG_KMS("can't release load detect pipe\n");
> > +			return;
> > +		}
> > +
> > +		state->acquire_ctx = ctx;
> > +
> >  		to_intel_connector(connector)->new_encoder = NULL;
> >  		intel_encoder->new_crtc = NULL;
> >  		intel_crtc->new_enabled = false;
> >  		intel_crtc->new_config = NULL;
> > -		intel_set_mode(crtc, NULL, 0, 0, NULL);
> > +		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> > +
> > +		drm_atomic_state_free(state);
> > 
> >  		if (old->release_fb) {
> >  			drm_framebuffer_unregister_private(old->release_fb);
> > @@ -10345,10 +10371,22 @@ static bool check_digital_port_conflicts(struct
> > drm_device *dev)
> >  	return true;
> >  }
> > 
> > -static struct intel_crtc_state *
> > +static void
> > +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) {
> > +	struct drm_crtc_state tmp_state;
> > +
> > +	/* Clear only the intel specific part of the crtc state */
> > +	tmp_state = crtc_state->base;
> > +	memset(crtc_state, 0, sizeof *crtc_state);
> > +	crtc_state->base = tmp_state;
> > +}
> > +
> > +static int
> >  intel_modeset_pipe_config(struct drm_crtc *crtc,
> >  			  struct drm_framebuffer *fb,
> > -			  struct drm_display_mode *mode)
> > +			  struct drm_display_mode *mode,
> > +			  struct drm_atomic_state *state)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct intel_encoder *encoder;
> > @@ -10358,17 +10396,19 @@ intel_modeset_pipe_config(struct drm_crtc
> > *crtc,
> > 
> >  	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
> >  		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> > -		return ERR_PTR(-EINVAL);
> > +		return -EINVAL;
> >  	}
> > 
> >  	if (!check_digital_port_conflicts(dev)) {
> >  		DRM_DEBUG_KMS("rejecting conflicting digital port
> > configuration\n");
> > -		return ERR_PTR(-EINVAL);
> > +		return -EINVAL;
> >  	}
> > 
> > -	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> > -	if (!pipe_config)
> > -		return ERR_PTR(-ENOMEM);
> > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > +	if (IS_ERR(pipe_config))
> > +		return PTR_ERR(pipe_config);
> > +
> > +	clear_intel_crtc_state(pipe_config);
> > 
> >  	pipe_config->base.crtc = crtc;
> >  	drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -
> > 10463,10 +10503,9 @@ encoder_retry:
> >  	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
> >  		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> > 
> > -	return pipe_config;
> > +	return 0;
> >  fail:
> > -	kfree(pipe_config);
> > -	return ERR_PTR(ret);
> > +	return ret;
> >  }
> > 
> >  /* Computes which crtcs are affected and sets the relevant bits in the mask. For
> > @@ -11144,17 +11183,19 @@ static struct intel_crtc_state *
> > intel_modeset_compute_config(struct drm_crtc *crtc,
> >  			     struct drm_display_mode *mode,
> >  			     struct drm_framebuffer *fb,
> > +			     struct drm_atomic_state *state,
> >  			     unsigned *modeset_pipes,
> >  			     unsigned *prepare_pipes,
> >  			     unsigned *disable_pipes)
> >  {
> >  	struct intel_crtc_state *pipe_config = NULL;
> > +	int ret = 0;
> > 
> >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> >  				     prepare_pipes, disable_pipes);
> > 
> >  	if ((*modeset_pipes) == 0)
> > -		goto out;
> > +		return NULL;
> > 
> >  	/*
> >  	 * Note this needs changes when we start tracking multiple modes @@ -
> > 11162,14 +11203,17 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
> >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> >  	 * for this crtc.
> >  	 */
> > -	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
> > -	if (IS_ERR(pipe_config)) {
> > -		goto out;
> > -	}
> > +	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > +	if (ret)
> > +		return ERR_PTR(ret);
> > +
> > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > +	if (IS_ERR(pipe_config))
> > +		return pipe_config;
> > +
> >  	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> >  			       "[modeset]");
> > 
> > -out:
> >  	return pipe_config;
> >  }
> > 
> > @@ -11214,6 +11258,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_display_mode *saved_mode;
> > +	struct intel_crtc_state *crtc_state_copy = NULL;
> >  	struct intel_crtc *intel_crtc;
> >  	int ret = 0;
> > 
> > @@ -11221,6 +11266,12 @@ static int __intel_set_mode(struct drm_crtc *crtc,
> >  	if (!saved_mode)
> >  		return -ENOMEM;
> > 
> > +	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
> > +	if (!crtc_state_copy) {
> > +		ret = -ENOMEM;
> > +		goto done;
> > +	}
> > +
> >  	*saved_mode = crtc->mode;
> > 
> >  	if (modeset_pipes)
> > @@ -11307,6 +11358,19 @@ done:
> >  	if (ret && crtc->state->enable)
> >  		crtc->mode = *saved_mode;
> > 
> > +	if (ret == 0 && pipe_config) {
> > +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +
> > +		/* The pipe_config will be freed with the atomic state, so
> > +		 * make a copy. */
> > +		memcpy(crtc_state_copy, intel_crtc->config,
> > +		       sizeof *crtc_state_copy);
> > +		intel_crtc->config = intel_crtc->new_config = crtc_state_copy;
> > +		intel_crtc->base.state = &crtc_state_copy->base;
> > +	} else {
> > +		kfree(crtc_state_copy);
> > +	}
> > +
> >  	kfree(saved_mode);
> >  	return ret;
> >  }
> > @@ -11332,27 +11396,51 @@ static int intel_set_mode_pipes(struct drm_crtc
> > *crtc,
> > 
> >  static int intel_set_mode(struct drm_crtc *crtc,
> >  			  struct drm_display_mode *mode,
> > -			  int x, int y, struct drm_framebuffer *fb)
> > +			  int x, int y, struct drm_framebuffer *fb,
> > +			  struct drm_atomic_state *state)
> >  {
> >  	struct intel_crtc_state *pipe_config;
> >  	unsigned modeset_pipes, prepare_pipes, disable_pipes;
> > +	int ret = 0;
> > 
> > -	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
> > +	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
> >  						   &modeset_pipes,
> >  						   &prepare_pipes,
> >  						   &disable_pipes);
> > 
> > -	if (IS_ERR(pipe_config))
> > -		return PTR_ERR(pipe_config);
> > +	if (IS_ERR(pipe_config)) {
> > +		ret = PTR_ERR(pipe_config);
> > +		goto out;
> > +	}
> > +
> > +	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > +				   modeset_pipes, prepare_pipes,
> > +				   disable_pipes);
> > +	if (ret)
> > +		goto out;
> > 
> > -	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > -				    modeset_pipes, prepare_pipes,
> > -				    disable_pipes);
> > +out:
> > +	return ret;
> >  }
> > 
> >  void intel_crtc_restore_mode(struct drm_crtc *crtc)  {
> > -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> > +	struct drm_device *dev = crtc->dev;
> > +	struct drm_atomic_state *state;
> > +
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state) {
> > +		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of
> > memory",
> > +			      crtc->base.id);
> > +		return;
> > +	}
> > +
> > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > +
> > +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
> > +		       state);
> > +
> > +	drm_atomic_state_free(state);
> >  }
> > 
> >  #undef for_each_intel_crtc_masked
> > @@ -11677,6 +11765,7 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)  {
> >  	struct drm_device *dev;
> >  	struct drm_mode_set save_set;
> > +	struct drm_atomic_state *state = NULL;
> >  	struct intel_set_config *config;
> >  	struct intel_crtc_state *pipe_config;
> >  	unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11721,12
> > +11810,20 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
> >  	 * such cases. */
> >  	intel_set_config_compute_mode_changes(set, config);
> > 
> > +	state = drm_atomic_state_alloc(dev);
> > +	if (!state) {
> > +		ret = -ENOMEM;
> > +		goto out_config;
> > +	}
> > +
> > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > +
> >  	ret = intel_modeset_stage_output_state(dev, set, config);
> >  	if (ret)
> >  		goto fail;
> > 
> >  	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
> > -						   set->fb,
> > +						   set->fb, state,
> >  						   &modeset_pipes,
> >  						   &prepare_pipes,
> >  						   &disable_pipes);
> > @@ -11746,10 +11843,6 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)
> >  		 */
> >  	}
> > 
> > -	/* set_mode will free it in the mode_changed case */
> > -	if (!config->mode_changed)
> > -		kfree(pipe_config);
> > -
> >  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> > 
> >  	if (config->mode_changed) {
> > @@ -11795,6 +11888,8 @@ static int intel_crtc_set_config(struct
> > drm_mode_set *set)
> >  fail:
> >  		intel_set_config_restore_state(dev, config);
> > 
> > +		drm_atomic_state_clear(state);
> > +
> >  		/*
> >  		 * HACK: if the pipe was on, but we didn't have a framebuffer,
> >  		 * force the pipe off to avoid oopsing in the modeset code @@
> > -11807,11 +11902,15 @@ fail:
> >  		/* Try to restore the config */
> >  		if (config->mode_changed &&
> >  		    intel_set_mode(save_set.crtc, save_set.mode,
> > -				   save_set.x, save_set.y, save_set.fb))
> > +				   save_set.x, save_set.y, save_set.fb,
> > +				   state))
> >  			DRM_ERROR("failed to restore config after modeset
> > failure\n");
> >  	}
> > 
> >  out_config:
> > +	if (state)
> > +		drm_atomic_state_free(state);
> > +
> >  	intel_set_config_free(config);
> >  	return ret;
> >  }
> > @@ -13852,8 +13951,7 @@ void intel_modeset_setup_hw_state(struct
> > drm_device *dev,
> >  			struct drm_crtc *crtc =
> >  				dev_priv->pipe_to_crtc_mapping[pipe];
> > 
> > -			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> > -				       crtc->primary->fb);
> > +			intel_crtc_restore_mode(crtc);
> >  		}
> >  	} else {
> >  		intel_modeset_update_staged_output_state(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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-19 23:23       ` Konduru, Chandra
@ 2015-03-20  8:40         ` Ander Conselvan De Oliveira
  2015-03-20  9:51           ` Daniel Vetter
  2015-03-22 16:46           ` Konduru, Chandra
  0 siblings, 2 replies; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-20  8:40 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Thu, 2015-03-19 at 23:23 +0000, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> > Sent: Thursday, March 19, 2015 12:52 AM
> > To: Konduru, Chandra
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is
> > being disabled
> > 
> > On Thu, 2015-03-19 at 00:12 +0000, Konduru, Chandra wrote:
> > >
> > > > -----Original Message-----
> > > > From: Conselvan De Oliveira, Ander
> > > > Sent: Friday, March 13, 2015 2:49 AM
> > > > To: intel-gfx@lists.freedesktop.org
> > > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > > Subject: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the
> > > > crtc is being disabled
> > > >
> > > > For consistency, allocate a new crtc_state for a crtc that is being disabled.
> > > > Previously only the enabled value of the current state would change.
> > > >
> > > > Signed-off-by: Ander Conselvan de Oliveira
> > > > <ander.conselvan.de.oliveira@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_display.c | 36
> > > > +++++++++++++++++++++++++--------
> > > > ---
> > > >  1 file changed, 25 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > > b/drivers/gpu/drm/i915/intel_display.c
> > > > index b61e3f6..62b9021 100644
> > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > @@ -11188,14 +11188,21 @@ intel_modeset_compute_config(struct
> > > > drm_crtc *crtc,
> > > >  			     unsigned *prepare_pipes,
> > > >  			     unsigned *disable_pipes)
> > > >  {
> > > > +	struct drm_device *dev = crtc->dev;
> > > >  	struct intel_crtc_state *pipe_config = NULL;
> > > > +	struct intel_crtc *intel_crtc;
> > > >  	int ret = 0;
> > > >
> > > >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> > > >  				     prepare_pipes, disable_pipes);
> > > >
> > > > -	if ((*modeset_pipes) == 0)
> > > > -		return NULL;
> > > > +	for_each_intel_crtc_masked(dev, *disable_pipes, intel_crtc) {
> > > > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > > > +		if (IS_ERR(pipe_config))
> > > > +			return pipe_config;
> > > > +
> > > > +		pipe_config->base.enable = false;
> > > > +	}
> > > >
> > > >  	/*
> > > >  	 * Note this needs changes when we start tracking multiple modes
> > > > @@ -
> > > > 11203,18 +11210,25 @@ intel_modeset_compute_config(struct drm_crtc
> > *crtc,
> > > >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> > > >  	 * for this crtc.
> > > >  	 */
> > > > -	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > > -	if (ret)
> > > > -		return ERR_PTR(ret);
> > > > +	for_each_intel_crtc_masked(dev, *modeset_pipes, intel_crtc) {
> > > > +		/* FIXME: For now we still expect modeset_pipes has at most
> > > > +		 * one bit set. */
> > > > +		if (WARN_ON(&intel_crtc->base != crtc))
> > > > +			continue;
> > > >
> > > > -	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > > -	if (IS_ERR(pipe_config))
> > > > -		return pipe_config;
> > > > +		ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > > +		if (ret)
> > > > +			return ERR_PTR(ret);
> > > > +
> > > > +		pipe_config = intel_atomic_get_crtc_state(state, intel_crtc);
> > > > +		if (IS_ERR(pipe_config))
> > > > +			return pipe_config;
> > > >
> > > > -	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > > > -			       "[modeset]");
> > > > +		intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > > > +				       "[modeset]");
> > > > +	}
> > > >
> > > > -	return pipe_config;
> > > > +	return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > >  }
> > >
> > > Instead of calling 3 separate intel_atomic_get_crtc_state() Can you
> > > have something like:
> > > intel_modeset_compute_config()
> > > {
> > > 	pipe_config = intel_atomic_get_crtc_state(state, crtc);
> > >
> > > 	for each disabled pipe {
> > > 		use pipe_config;
> > > 	}
> > >
> > > 	for each mode_set pipe {
> > > 		use pipe_config;
> > > 	}
> > >
> > > 	return pipe_config;
> > > }
> > >
> > >
> > > Or the way currently done is to cover where disable_pipes != modeset_pipes?
> > > By the way, when can it happen?
> > 
> > Yep, disable_pipes can be different than modeset_pipes if we the mode set
> > "steals" a connector. For instance, we could have pipe A driving
> > HDMI-1 and then mode set to pipe B to drive HDMI-1. Pipe B will steal the
> > encoder from pipe A, and cause it to be disable. In that case disable_pipes will
> > have the bit for pipe A set, while modeset_pipes will have the bit for pipe B set.
> 
> 1) 
> Consider two simple scenarios:  
> Case1: User code moving HDMI from A to B:
> drmModeSetCrtc(crtcA, HDMI);
> drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */
> 
> Case2: User code turning off HDMI:
> drmModeSetCrtc(crtcA, HDMI);
> drmModeSetCrtc(crtcA, disable);
> 
> In both cases, driver will be disabling crtc for pipe A. 
> In case 1, there is no associated crtc_state or compute & commit but 
> directly triggering crtc_disable(crtcA).
> In case 2, there is associated crtc_state and associated compute and setmode
> calls crtc_disable(crtcA);
> 
> Won't this cause trouble for low level functions (disable clocks, connectors, 
> encoders, planes etc. etc...) acting on variables being computed and staged 
> in their respective states?
>     where case 1 calls with current crtc->config, 
>     and case 2 calls crt->config which is computed crtc_state

It is inconsistent, yes. But at the moment, for the disable case, we
just duplicate the crtc_state and set crtc_state->base.enable = false.
As things stand at the moment, the net effect should be the same: we
call the disable hook before changing the current state, and after we
change the states, the only field that changed was
crtc_state->base.enable. The only difference is what does
intel_crtc->config points to.

> 2)
> For example, to disable a plane differentiate between below two:
> plane being called to disable with fb is valid
> 	vs.
> plane being called to disable with fb is null.
> 
> There is crtc->active somehow to take care this, but I think this should 
> move to crtc_state. Same applies for any such other variables in crtc. 
> And respective resource's functions should check its hosting crtc_state 
> along with its own conditions to act on its resource.
> 
> If not getting into this patch series, these changes should go into next 
> series for achieving crtc atomicity.

There's been discussion about crtc->active vs. crtc_state->base.active
already. One problem is that the atomic semantics is different than the
i915 one. We use crtc->active internally to mean the pipe is really
active, so we only turn that on in the enable crtc hook and immediately
disable it in the disable hook. We then use that value for sanity
checking.

The atomic active field may actually be true before we are finished
committing, so it may be true while the crtc is still off.

I think Matt had patches for this, but they were deferred until my patch
series goes in.

> 3)
> Also low level enable/disable functions can start causing confusion 
> if they aren't read/interpreted correctly. Either we should have resource_commit 
> which further calls resource->enable() or resource->disable() depending 
> on its own state and its hosting resource state; or have resource_commit 
> calling resource->update() where it does either enable or disable based 
> on state.
> 
> We don't have above for crtc but should be done something like this 
> if not in this patch but sometime after in order to achieve crtc atomicity.

We will need something like that for the implementation of the atomic
mode set, but I think we can treat that as an independent issue from
this patch series.


Ander

> 
> 
> > 
> > 
> > Ander
> > 
> > >
> > > >
> > > >  static int __intel_set_mode_setup_plls(struct drm_device *dev,
> > > > --
> > > > 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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-20  8:40         ` Ander Conselvan De Oliveira
@ 2015-03-20  9:51           ` Daniel Vetter
  2015-03-20 10:06             ` Ander Conselvan De Oliveira
  2015-03-22 16:46           ` Konduru, Chandra
  1 sibling, 1 reply; 52+ messages in thread
From: Daniel Vetter @ 2015-03-20  9:51 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx

On Fri, Mar 20, 2015 at 10:40:37AM +0200, Ander Conselvan De Oliveira wrote:
> On Thu, 2015-03-19 at 23:23 +0000, Konduru, Chandra wrote:
> > 1) 
> > Consider two simple scenarios:  
> > Case1: User code moving HDMI from A to B:
> > drmModeSetCrtc(crtcA, HDMI);
> > drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */
> > 
> > Case2: User code turning off HDMI:
> > drmModeSetCrtc(crtcA, HDMI);
> > drmModeSetCrtc(crtcA, disable);
> > 
> > In both cases, driver will be disabling crtc for pipe A. 
> > In case 1, there is no associated crtc_state or compute & commit but 
> > directly triggering crtc_disable(crtcA).
> > In case 2, there is associated crtc_state and associated compute and setmode
> > calls crtc_disable(crtcA);
> > 
> > Won't this cause trouble for low level functions (disable clocks, connectors, 
> > encoders, planes etc. etc...) acting on variables being computed and staged 
> > in their respective states?
> >     where case 1 calls with current crtc->config, 
> >     and case 2 calls crt->config which is computed crtc_state
> 
> It is inconsistent, yes. But at the moment, for the disable case, we
> just duplicate the crtc_state and set crtc_state->base.enable = false.
> As things stand at the moment, the net effect should be the same: we
> call the disable hook before changing the current state, and after we
> change the states, the only field that changed was
> crtc_state->base.enable. The only difference is what does
> intel_crtc->config points to.

I didn't digg into full details but don't we need to at least clear out
shared resources like plls too? Or is that all guarded with checks for
crtc_state->enable?

Overall it sounds like clearing the crtc state properly when duplicating
will be a lot of tricky fun.
-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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-20  9:51           ` Daniel Vetter
@ 2015-03-20 10:06             ` Ander Conselvan De Oliveira
  2015-03-20 10:39               ` Daniel Vetter
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-20 10:06 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Fri, 2015-03-20 at 10:51 +0100, Daniel Vetter wrote:
> On Fri, Mar 20, 2015 at 10:40:37AM +0200, Ander Conselvan De Oliveira wrote:
> > On Thu, 2015-03-19 at 23:23 +0000, Konduru, Chandra wrote:
> > > 1) 
> > > Consider two simple scenarios:  
> > > Case1: User code moving HDMI from A to B:
> > > drmModeSetCrtc(crtcA, HDMI);
> > > drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */
> > > 
> > > Case2: User code turning off HDMI:
> > > drmModeSetCrtc(crtcA, HDMI);
> > > drmModeSetCrtc(crtcA, disable);
> > > 
> > > In both cases, driver will be disabling crtc for pipe A. 
> > > In case 1, there is no associated crtc_state or compute & commit but 
> > > directly triggering crtc_disable(crtcA).
> > > In case 2, there is associated crtc_state and associated compute and setmode
> > > calls crtc_disable(crtcA);
> > > 
> > > Won't this cause trouble for low level functions (disable clocks, connectors, 
> > > encoders, planes etc. etc...) acting on variables being computed and staged 
> > > in their respective states?
> > >     where case 1 calls with current crtc->config, 
> > >     and case 2 calls crt->config which is computed crtc_state
> > 
> > It is inconsistent, yes. But at the moment, for the disable case, we
> > just duplicate the crtc_state and set crtc_state->base.enable = false.
> > As things stand at the moment, the net effect should be the same: we
> > call the disable hook before changing the current state, and after we
> > change the states, the only field that changed was
> > crtc_state->base.enable. The only difference is what does
> > intel_crtc->config points to.
> 
> I didn't digg into full details but don't we need to at least clear out
> shared resources like plls too? Or is that all guarded with checks for
> crtc_state->enable?

We don't update crtc_state->shared_dpll during disable. But the crtc off
function calls intel_put_shared_dpll() that removes the crtc from the
shared dpll's crtc mask (in global state). When we enable we allocate a
new state that has crtc_state->shared_dpll = DPLL_ID_PRIVATE.

Bottom line is, we don't rely on the old state when enabling a crtc.

> Overall it sounds like clearing the crtc state properly when duplicating
> will be a lot of tricky fun.

Yeah, sounds like there's still "fun" times ahead.

Ander

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

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

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-20 10:06             ` Ander Conselvan De Oliveira
@ 2015-03-20 10:39               ` Daniel Vetter
  0 siblings, 0 replies; 52+ messages in thread
From: Daniel Vetter @ 2015-03-20 10:39 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx

On Fri, Mar 20, 2015 at 12:06:46PM +0200, Ander Conselvan De Oliveira wrote:
> On Fri, 2015-03-20 at 10:51 +0100, Daniel Vetter wrote:
> > On Fri, Mar 20, 2015 at 10:40:37AM +0200, Ander Conselvan De Oliveira wrote:
> > > On Thu, 2015-03-19 at 23:23 +0000, Konduru, Chandra wrote:
> > > > 1) 
> > > > Consider two simple scenarios:  
> > > > Case1: User code moving HDMI from A to B:
> > > > drmModeSetCrtc(crtcA, HDMI);
> > > > drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */
> > > > 
> > > > Case2: User code turning off HDMI:
> > > > drmModeSetCrtc(crtcA, HDMI);
> > > > drmModeSetCrtc(crtcA, disable);
> > > > 
> > > > In both cases, driver will be disabling crtc for pipe A. 
> > > > In case 1, there is no associated crtc_state or compute & commit but 
> > > > directly triggering crtc_disable(crtcA).
> > > > In case 2, there is associated crtc_state and associated compute and setmode
> > > > calls crtc_disable(crtcA);
> > > > 
> > > > Won't this cause trouble for low level functions (disable clocks, connectors, 
> > > > encoders, planes etc. etc...) acting on variables being computed and staged 
> > > > in their respective states?
> > > >     where case 1 calls with current crtc->config, 
> > > >     and case 2 calls crt->config which is computed crtc_state
> > > 
> > > It is inconsistent, yes. But at the moment, for the disable case, we
> > > just duplicate the crtc_state and set crtc_state->base.enable = false.
> > > As things stand at the moment, the net effect should be the same: we
> > > call the disable hook before changing the current state, and after we
> > > change the states, the only field that changed was
> > > crtc_state->base.enable. The only difference is what does
> > > intel_crtc->config points to.
> > 
> > I didn't digg into full details but don't we need to at least clear out
> > shared resources like plls too? Or is that all guarded with checks for
> > crtc_state->enable?
> 
> We don't update crtc_state->shared_dpll during disable. But the crtc off
> function calls intel_put_shared_dpll() that removes the crtc from the
> shared dpll's crtc mask (in global state). When we enable we allocate a
> new state that has crtc_state->shared_dpll = DPLL_ID_PRIVATE.
> 
> Bottom line is, we don't rely on the old state when enabling a crtc.

Ah right I've missed that. Need to keep an eye out for this bit to make
sure we keep it working. Also it's another case where we change the states
still after the check phase, which is a big no-no in atomic land.

> > Overall it sounds like clearing the crtc state properly when duplicating
> > will be a lot of tricky fun.
> 
> Yeah, sounds like there's still "fun" times ahead.

Indeed.
-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] 52+ messages in thread

* Re: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to using atomic state
  2015-03-20  6:28     ` Ander Conselvan De Oliveira
@ 2015-03-22 16:14       ` Konduru, Chandra
  0 siblings, 0 replies; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-22 16:14 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx



> -----Original Message-----
> From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> Sent: Thursday, March 19, 2015 11:28 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to
> using atomic state
> 
> On Thu, 2015-03-19 at 19:24 +0000, Konduru, Chandra wrote:
> >
> > > -----Original Message-----
> > > From: Conselvan De Oliveira, Ander
> > > Sent: Friday, March 13, 2015 2:49 AM
> > > To: intel-gfx@lists.freedesktop.org
> > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > Subject: [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type()
> > > to using atomic state
> > >
> > > Pass a crtc_state to it and find whether the pipe has an encoder of
> > > a given type by looking at the drm_atomic_state the crtc_state points to.
> > >
> > > Until recently i9xx_get_refclk() used to be called indirectly from
> > > vlv_force_pll_on() with a dummy crtc_state. That dummy crtc state is
> > > not converted to be part of a full drm atomic state, so add a WARN
> > > in case someone decides to call that again with such a dummy state.
> > >
> > > v2: Warn if there is no connectors for a given crtc. (Daniel)
> > >     Replace comment i9xx_get_refclk() with a WARN_ON(). (Ander)
> > >
> > > Signed-off-by: Ander Conselvan de Oliveira
> > > <ander.conselvan.de.oliveira@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/i915_drv.h      |   2 +-
> > >  drivers/gpu/drm/i915/intel_display.c | 133
> > > +++++++++++++++++++++-------------
> > > -
> > >  2 files changed, 83 insertions(+), 52 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > > b/drivers/gpu/drm/i915/i915_drv.h index 490ab8c..576e101 100644
> > > --- a/drivers/gpu/drm/i915/i915_drv.h
> > > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > > @@ -541,7 +541,7 @@ struct drm_i915_display_funcs {
> > >  	 * Returns true on success, false on failure.
> > >  	 */
> > >  	bool (*find_dpll)(const struct intel_limit *limit,
> > > -			  struct intel_crtc *crtc,
> > > +			  struct intel_crtc_state *crtc_state,
> > >  			  int target, int refclk,
> > >  			  struct dpll *match_clock,
> > >  			  struct dpll *best_clock);
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index 8c97186..be1979e 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -431,25 +431,41 @@ bool intel_pipe_has_type(struct intel_crtc
> > > *crtc, enum intel_output_type type)
> > >   * intel_pipe_has_type() but looking at encoder->new_crtc instead of
> > >   * encoder->crtc.
> > >   */
> > > -static bool intel_pipe_will_have_type(struct intel_crtc *crtc, int
> > > type)
> > > +static bool intel_pipe_will_have_type(const struct intel_crtc_state
> *crtc_state,
> > > +				      int type)
> > >  {
> > > -	struct drm_device *dev = crtc->base.dev;
> > > +	struct drm_atomic_state *state = crtc_state->base.state;
> > > +	struct drm_connector_state *connector_state;
> > >  	struct intel_encoder *encoder;
> > > +	int i, num_connectors = 0;
> > > +
> > > +	for (i = 0; i < state->num_connector; i++) {
> > > +		if (!state->connectors[i])
> > > +			continue;
> > > +
> > > +		connector_state = state->connector_states[i];
> > > +		if (connector_state->crtc != crtc_state->base.crtc)
> > > +			continue;
> > > +
> > > +		num_connectors++;
> >
> > Above piece of code to loop through state->connectors[] is present in
> > multiple places, can you have a helper something like below to save
> > some typing and code reduction?
> >
> > struct connector_state * intel_crtc_state_connector(crtc_state, crtc);
> >
> > also similarily for encoder
> > struct encoder_state *intel_crtc_state_encoder(crtc_state, crtc);
> 
> This wouldn't work for cloned setups, where we have more than one
> connector/encoder in a single pipe.

May be it is for now. But as part of full atomic crtc, I think clone 
setup should be taken care by having this called from respective
crtcs and its crtc_states.

> 
> Ander
> 
> > >
> > > -	for_each_intel_encoder(dev, encoder)
> > > -		if (encoder->new_crtc == crtc && encoder->type == type)
> > > +		encoder = to_intel_encoder(connector_state->best_encoder);
> > > +		if (encoder->type == type)
> > >  			return true;
> > > +	}
> > > +
> > > +	WARN_ON(num_connectors == 0);
> > >
> > >  	return false;
> > >  }
> > >
> > > -static const intel_limit_t *intel_ironlake_limit(struct intel_crtc *crtc,
> > > -						int refclk)
> > > +static const intel_limit_t *
> > > +intel_ironlake_limit(struct intel_crtc_state *crtc_state, int
> > > +refclk)
> > >  {
> > > -	struct drm_device *dev = crtc->base.dev;
> > > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> > >  	const intel_limit_t *limit;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		if (intel_is_dual_link_lvds(dev)) {
> > >  			if (refclk == 100000)
> > >  				limit = &intel_limits_ironlake_dual_lvds_100m;
> > > @@ -467,20 +483,21 @@ static const intel_limit_t
> > > *intel_ironlake_limit(struct intel_crtc *crtc,
> > >  	return limit;
> > >  }
> > >
> > > -static const intel_limit_t *intel_g4x_limit(struct intel_crtc
> > > *crtc)
> > > +static const intel_limit_t *
> > > +intel_g4x_limit(struct intel_crtc_state *crtc_state)
> > >  {
> > > -	struct drm_device *dev = crtc->base.dev;
> > > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> > >  	const intel_limit_t *limit;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		if (intel_is_dual_link_lvds(dev))
> > >  			limit = &intel_limits_g4x_dual_channel_lvds;
> > >  		else
> > >  			limit = &intel_limits_g4x_single_channel_lvds;
> > > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI) ||
> > > -		   intel_pipe_will_have_type(crtc, INTEL_OUTPUT_ANALOG)) {
> > > +	} else if (intel_pipe_will_have_type(crtc_state,
> > > +INTEL_OUTPUT_HDMI)
> > > ||
> > > +		   intel_pipe_will_have_type(crtc_state,
> > > INTEL_OUTPUT_ANALOG)) {
> > >  		limit = &intel_limits_g4x_hdmi;
> > > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO)) {
> > > +	} else if (intel_pipe_will_have_type(crtc_state,
> > > +INTEL_OUTPUT_SDVO)) {
> > >  		limit = &intel_limits_g4x_sdvo;
> > >  	} else /* The option is for other outputs */
> > >  		limit = &intel_limits_i9xx_sdvo;
> > > @@ -488,17 +505,18 @@ static const intel_limit_t
> > > *intel_g4x_limit(struct intel_crtc *crtc)
> > >  	return limit;
> > >  }
> > >
> > > -static const intel_limit_t *intel_limit(struct intel_crtc *crtc,
> > > int refclk)
> > > +static const intel_limit_t *
> > > +intel_limit(struct intel_crtc_state *crtc_state, int refclk)
> > >  {
> > > -	struct drm_device *dev = crtc->base.dev;
> > > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> > >  	const intel_limit_t *limit;
> > >
> > >  	if (HAS_PCH_SPLIT(dev))
> > > -		limit = intel_ironlake_limit(crtc, refclk);
> > > +		limit = intel_ironlake_limit(crtc_state, refclk);
> > >  	else if (IS_G4X(dev)) {
> > > -		limit = intel_g4x_limit(crtc);
> > > +		limit = intel_g4x_limit(crtc_state);
> > >  	} else if (IS_PINEVIEW(dev)) {
> > > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > > +		if (intel_pipe_will_have_type(crtc_state,
> > > INTEL_OUTPUT_LVDS))
> > >  			limit = &intel_limits_pineview_lvds;
> > >  		else
> > >  			limit = &intel_limits_pineview_sdvo; @@ -507,14
> > > +525,14 @@ static const intel_limit_t *intel_limit(struct intel_crtc
> > > +*crtc, int
> > > refclk)
> > >  	} else if (IS_VALLEYVIEW(dev)) {
> > >  		limit = &intel_limits_vlv;
> > >  	} else if (!IS_GEN2(dev)) {
> > > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > > +		if (intel_pipe_will_have_type(crtc_state,
> > > INTEL_OUTPUT_LVDS))
> > >  			limit = &intel_limits_i9xx_lvds;
> > >  		else
> > >  			limit = &intel_limits_i9xx_sdvo;
> > >  	} else {
> > > -		if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > > +		if (intel_pipe_will_have_type(crtc_state,
> > > INTEL_OUTPUT_LVDS))
> > >  			limit = &intel_limits_i8xx_lvds;
> > > -		else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_DVO))
> > > +		else if (intel_pipe_will_have_type(crtc_state,
> > > INTEL_OUTPUT_DVO))
> > >  			limit = &intel_limits_i8xx_dvo;
> > >  		else
> > >  			limit = &intel_limits_i8xx_dac;
> > > @@ -601,15 +619,17 @@ static bool intel_PLL_is_valid(struct
> > > drm_device *dev, }
> > >
> > >  static bool
> > > -i9xx_find_best_dpll(const intel_limit_t *limit, struct intel_crtc
> > > *crtc,
> > > +i9xx_find_best_dpll(const intel_limit_t *limit,
> > > +		    struct intel_crtc_state *crtc_state,
> > >  		    int target, int refclk, intel_clock_t *match_clock,
> > >  		    intel_clock_t *best_clock)
> > >  {
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > >  	struct drm_device *dev = crtc->base.dev;
> > >  	intel_clock_t clock;
> > >  	int err = target;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		/*
> > >  		 * For LVDS just rely on its current settings for dual-channel.
> > >  		 * We haven't figured out how to reliably set up different @@ -
> > > 662,15 +682,17 @@ i9xx_find_best_dpll(const intel_limit_t *limit,
> > > struct intel_crtc *crtc,  }
> > >
> > >  static bool
> > > -pnv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc
> > > *crtc,
> > > +pnv_find_best_dpll(const intel_limit_t *limit,
> > > +		   struct intel_crtc_state *crtc_state,
> > >  		   int target, int refclk, intel_clock_t *match_clock,
> > >  		   intel_clock_t *best_clock)
> > >  {
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > >  	struct drm_device *dev = crtc->base.dev;
> > >  	intel_clock_t clock;
> > >  	int err = target;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		/*
> > >  		 * For LVDS just rely on its current settings for dual-channel.
> > >  		 * We haven't figured out how to reliably set up different @@ -
> > > 721,10 +743,12 @@ pnv_find_best_dpll(const intel_limit_t *limit,
> > > struct intel_crtc *crtc,  }
> > >
> > >  static bool
> > > -g4x_find_best_dpll(const intel_limit_t *limit, struct intel_crtc
> > > *crtc,
> > > +g4x_find_best_dpll(const intel_limit_t *limit,
> > > +		   struct intel_crtc_state *crtc_state,
> > >  		   int target, int refclk, intel_clock_t *match_clock,
> > >  		   intel_clock_t *best_clock)
> > >  {
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > >  	struct drm_device *dev = crtc->base.dev;
> > >  	intel_clock_t clock;
> > >  	int max_n;
> > > @@ -733,7 +757,7 @@ g4x_find_best_dpll(const intel_limit_t *limit,
> > > struct intel_crtc *crtc,
> > >  	int err_most = (target >> 8) + (target >> 9);
> > >  	found = false;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		if (intel_is_dual_link_lvds(dev))
> > >  			clock.p2 = limit->p2.p2_fast;
> > >  		else
> > > @@ -778,10 +802,12 @@ g4x_find_best_dpll(const intel_limit_t *limit,
> > > struct intel_crtc *crtc,  }
> > >
> > >  static bool
> > > -vlv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc
> > > *crtc,
> > > +vlv_find_best_dpll(const intel_limit_t *limit,
> > > +		   struct intel_crtc_state *crtc_state,
> > >  		   int target, int refclk, intel_clock_t *match_clock,
> > >  		   intel_clock_t *best_clock)
> > >  {
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > >  	struct drm_device *dev = crtc->base.dev;
> > >  	intel_clock_t clock;
> > >  	unsigned int bestppm = 1000000;
> > > @@ -835,10 +861,12 @@ vlv_find_best_dpll(const intel_limit_t *limit,
> > > struct intel_crtc *crtc,  }
> > >
> > >  static bool
> > > -chv_find_best_dpll(const intel_limit_t *limit, struct intel_crtc
> > > *crtc,
> > > +chv_find_best_dpll(const intel_limit_t *limit,
> > > +		   struct intel_crtc_state *crtc_state,
> > >  		   int target, int refclk, intel_clock_t *match_clock,
> > >  		   intel_clock_t *best_clock)
> > >  {
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > >  	struct drm_device *dev = crtc->base.dev;
> > >  	intel_clock_t clock;
> > >  	uint64_t m2;
> > > @@ -5726,7 +5754,7 @@ static int intel_crtc_compute_config(struct
> > > intel_crtc *crtc,
> > >  	 * - LVDS dual channel mode
> > >  	 * - Double wide pipe
> > >  	 */
> > > -	if ((intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > > +	if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) &&
> > >  	     intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
> > >  		pipe_config->pipe_src_w &= ~1;
> > >
> > > @@ -5905,15 +5933,18 @@ static inline bool
> > > intel_panel_use_ssc(struct drm_i915_private *dev_priv)
> > >  		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);  }
> > >
> > > -static int i9xx_get_refclk(struct intel_crtc *crtc, int
> > > num_connectors)
> > > +static int i9xx_get_refclk(const struct intel_crtc_state *crtc_state,
> > > +			   int num_connectors)
> > >  {
> > > -	struct drm_device *dev = crtc->base.dev;
> > > +	struct drm_device *dev = crtc_state->base.crtc->dev;
> > >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > >  	int refclk;
> > >
> > > +	WARN_ON(!crtc_state->base.state);
> > > +
> > >  	if (IS_VALLEYVIEW(dev)) {
> > >  		refclk = 100000;
> > > -	} else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > > +	} else if (intel_pipe_will_have_type(crtc_state,
> > > +INTEL_OUTPUT_LVDS)
> > > &&
> > >  	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
> > >  		refclk = dev_priv->vbt.lvds_ssc_freq;
> > >  		DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n",
> refclk);
> > > @@ -5956,7 +5987,7 @@ static void i9xx_update_pll_dividers(struct
> > > intel_crtc *crtc,
> > >  	crtc_state->dpll_hw_state.fp0 = fp;
> > >
> > >  	crtc->lowfreq_avail = false;
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> > >  	    reduced_clock && i915.powersave) {
> > >  		crtc_state->dpll_hw_state.fp1 = fp2;
> > >  		crtc->lowfreq_avail = true;
> > > @@ -6314,6 +6345,7 @@ 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 pipe_config = {
> > > +		.base.crtc = &crtc->base,
> > >  		.pixel_multiplier = 1,
> > >  		.dpll = *dpll,
> > >  	};
> > > @@ -6358,12 +6390,12 @@ static void i9xx_update_pll(struct
> > > intel_crtc *crtc,
> > >
> > >  	i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock);
> > >
> > > -	is_sdvo = intel_pipe_will_have_type(crtc, INTEL_OUTPUT_SDVO) ||
> > > -		intel_pipe_will_have_type(crtc, INTEL_OUTPUT_HDMI);
> > > +	is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)
> > > ||
> > > +		intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI);
> > >
> > >  	dpll = DPLL_VGA_MODE_DIS;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS))
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS))
> > >  		dpll |= DPLLB_MODE_LVDS;
> > >  	else
> > >  		dpll |= DPLLB_MODE_DAC_SERIAL;
> > > @@ -6406,7 +6438,7 @@ static void i9xx_update_pll(struct intel_crtc
> > > *crtc,
> > >
> > >  	if (crtc_state->sdvo_tv_clock)
> > >  		dpll |= PLL_REF_INPUT_TVCLKINBC;
> > > -	else if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > > +	else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)
> > > +&&
> > >  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> > >  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> > >  	else
> > > @@ -6436,7 +6468,7 @@ static void i8xx_update_pll(struct intel_crtc
> > > *crtc,
> > >
> > >  	dpll = DPLL_VGA_MODE_DIS;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS)) {
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) {
> > >  		dpll |= (1 << (clock->p1 - 1)) <<
> DPLL_FPA01_P1_POST_DIV_SHIFT;
> > >  	} else {
> > >  		if (clock->p1 == 2)
> > > @@ -6447,10 +6479,10 @@ static void i8xx_update_pll(struct intel_crtc
> *crtc,
> > >  			dpll |= PLL_P2_DIVIDE_BY_4;
> > >  	}
> > >
> > > -	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc,
> > > INTEL_OUTPUT_DVO))
> > > +	if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state,
> > > +INTEL_OUTPUT_DVO))
> > >  		dpll |= DPLL_DVO_2X_MODE;
> > >
> > > -	if (intel_pipe_will_have_type(crtc, INTEL_OUTPUT_LVDS) &&
> > > +	if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) &&
> > >  		 intel_panel_use_ssc(dev_priv) && num_connectors < 2)
> > >  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
> > >  	else
> > > @@ -6687,7 +6719,7 @@ static int i9xx_crtc_compute_clock(struct
> > > intel_crtc *crtc,
> > >  		return 0;
> > >
> > >  	if (!crtc_state->clock_set) {
> > > -		refclk = i9xx_get_refclk(crtc, num_connectors);
> > > +		refclk = i9xx_get_refclk(crtc_state, num_connectors);
> > >
> > >  		/*
> > >  		 * Returns a set of divisors for the desired target clock with @@
> > > -6695,8 +6727,8 @@ static int i9xx_crtc_compute_clock(struct intel_crtc
> *crtc,
> > >  		 * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
> > >  		 * 2) / p1 / p2.
> > >  		 */
> > > -		limit = intel_limit(crtc, refclk);
> > > -		ok = dev_priv->display.find_dpll(limit, crtc,
> > > +		limit = intel_limit(crtc_state, refclk);
> > > +		ok = dev_priv->display.find_dpll(limit, crtc_state,
> > >  						 crtc_state->port_clock,
> > >  						 refclk, NULL, &clock);
> > >  		if (!ok) {
> > > @@ -6712,7 +6744,7 @@ static int i9xx_crtc_compute_clock(struct
> > > intel_crtc *crtc,
> > >  			 * we will disable the LVDS downclock feature.
> > >  			 */
> > >  			has_reduced_clock =
> > > -				dev_priv->display.find_dpll(limit, crtc,
> > > +				dev_priv->display.find_dpll(limit, crtc_state,
> > >  							    dev_priv-
> > > >lvds_downclock,
> > >  							    refclk, &clock,
> > >  							    &reduced_clock);
> > > @@ -7540,12 +7572,11 @@ static bool ironlake_compute_clocks(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);
> > >  	int refclk;
> > >  	const intel_limit_t *limit;
> > >  	bool ret, is_lvds = false;
> > >
> > > -	is_lvds = intel_pipe_will_have_type(intel_crtc, INTEL_OUTPUT_LVDS);
> > > +	is_lvds = intel_pipe_will_have_type(crtc_state,
> > > +INTEL_OUTPUT_LVDS);
> > >
> > >  	refclk = ironlake_get_refclk(crtc);
> > >
> > > @@ -7554,8 +7585,8 @@ static bool ironlake_compute_clocks(struct
> > > drm_crtc *crtc,
> > >  	 * refclk, or FALSE.  The returned values represent the clock equation:
> > >  	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
> > >  	 */
> > > -	limit = intel_limit(intel_crtc, refclk);
> > > -	ret = dev_priv->display.find_dpll(limit, intel_crtc,
> > > +	limit = intel_limit(crtc_state, refclk);
> > > +	ret = dev_priv->display.find_dpll(limit, crtc_state,
> > >  					  crtc_state->port_clock,
> > >  					  refclk, NULL, clock);
> > >  	if (!ret)
> > > @@ -7569,7 +7600,7 @@ static bool ironlake_compute_clocks(struct
> > > drm_crtc *crtc,
> > >  		 * downclock feature.
> > >  		*/
> > >  		*has_reduced_clock =
> > > -			dev_priv->display.find_dpll(limit, intel_crtc,
> > > +			dev_priv->display.find_dpll(limit, crtc_state,
> > >  						    dev_priv->lvds_downclock,
> > >  						    refclk, clock,
> > >  						    reduced_clock);
> > > --
> > > 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] 52+ messages in thread

* Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-20  6:46     ` Conselvan De Oliveira, Ander
@ 2015-03-22 16:20       ` Konduru, Chandra
  2015-03-23  7:33         ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-22 16:20 UTC (permalink / raw)
  To: Conselvan De Oliveira, Ander; +Cc: intel-gfx



> -----Original Message-----
> From: Conselvan De Oliveira, Ander
> Sent: Thursday, March 19, 2015 11:46 PM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C
> using atomic state
> 
> On Thu, 2015-03-19 at 20:58 +0000, Konduru, Chandra wrote:
> >
> > > -----Original Message-----
> > > From: Conselvan De Oliveira, Ander
> > > Sent: Friday, March 13, 2015 2:49 AM
> > > To: intel-gfx@lists.freedesktop.org
> > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > Subject: [PATCH 16/19] drm/i915: Check lane sharing between pipes B
> > > & C using atomic state
> > >
> > > Makes that code atomic ready.
> > >
> > > Signed-off-by: Ander Conselvan de Oliveira
> > > <ander.conselvan.de.oliveira@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_display.c | 49
> > > ++++++++++++++++++++++++++++++-
> > > -----
> > >  1 file changed, 42 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index e720a48..8c97186 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct
> > > intel_connector *connector)
> > >  	return encoder->get_hw_state(encoder, &pipe);  }
> > >
> > > -static int pipe_required_fdi_lanes(struct drm_device *dev, enum
> > > pipe pipe)
> > > +static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
> > > +				   enum pipe pipe)
> > >  {
> > >  	struct intel_crtc *crtc =
> > > -		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, pipe));
> > > +	struct intel_crtc_state *crtc_state;
> > > +
> > > +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> > > +	if (WARN_ON(IS_ERR(crtc_state))) {
> > > +		/* Cause modeset to fail due to excess lanes. */
> > > +		return 5;
> > > +	}
> > >
> > > -	if (crtc->base.state->enable &&
> > > -	    crtc->config->has_pch_encoder)
> > > +	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
> > >  		return crtc->config->fdi_lanes;
> > >
> > >  	return 0;
> > > @@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct
> > > drm_device *dev, enum pipe pipe)  static bool
> > > ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
> > >  				     struct intel_crtc_state *pipe_config)  {
> > > +	struct drm_atomic_state *state = pipe_config->base.state;
> > > +
> > >  	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
> > >  		      pipe_name(pipe), pipe_config->fdi_lanes);
> > >  	if (pipe_config->fdi_lanes > 4) {
> > > @@ -5579,7 +5588,7 @@ static bool ironlake_check_fdi_lanes(struct
> > > drm_device *dev, enum pipe pipe,
> > >  		return true;
> > >  	case PIPE_B:
> > >  		if (pipe_config->fdi_lanes > 2 &&
> > > -		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
> > > +		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
> > >  			DRM_DEBUG_KMS("invalid shared fdi lane config on
> pipe %c: %i
> > > lanes\n",
> > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > >  			return false;
> > > @@ -5591,7 +5600,7 @@ static bool ironlake_check_fdi_lanes(struct
> > > drm_device *dev, enum pipe pipe,
> > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > >  			return false;
> > >  		}
> > > -		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
> > > +		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
> > >  			DRM_DEBUG_KMS("fdi link B uses too many lanes to
> enable link
> > > C\n");
> > >  			return false;
> > >  		}
> > > @@ -5601,15 +5610,41 @@ static bool ironlake_check_fdi_lanes(struct
> > > drm_device *dev, enum pipe pipe,
> > >  	}
> > >  }
> > >
> > > +static int add_pipe_b_c_to_state(struct drm_atomic_state *state) {
> > > +	struct intel_crtc *pipe_B =
> > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_B));
> > > +	struct intel_crtc *pipe_C =
> > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_C));
> > > +	struct intel_crtc_state *crtc_state;
> > > +
> > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
> > > +	if (IS_ERR(crtc_state))
> > > +		return PTR_ERR(crtc_state);
> > > +
> > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
> > > +	if (IS_ERR(crtc_state))
> > > +		return PTR_ERR(crtc_state);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  #define RETRY 1
> > >  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> > >  				       struct intel_crtc_state *pipe_config)  {
> > >  	struct drm_device *dev = intel_crtc->base.dev;
> > >  	struct drm_display_mode *adjusted_mode = &pipe_config-
> > > >base.adjusted_mode;
> > > -	int lane, link_bw, fdi_dotclock;
> > > +	int lane, link_bw, fdi_dotclock, ret;
> > >  	bool setup_ok, needs_recompute = false;
> > >
> > > +	if (IS_IVYBRIDGE(dev) &&
> > > +	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
> > > +		ret = add_pipe_b_c_to_state(pipe_config->base.state);
> >
> > In this scenario, crtc_states are created for both pipe B & C as an
> > operation on one can affect the other. I may be missing something
> > here, but where is the other crtc_state being used: compute/check flow
> > and/or commit flow?
> 
> The function pipe_required_fdi_lanes() above is changed in this patch to use the
> crtc_state in the drm atomic state to determined FDI lane availability. At this
> point we don't yet allow changes to multiple pipes, so the mode set is rejected if
> the pipe that is not being mode set uses too many lanes.

If request requires too many lanes then mode set is rejected, that is fine.
But my query is when the request requires lanes that can be supported.
In that case where the other crtc_state is being used?

> 
> Ander
> 
> >
> > > +		if (ret < 0)
> > > +			return ret;
> > > +	}
> > > +
> > >  retry:
> > >  	/* FDI is a binary signal running at ~2.7GHz, encoding
> > >  	 * each output octet as 10 bits. The actual frequency
> > > --
> > > 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] 52+ messages in thread

* Re: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code
  2015-03-20  7:00     ` Ander Conselvan De Oliveira
@ 2015-03-22 16:28       ` Konduru, Chandra
  0 siblings, 0 replies; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-22 16:28 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx



> -----Original Message-----
> From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> Sent: Friday, March 20, 2015 12:00 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the
> legacy modeset code
> 
> On Thu, 2015-03-19 at 21:08 +0000, Konduru, Chandra wrote:
> >
> > > -----Original Message-----
> > > From: Conselvan De Oliveira, Ander
> > > Sent: Friday, March 13, 2015 2:49 AM
> > > To: intel-gfx@lists.freedesktop.org
> > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > Subject: [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the
> > > legacy modeset code
> > >
> > > For the atomic conversion, the mode set paths need to be changed to
> > > rely on an atomic state instead of using the staged config. By using
> > > an atomic state for the legacy code, we will be able to convert the code base
> in small chunks.
> > >
> > > v2: Squash patch that adds state argument to intel_set_mode(). (Ander)
> > >     Make every caller of intel_set_mode() allocate state. (Daniel)
> > >     Call drm_atomic_state_clear() in set config's error path.
> > > (Daniel)
> > >
> > > Signed-off-by: Ander Conselvan de Oliveira
> > > <ander.conselvan.de.oliveira@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_display.c | 168
> > > +++++++++++++++++++++++++++----
> > > ----
> > >  1 file changed, 133 insertions(+), 35 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index 78ea122..b61e3f6 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -37,6 +37,7 @@
> > >  #include <drm/i915_drm.h>
> > >  #include "i915_drv.h"
> > >  #include "i915_trace.h"
> > > +#include <drm/drm_atomic.h>
> > >  #include <drm/drm_atomic_helper.h>
> > >  #include <drm/drm_dp_helper.h>
> > >  #include <drm/drm_crtc_helper.h>
> > > @@ -82,7 +83,8 @@ 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_display_mode *mode,
> > > -			  int x, int y, struct drm_framebuffer *old_fb);
> > > +			  int x, int y, struct drm_framebuffer *old_fb,
> > > +			  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, @@
> > > -8802,6 +8804,7 @@ bool intel_get_load_detect_pipe(struct
> > > drm_connector *connector,
> > >  	struct drm_device *dev = encoder->dev;
> > >  	struct drm_framebuffer *fb;
> > >  	struct drm_mode_config *config = &dev->mode_config;
> > > +	struct drm_atomic_state *state = NULL;
> > >  	int ret, i = -1;
> > >
> > >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", @@
> > > -8883,6 +8886,12 @@ retry:
> > >  	old->load_detect_temp = true;
> > >  	old->release_fb = NULL;
> > >
> > > +	state = drm_atomic_state_alloc(dev);
> > > +	if (!state)
> > > +		return false;
> > > +
> > > +	state->acquire_ctx = ctx;
> > > +
> > >  	if (!mode)
> > >  		mode = &load_detect_mode;
> > >
> > > @@ -8905,7 +8914,7 @@ retry:
> > >  		goto fail;
> > >  	}
> > >
> > > -	if (intel_set_mode(crtc, mode, 0, 0, fb)) {
> > > +	if (intel_set_mode(crtc, mode, 0, 0, fb, 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);
> > > @@ -8924,6 +8933,11 @@ retry:
> > >  	else
> > >  		intel_crtc->new_config = NULL;
> >
> > There are still occurrences of new_config, which you indicated killing them.
> > Will you be sending out another version?
> 
> I indicated I have the intention of killing crtc->new_config, and I do have
> patches in my private branch to that extent. However, I don't think those
> patches are needed by this series, so I rather get this in first.

That is fine if they are coming in next one.

> 
> > Same applies to any new_xxx variables where they supposed to be in
> > respective states or take them out.
> >
> > crtc->new_crtc
> > crtc->new_config
> > crtc->new_enabled
> > encoder->new_encoder
> > dpll->new_config
> 
> I'm working on removing the usage of all those variables, and I'll follow up with
> more patches. But we can't completely remove the staged config util the
> hardware state readout code is converted to atomic, since the force_restore
> path relies on the staged config containing the "user requested" state.
> 
> This patch series is not all that is needed to remove the staged config, but a big
> step in the right direction. The important bit here is not whether or not the
> staged config still exists, but the fact that new code can be written to not rely on
> it.

If these things are binned for next series that is fine.

> 
> > In __intel_set_mode_setup_plls() before calling crtc_compute_clock()
> > it is picking crtc_state from crtc->new_config. I think crtc_state
> > should be a parameter to __intel_set_mode_setup_plls() and then pass
> > further it to compute_clocks().
> 
> I have the following patch in a private branch:

Looks ok, but it would have less typing and code if crtc_state is simply
passed to it rather than calling helper to get it.

> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 43d0e43..1f1878f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11403,10 +11403,11 @@ intel_modeset_compute_config(struct drm_crtc
> *crtc,
>         return intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));  }
> 
> -static int __intel_set_mode_setup_plls(struct drm_device *dev,
> +static int __intel_set_mode_setup_plls(struct drm_atomic_state *state,
>                                        unsigned modeset_pipes,
>                                        unsigned disable_pipes)  {
> +       struct drm_device *dev = state->dev;
>         struct drm_i915_private *dev_priv = to_i915(dev);
>         unsigned clear_pipes = modeset_pipes | disable_pipes;
>         struct intel_crtc *intel_crtc;
> @@ -11420,9 +11421,11 @@ static int __intel_set_mode_setup_plls(struct
> drm_device *dev,
>                 goto done;
> 
>         for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
> -               struct intel_crtc_state *state = intel_crtc->new_config;
> +               struct intel_crtc_state *crtc_state =
> +                       intel_atomic_get_crtc_state(state, intel_crtc);
> +
>                 ret = dev_priv->display.crtc_compute_clock(intel_crtc,
> -                                                          state);
> +                                                          crtc_state);
>                 if (ret) {
>                         intel_shared_dpll_abort_config(dev_priv);
>                         goto done;
> @@ -11480,7 +11483,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
>                 prepare_pipes &= ~disable_pipes;
>         }
> 
> -       ret = __intel_set_mode_setup_plls(dev, modeset_pipes, disable_pipes);
> +       ret = __intel_set_mode_setup_plls(state, modeset_pipes,
> + disable_pipes);
>         if (ret)
>                 goto done;
> 
> Ander
> 
> >
> >
> > >  fail_unlock:
> > > +	if (state) {
> > > +		drm_atomic_state_free(state);
> > > +		state = NULL;
> > > +	}
> > > +
> > >  	if (ret == -EDEADLK) {
> > >  		drm_modeset_backoff(ctx);
> > >  		goto retry;
> > > @@ -8936,22 +8950,34 @@ void intel_release_load_detect_pipe(struct
> > > drm_connector *connector,
> > >  				    struct intel_load_detect_pipe *old,
> > >  				    struct drm_modeset_acquire_ctx *ctx)  {
> > > +	struct drm_device *dev = connector->dev;
> > >  	struct intel_encoder *intel_encoder =
> > >  		intel_attached_encoder(connector);
> > >  	struct drm_encoder *encoder = &intel_encoder->base;
> > >  	struct drm_crtc *crtc = encoder->crtc;
> > >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > +	struct drm_atomic_state *state;
> > >
> > >  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
> > >  		      connector->base.id, connector->name,
> > >  		      encoder->base.id, encoder->name);
> > >
> > >  	if (old->load_detect_temp) {
> > > +		state = drm_atomic_state_alloc(dev);
> > > +		if (!state) {
> > > +			DRM_DEBUG_KMS("can't release load detect pipe\n");
> > > +			return;
> > > +		}
> > > +
> > > +		state->acquire_ctx = ctx;
> > > +
> > >  		to_intel_connector(connector)->new_encoder = NULL;
> > >  		intel_encoder->new_crtc = NULL;
> > >  		intel_crtc->new_enabled = false;
> > >  		intel_crtc->new_config = NULL;
> > > -		intel_set_mode(crtc, NULL, 0, 0, NULL);
> > > +		intel_set_mode(crtc, NULL, 0, 0, NULL, state);
> > > +
> > > +		drm_atomic_state_free(state);
> > >
> > >  		if (old->release_fb) {
> > >  			drm_framebuffer_unregister_private(old->release_fb);
> > > @@ -10345,10 +10371,22 @@ static bool
> > > check_digital_port_conflicts(struct
> > > drm_device *dev)
> > >  	return true;
> > >  }
> > >
> > > -static struct intel_crtc_state *
> > > +static void
> > > +clear_intel_crtc_state(struct intel_crtc_state *crtc_state) {
> > > +	struct drm_crtc_state tmp_state;
> > > +
> > > +	/* Clear only the intel specific part of the crtc state */
> > > +	tmp_state = crtc_state->base;
> > > +	memset(crtc_state, 0, sizeof *crtc_state);
> > > +	crtc_state->base = tmp_state;
> > > +}
> > > +
> > > +static int
> > >  intel_modeset_pipe_config(struct drm_crtc *crtc,
> > >  			  struct drm_framebuffer *fb,
> > > -			  struct drm_display_mode *mode)
> > > +			  struct drm_display_mode *mode,
> > > +			  struct drm_atomic_state *state)
> > >  {
> > >  	struct drm_device *dev = crtc->dev;
> > >  	struct intel_encoder *encoder;
> > > @@ -10358,17 +10396,19 @@ intel_modeset_pipe_config(struct drm_crtc
> > > *crtc,
> > >
> > >  	if (!check_encoder_cloning(to_intel_crtc(crtc))) {
> > >  		DRM_DEBUG_KMS("rejecting invalid cloning configuration\n");
> > > -		return ERR_PTR(-EINVAL);
> > > +		return -EINVAL;
> > >  	}
> > >
> > >  	if (!check_digital_port_conflicts(dev)) {
> > >  		DRM_DEBUG_KMS("rejecting conflicting digital port
> > > configuration\n");
> > > -		return ERR_PTR(-EINVAL);
> > > +		return -EINVAL;
> > >  	}
> > >
> > > -	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> > > -	if (!pipe_config)
> > > -		return ERR_PTR(-ENOMEM);
> > > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > +	if (IS_ERR(pipe_config))
> > > +		return PTR_ERR(pipe_config);
> > > +
> > > +	clear_intel_crtc_state(pipe_config);
> > >
> > >  	pipe_config->base.crtc = crtc;
> > >  	drm_mode_copy(&pipe_config->base.adjusted_mode, mode); @@ -
> > > 10463,10 +10503,9 @@ encoder_retry:
> > >  	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
> > >  		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> > >
> > > -	return pipe_config;
> > > +	return 0;
> > >  fail:
> > > -	kfree(pipe_config);
> > > -	return ERR_PTR(ret);
> > > +	return ret;
> > >  }
> > >
> > >  /* Computes which crtcs are affected and sets the relevant bits in
> > > the mask. For @@ -11144,17 +11183,19 @@ static struct
> > > intel_crtc_state * intel_modeset_compute_config(struct drm_crtc *crtc,
> > >  			     struct drm_display_mode *mode,
> > >  			     struct drm_framebuffer *fb,
> > > +			     struct drm_atomic_state *state,
> > >  			     unsigned *modeset_pipes,
> > >  			     unsigned *prepare_pipes,
> > >  			     unsigned *disable_pipes)
> > >  {
> > >  	struct intel_crtc_state *pipe_config = NULL;
> > > +	int ret = 0;
> > >
> > >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> > >  				     prepare_pipes, disable_pipes);
> > >
> > >  	if ((*modeset_pipes) == 0)
> > > -		goto out;
> > > +		return NULL;
> > >
> > >  	/*
> > >  	 * Note this needs changes when we start tracking multiple modes
> > > @@ -
> > > 11162,14 +11203,17 @@ intel_modeset_compute_config(struct drm_crtc
> *crtc,
> > >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> > >  	 * for this crtc.
> > >  	 */
> > > -	pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
> > > -	if (IS_ERR(pipe_config)) {
> > > -		goto out;
> > > -	}
> > > +	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > +	if (ret)
> > > +		return ERR_PTR(ret);
> > > +
> > > +	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > +	if (IS_ERR(pipe_config))
> > > +		return pipe_config;
> > > +
> > >  	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > >  			       "[modeset]");
> > >
> > > -out:
> > >  	return pipe_config;
> > >  }
> > >
> > > @@ -11214,6 +11258,7 @@ static int __intel_set_mode(struct drm_crtc
> *crtc,
> > >  	struct drm_device *dev = crtc->dev;
> > >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > >  	struct drm_display_mode *saved_mode;
> > > +	struct intel_crtc_state *crtc_state_copy = NULL;
> > >  	struct intel_crtc *intel_crtc;
> > >  	int ret = 0;
> > >
> > > @@ -11221,6 +11266,12 @@ static int __intel_set_mode(struct drm_crtc
> *crtc,
> > >  	if (!saved_mode)
> > >  		return -ENOMEM;
> > >
> > > +	crtc_state_copy = kmalloc(sizeof(*crtc_state_copy), GFP_KERNEL);
> > > +	if (!crtc_state_copy) {
> > > +		ret = -ENOMEM;
> > > +		goto done;
> > > +	}
> > > +
> > >  	*saved_mode = crtc->mode;
> > >
> > >  	if (modeset_pipes)
> > > @@ -11307,6 +11358,19 @@ done:
> > >  	if (ret && crtc->state->enable)
> > >  		crtc->mode = *saved_mode;
> > >
> > > +	if (ret == 0 && pipe_config) {
> > > +		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > > +
> > > +		/* The pipe_config will be freed with the atomic state, so
> > > +		 * make a copy. */
> > > +		memcpy(crtc_state_copy, intel_crtc->config,
> > > +		       sizeof *crtc_state_copy);
> > > +		intel_crtc->config = intel_crtc->new_config = crtc_state_copy;
> > > +		intel_crtc->base.state = &crtc_state_copy->base;
> > > +	} else {
> > > +		kfree(crtc_state_copy);
> > > +	}
> > > +
> > >  	kfree(saved_mode);
> > >  	return ret;
> > >  }
> > > @@ -11332,27 +11396,51 @@ static int intel_set_mode_pipes(struct
> > > drm_crtc *crtc,
> > >
> > >  static int intel_set_mode(struct drm_crtc *crtc,
> > >  			  struct drm_display_mode *mode,
> > > -			  int x, int y, struct drm_framebuffer *fb)
> > > +			  int x, int y, struct drm_framebuffer *fb,
> > > +			  struct drm_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *pipe_config;
> > >  	unsigned modeset_pipes, prepare_pipes, disable_pipes;
> > > +	int ret = 0;
> > >
> > > -	pipe_config = intel_modeset_compute_config(crtc, mode, fb,
> > > +	pipe_config = intel_modeset_compute_config(crtc, mode, fb, state,
> > >  						   &modeset_pipes,
> > >  						   &prepare_pipes,
> > >  						   &disable_pipes);
> > >
> > > -	if (IS_ERR(pipe_config))
> > > -		return PTR_ERR(pipe_config);
> > > +	if (IS_ERR(pipe_config)) {
> > > +		ret = PTR_ERR(pipe_config);
> > > +		goto out;
> > > +	}
> > > +
> > > +	ret = intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > > +				   modeset_pipes, prepare_pipes,
> > > +				   disable_pipes);
> > > +	if (ret)
> > > +		goto out;
> > >
> > > -	return intel_set_mode_pipes(crtc, mode, x, y, fb, pipe_config,
> > > -				    modeset_pipes, prepare_pipes,
> > > -				    disable_pipes);
> > > +out:
> > > +	return ret;
> > >  }
> > >
> > >  void intel_crtc_restore_mode(struct drm_crtc *crtc)  {
> > > -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> > > +	struct drm_device *dev = crtc->dev;
> > > +	struct drm_atomic_state *state;
> > > +
> > > +	state = drm_atomic_state_alloc(dev);
> > > +	if (!state) {
> > > +		DRM_DEBUG_KMS("[CRTC:%d] mode restore failed, out of
> > > memory",
> > > +			      crtc->base.id);
> > > +		return;
> > > +	}
> > > +
> > > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > > +
> > > +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb,
> > > +		       state);
> > > +
> > > +	drm_atomic_state_free(state);
> > >  }
> > >
> > >  #undef for_each_intel_crtc_masked
> > > @@ -11677,6 +11765,7 @@ static int intel_crtc_set_config(struct
> > > drm_mode_set *set)  {
> > >  	struct drm_device *dev;
> > >  	struct drm_mode_set save_set;
> > > +	struct drm_atomic_state *state = NULL;
> > >  	struct intel_set_config *config;
> > >  	struct intel_crtc_state *pipe_config;
> > >  	unsigned modeset_pipes, prepare_pipes, disable_pipes; @@ -11721,12
> > > +11810,20 @@ static int intel_crtc_set_config(struct drm_mode_set
> > > +*set)
> > >  	 * such cases. */
> > >  	intel_set_config_compute_mode_changes(set, config);
> > >
> > > +	state = drm_atomic_state_alloc(dev);
> > > +	if (!state) {
> > > +		ret = -ENOMEM;
> > > +		goto out_config;
> > > +	}
> > > +
> > > +	state->acquire_ctx = dev->mode_config.acquire_ctx;
> > > +
> > >  	ret = intel_modeset_stage_output_state(dev, set, config);
> > >  	if (ret)
> > >  		goto fail;
> > >
> > >  	pipe_config = intel_modeset_compute_config(set->crtc, set->mode,
> > > -						   set->fb,
> > > +						   set->fb, state,
> > >  						   &modeset_pipes,
> > >  						   &prepare_pipes,
> > >  						   &disable_pipes);
> > > @@ -11746,10 +11843,6 @@ static int intel_crtc_set_config(struct
> > > drm_mode_set *set)
> > >  		 */
> > >  	}
> > >
> > > -	/* set_mode will free it in the mode_changed case */
> > > -	if (!config->mode_changed)
> > > -		kfree(pipe_config);
> > > -
> > >  	intel_update_pipe_size(to_intel_crtc(set->crtc));
> > >
> > >  	if (config->mode_changed) {
> > > @@ -11795,6 +11888,8 @@ static int intel_crtc_set_config(struct
> > > drm_mode_set *set)
> > >  fail:
> > >  		intel_set_config_restore_state(dev, config);
> > >
> > > +		drm_atomic_state_clear(state);
> > > +
> > >  		/*
> > >  		 * HACK: if the pipe was on, but we didn't have a framebuffer,
> > >  		 * force the pipe off to avoid oopsing in the modeset code @@
> > > -11807,11 +11902,15 @@ fail:
> > >  		/* Try to restore the config */
> > >  		if (config->mode_changed &&
> > >  		    intel_set_mode(save_set.crtc, save_set.mode,
> > > -				   save_set.x, save_set.y, save_set.fb))
> > > +				   save_set.x, save_set.y, save_set.fb,
> > > +				   state))
> > >  			DRM_ERROR("failed to restore config after modeset
> failure\n");
> > >  	}
> > >
> > >  out_config:
> > > +	if (state)
> > > +		drm_atomic_state_free(state);
> > > +
> > >  	intel_set_config_free(config);
> > >  	return ret;
> > >  }
> > > @@ -13852,8 +13951,7 @@ void intel_modeset_setup_hw_state(struct
> > > drm_device *dev,
> > >  			struct drm_crtc *crtc =
> > >  				dev_priv->pipe_to_crtc_mapping[pipe];
> > >
> > > -			intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> > > -				       crtc->primary->fb);
> > > +			intel_crtc_restore_mode(crtc);
> > >  		}
> > >  	} else {
> > >  		intel_modeset_update_staged_output_state(dev);
> > > --
> > > 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] 52+ messages in thread

* Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled
  2015-03-20  8:40         ` Ander Conselvan De Oliveira
  2015-03-20  9:51           ` Daniel Vetter
@ 2015-03-22 16:46           ` Konduru, Chandra
  1 sibling, 0 replies; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-22 16:46 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx



> -----Original Message-----
> From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> Sent: Friday, March 20, 2015 1:41 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org; Roper, Matthew D
> Subject: Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is
> being disabled
> 
> On Thu, 2015-03-19 at 23:23 +0000, Konduru, Chandra wrote:
> >
> >
> > > -----Original Message-----
> > > From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> > > Sent: Thursday, March 19, 2015 12:52 AM
> > > To: Konduru, Chandra
> > > Cc: intel-gfx@lists.freedesktop.org
> > > Subject: Re: [PATCH 04/19] drm/i915: Allocate a crtc_state also when
> > > the crtc is being disabled
> > >
> > > On Thu, 2015-03-19 at 00:12 +0000, Konduru, Chandra wrote:
> > > >
> > > > > -----Original Message-----
> > > > > From: Conselvan De Oliveira, Ander
> > > > > Sent: Friday, March 13, 2015 2:49 AM
> > > > > To: intel-gfx@lists.freedesktop.org
> > > > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > > > Subject: [PATCH 04/19] drm/i915: Allocate a crtc_state also when
> > > > > the crtc is being disabled
> > > > >
> > > > > For consistency, allocate a new crtc_state for a crtc that is being
> disabled.
> > > > > Previously only the enabled value of the current state would change.
> > > > >
> > > > > Signed-off-by: Ander Conselvan de Oliveira
> > > > > <ander.conselvan.de.oliveira@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/intel_display.c | 36
> > > > > +++++++++++++++++++++++++--------
> > > > > ---
> > > > >  1 file changed, 25 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > > > b/drivers/gpu/drm/i915/intel_display.c
> > > > > index b61e3f6..62b9021 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > > @@ -11188,14 +11188,21 @@ intel_modeset_compute_config(struct
> > > > > drm_crtc *crtc,
> > > > >  			     unsigned *prepare_pipes,
> > > > >  			     unsigned *disable_pipes)  {
> > > > > +	struct drm_device *dev = crtc->dev;
> > > > >  	struct intel_crtc_state *pipe_config = NULL;
> > > > > +	struct intel_crtc *intel_crtc;
> > > > >  	int ret = 0;
> > > > >
> > > > >  	intel_modeset_affected_pipes(crtc, modeset_pipes,
> > > > >  				     prepare_pipes, disable_pipes);
> > > > >
> > > > > -	if ((*modeset_pipes) == 0)
> > > > > -		return NULL;
> > > > > +	for_each_intel_crtc_masked(dev, *disable_pipes, intel_crtc) {
> > > > > +		pipe_config = intel_atomic_get_crtc_state(state,
> intel_crtc);
> > > > > +		if (IS_ERR(pipe_config))
> > > > > +			return pipe_config;
> > > > > +
> > > > > +		pipe_config->base.enable = false;
> > > > > +	}
> > > > >
> > > > >  	/*
> > > > >  	 * Note this needs changes when we start tracking multiple
> > > > > modes @@ -
> > > > > 11203,18 +11210,25 @@ intel_modeset_compute_config(struct
> > > > > drm_crtc
> > > *crtc,
> > > > >  	 * (i.e. one pipe_config for each crtc) rather than just the one
> > > > >  	 * for this crtc.
> > > > >  	 */
> > > > > -	ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > > > -	if (ret)
> > > > > -		return ERR_PTR(ret);
> > > > > +	for_each_intel_crtc_masked(dev, *modeset_pipes, intel_crtc) {
> > > > > +		/* FIXME: For now we still expect modeset_pipes has at
> most
> > > > > +		 * one bit set. */
> > > > > +		if (WARN_ON(&intel_crtc->base != crtc))
> > > > > +			continue;
> > > > >
> > > > > -	pipe_config = intel_atomic_get_crtc_state(state, to_intel_crtc(crtc));
> > > > > -	if (IS_ERR(pipe_config))
> > > > > -		return pipe_config;
> > > > > +		ret = intel_modeset_pipe_config(crtc, fb, mode, state);
> > > > > +		if (ret)
> > > > > +			return ERR_PTR(ret);
> > > > > +
> > > > > +		pipe_config = intel_atomic_get_crtc_state(state,
> intel_crtc);
> > > > > +		if (IS_ERR(pipe_config))
> > > > > +			return pipe_config;
> > > > >
> > > > > -	intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
> > > > > -			       "[modeset]");
> > > > > +		intel_dump_pipe_config(to_intel_crtc(crtc),
> pipe_config,
> > > > > +				       "[modeset]");
> > > > > +	}
> > > > >
> > > > > -	return pipe_config;
> > > > > +	return intel_atomic_get_crtc_state(state,
> > > > > +to_intel_crtc(crtc));
> > > > >  }
> > > >
> > > > Instead of calling 3 separate intel_atomic_get_crtc_state() Can
> > > > you have something like:
> > > > intel_modeset_compute_config()
> > > > {
> > > > 	pipe_config = intel_atomic_get_crtc_state(state, crtc);
> > > >
> > > > 	for each disabled pipe {
> > > > 		use pipe_config;
> > > > 	}
> > > >
> > > > 	for each mode_set pipe {
> > > > 		use pipe_config;
> > > > 	}
> > > >
> > > > 	return pipe_config;
> > > > }
> > > >
> > > >
> > > > Or the way currently done is to cover where disable_pipes !=
> modeset_pipes?
> > > > By the way, when can it happen?
> > >
> > > Yep, disable_pipes can be different than modeset_pipes if we the
> > > mode set "steals" a connector. For instance, we could have pipe A
> > > driving
> > > HDMI-1 and then mode set to pipe B to drive HDMI-1. Pipe B will
> > > steal the encoder from pipe A, and cause it to be disable. In that
> > > case disable_pipes will have the bit for pipe A set, while modeset_pipes will
> have the bit for pipe B set.
> >
> > 1)
> > Consider two simple scenarios:
> > Case1: User code moving HDMI from A to B:
> > drmModeSetCrtc(crtcA, HDMI);
> > drmModeSetCrtc(crtcB, HDMI); /* moving HDMI to pipe B */
> >
> > Case2: User code turning off HDMI:
> > drmModeSetCrtc(crtcA, HDMI);
> > drmModeSetCrtc(crtcA, disable);
> >
> > In both cases, driver will be disabling crtc for pipe A.
> > In case 1, there is no associated crtc_state or compute & commit but
> > directly triggering crtc_disable(crtcA).
> > In case 2, there is associated crtc_state and associated compute and
> > setmode calls crtc_disable(crtcA);
> >
> > Won't this cause trouble for low level functions (disable clocks,
> > connectors, encoders, planes etc. etc...) acting on variables being
> > computed and staged in their respective states?
> >     where case 1 calls with current crtc->config,
> >     and case 2 calls crt->config which is computed crtc_state
> 
> It is inconsistent, yes. But at the moment, for the disable case, we just duplicate
> the crtc_state and set crtc_state->base.enable = false.
> As things stand at the moment, the net effect should be the same: we call the
> disable hook before changing the current state, and after we change the states,
> the only field that changed was crtc_state->base.enable. The only difference is
> what does intel_crtc->config points to.

As things stand atm, this may be ok. But as soon as low level functions
truly depend on state and its hosting crtc state to act on, this becomes
an issue if crtc->config pointing to new state vs. current state.
I saw this as an issue while implementing scalers, but managed to make
it work. 
I think this is one another next steps as part of full atomic crtc.

> 
> > 2)
> > For example, to disable a plane differentiate between below two:
> > plane being called to disable with fb is valid
> > 	vs.
> > plane being called to disable with fb is null.
> >
> > There is crtc->active somehow to take care this, but I think this
> > should move to crtc_state. Same applies for any such other variables in crtc.
> > And respective resource's functions should check its hosting
> > crtc_state along with its own conditions to act on its resource.
> >
> > If not getting into this patch series, these changes should go into
> > next series for achieving crtc atomicity.
> 
> There's been discussion about crtc->active vs. crtc_state->base.active already.
> One problem is that the atomic semantics is different than the
> i915 one. 

Yeah, this is something we need to settle on.

> We use crtc->active internally to mean the pipe is really active, so we
> only turn that on in the enable crtc hook and immediately disable it in the disable
> hook. We then use that value for sanity checking.

I think it seems opposite to the atomic semantics. But will we be using
crtc_state->base.active in atomic semantics way? May be need to settle
on in next steps after this series if not now.

> 
> The atomic active field may actually be true before we are finished committing,
> so it may be true while the crtc is still off.
> 
> I think Matt had patches for this, but they were deferred until my patch series
> goes in.
> 
> > 3)
> > Also low level enable/disable functions can start causing confusion if
> > they aren't read/interpreted correctly. Either we should have
> > resource_commit which further calls resource->enable() or
> > resource->disable() depending on its own state and its hosting
> > resource state; or have resource_commit calling resource->update()
> > where it does either enable or disable based on state.
> >
> > We don't have above for crtc but should be done something like this if
> > not in this patch but sometime after in order to achieve crtc atomicity.
> 
> We will need something like that for the implementation of the atomic mode
> set, but I think we can treat that as an independent issue from this patch series.

That is fine as long as it is binned for next time.

> 
> 
> Ander
> 
> >
> >
> > >
> > >
> > > Ander
> > >
> > > >
> > > > >
> > > > >  static int __intel_set_mode_setup_plls(struct drm_device *dev,
> > > > > --
> > > > > 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] 52+ messages in thread

* Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-22 16:20       ` Konduru, Chandra
@ 2015-03-23  7:33         ` Ander Conselvan De Oliveira
  2015-03-23 16:57           ` Konduru, Chandra
  0 siblings, 1 reply; 52+ messages in thread
From: Ander Conselvan De Oliveira @ 2015-03-23  7:33 UTC (permalink / raw)
  To: Konduru, Chandra; +Cc: intel-gfx

On Sun, 2015-03-22 at 16:20 +0000, Konduru, Chandra wrote:
> 
> 
> > -----Original Message-----
> > From: Conselvan De Oliveira, Ander
> > Sent: Thursday, March 19, 2015 11:46 PM
> > To: Konduru, Chandra
> > Cc: intel-gfx@lists.freedesktop.org
> > Subject: Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C
> > using atomic state
> > 
> > On Thu, 2015-03-19 at 20:58 +0000, Konduru, Chandra wrote:
> > >
> > > > -----Original Message-----
> > > > From: Conselvan De Oliveira, Ander
> > > > Sent: Friday, March 13, 2015 2:49 AM
> > > > To: intel-gfx@lists.freedesktop.org
> > > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > > Subject: [PATCH 16/19] drm/i915: Check lane sharing between pipes B
> > > > & C using atomic state
> > > >
> > > > Makes that code atomic ready.
> > > >
> > > > Signed-off-by: Ander Conselvan de Oliveira
> > > > <ander.conselvan.de.oliveira@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_display.c | 49
> > > > ++++++++++++++++++++++++++++++-
> > > > -----
> > > >  1 file changed, 42 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > > b/drivers/gpu/drm/i915/intel_display.c
> > > > index e720a48..8c97186 100644
> > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > @@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct
> > > > intel_connector *connector)
> > > >  	return encoder->get_hw_state(encoder, &pipe);  }
> > > >
> > > > -static int pipe_required_fdi_lanes(struct drm_device *dev, enum
> > > > pipe pipe)
> > > > +static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
> > > > +				   enum pipe pipe)
> > > >  {
> > > >  	struct intel_crtc *crtc =
> > > > -		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, pipe));
> > > > +	struct intel_crtc_state *crtc_state;
> > > > +
> > > > +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> > > > +	if (WARN_ON(IS_ERR(crtc_state))) {
> > > > +		/* Cause modeset to fail due to excess lanes. */
> > > > +		return 5;
> > > > +	}
> > > >
> > > > -	if (crtc->base.state->enable &&
> > > > -	    crtc->config->has_pch_encoder)
> > > > +	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
> > > >  		return crtc->config->fdi_lanes;
> > > >
> > > >  	return 0;
> > > > @@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct
> > > > drm_device *dev, enum pipe pipe)  static bool
> > > > ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
> > > >  				     struct intel_crtc_state *pipe_config)  {
> > > > +	struct drm_atomic_state *state = pipe_config->base.state;
> > > > +
> > > >  	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
> > > >  		      pipe_name(pipe), pipe_config->fdi_lanes);
> > > >  	if (pipe_config->fdi_lanes > 4) {
> > > > @@ -5579,7 +5588,7 @@ static bool ironlake_check_fdi_lanes(struct
> > > > drm_device *dev, enum pipe pipe,
> > > >  		return true;
> > > >  	case PIPE_B:
> > > >  		if (pipe_config->fdi_lanes > 2 &&
> > > > -		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
> > > > +		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
> > > >  			DRM_DEBUG_KMS("invalid shared fdi lane config on
> > pipe %c: %i
> > > > lanes\n",
> > > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > > >  			return false;
> > > > @@ -5591,7 +5600,7 @@ static bool ironlake_check_fdi_lanes(struct
> > > > drm_device *dev, enum pipe pipe,
> > > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > > >  			return false;
> > > >  		}
> > > > -		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
> > > > +		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
> > > >  			DRM_DEBUG_KMS("fdi link B uses too many lanes to
> > enable link
> > > > C\n");
> > > >  			return false;
> > > >  		}
> > > > @@ -5601,15 +5610,41 @@ static bool ironlake_check_fdi_lanes(struct
> > > > drm_device *dev, enum pipe pipe,
> > > >  	}
> > > >  }
> > > >
> > > > +static int add_pipe_b_c_to_state(struct drm_atomic_state *state) {
> > > > +	struct intel_crtc *pipe_B =
> > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_B));
> > > > +	struct intel_crtc *pipe_C =
> > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev, PIPE_C));
> > > > +	struct intel_crtc_state *crtc_state;
> > > > +
> > > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
> > > > +	if (IS_ERR(crtc_state))
> > > > +		return PTR_ERR(crtc_state);
> > > > +
> > > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
> > > > +	if (IS_ERR(crtc_state))
> > > > +		return PTR_ERR(crtc_state);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >  #define RETRY 1
> > > >  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> > > >  				       struct intel_crtc_state *pipe_config)  {
> > > >  	struct drm_device *dev = intel_crtc->base.dev;
> > > >  	struct drm_display_mode *adjusted_mode = &pipe_config-
> > > > >base.adjusted_mode;
> > > > -	int lane, link_bw, fdi_dotclock;
> > > > +	int lane, link_bw, fdi_dotclock, ret;
> > > >  	bool setup_ok, needs_recompute = false;
> > > >
> > > > +	if (IS_IVYBRIDGE(dev) &&
> > > > +	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
> > > > +		ret = add_pipe_b_c_to_state(pipe_config->base.state);
> > >
> > > In this scenario, crtc_states are created for both pipe B & C as an
> > > operation on one can affect the other. I may be missing something
> > > here, but where is the other crtc_state being used: compute/check flow
> > > and/or commit flow?
> > 
> > The function pipe_required_fdi_lanes() above is changed in this patch to use the
> > crtc_state in the drm atomic state to determined FDI lane availability. At this
> > point we don't yet allow changes to multiple pipes, so the mode set is rejected if
> > the pipe that is not being mode set uses too many lanes.
> 
> If request requires too many lanes then mode set is rejected, that is fine.
> But my query is when the request requires lanes that can be supported.
> In that case where the other crtc_state is being used?

Same place, pipe_required_fdi_lanes() called from
ironlake_check_fdi_lanes().

Ander


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

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

* Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state
  2015-03-23  7:33         ` Ander Conselvan De Oliveira
@ 2015-03-23 16:57           ` Konduru, Chandra
  0 siblings, 0 replies; 52+ messages in thread
From: Konduru, Chandra @ 2015-03-23 16:57 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira; +Cc: intel-gfx



> -----Original Message-----
> From: Ander Conselvan De Oliveira [mailto:conselvan2@gmail.com]
> Sent: Monday, March 23, 2015 12:34 AM
> To: Konduru, Chandra
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C
> using atomic state
> 
> On Sun, 2015-03-22 at 16:20 +0000, Konduru, Chandra wrote:
> >
> >
> > > -----Original Message-----
> > > From: Conselvan De Oliveira, Ander
> > > Sent: Thursday, March 19, 2015 11:46 PM
> > > To: Konduru, Chandra
> > > Cc: intel-gfx@lists.freedesktop.org
> > > Subject: Re: [PATCH 16/19] drm/i915: Check lane sharing between
> > > pipes B & C using atomic state
> > >
> > > On Thu, 2015-03-19 at 20:58 +0000, Konduru, Chandra wrote:
> > > >
> > > > > -----Original Message-----
> > > > > From: Conselvan De Oliveira, Ander
> > > > > Sent: Friday, March 13, 2015 2:49 AM
> > > > > To: intel-gfx@lists.freedesktop.org
> > > > > Cc: Konduru, Chandra; Conselvan De Oliveira, Ander
> > > > > Subject: [PATCH 16/19] drm/i915: Check lane sharing between
> > > > > pipes B & C using atomic state
> > > > >
> > > > > Makes that code atomic ready.
> > > > >
> > > > > Signed-off-by: Ander Conselvan de Oliveira
> > > > > <ander.conselvan.de.oliveira@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/intel_display.c | 49
> > > > > ++++++++++++++++++++++++++++++-
> > > > > -----
> > > > >  1 file changed, 42 insertions(+), 7 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > > > b/drivers/gpu/drm/i915/intel_display.c
> > > > > index e720a48..8c97186 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > > @@ -5537,13 +5537,20 @@ bool intel_connector_get_hw_state(struct
> > > > > intel_connector *connector)
> > > > >  	return encoder->get_hw_state(encoder, &pipe);  }
> > > > >
> > > > > -static int pipe_required_fdi_lanes(struct drm_device *dev, enum
> > > > > pipe pipe)
> > > > > +static int pipe_required_fdi_lanes(struct drm_atomic_state *state,
> > > > > +				   enum pipe pipe)
> > > > >  {
> > > > >  	struct intel_crtc *crtc =
> > > > > -		to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
> > > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev,
> pipe));
> > > > > +	struct intel_crtc_state *crtc_state;
> > > > > +
> > > > > +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> > > > > +	if (WARN_ON(IS_ERR(crtc_state))) {
> > > > > +		/* Cause modeset to fail due to excess lanes. */
> > > > > +		return 5;
> > > > > +	}
> > > > >
> > > > > -	if (crtc->base.state->enable &&
> > > > > -	    crtc->config->has_pch_encoder)
> > > > > +	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
> > > > >  		return crtc->config->fdi_lanes;
> > > > >
> > > > >  	return 0;
> > > > > @@ -5552,6 +5559,8 @@ static int pipe_required_fdi_lanes(struct
> > > > > drm_device *dev, enum pipe pipe)  static bool
> > > > > ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
> > > > >  				     struct intel_crtc_state *pipe_config)  {
> > > > > +	struct drm_atomic_state *state = pipe_config->base.state;
> > > > > +
> > > > >  	DRM_DEBUG_KMS("checking fdi config on pipe %c, lanes %i\n",
> > > > >  		      pipe_name(pipe), pipe_config->fdi_lanes);
> > > > >  	if (pipe_config->fdi_lanes > 4) { @@ -5579,7 +5588,7 @@ static
> > > > > bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe
> > > > > pipe,
> > > > >  		return true;
> > > > >  	case PIPE_B:
> > > > >  		if (pipe_config->fdi_lanes > 2 &&
> > > > > -		    pipe_required_fdi_lanes(dev, PIPE_C) > 0) {
> > > > > +		    pipe_required_fdi_lanes(state, PIPE_C) > 0) {
> > > > >  			DRM_DEBUG_KMS("invalid shared fdi lane config on
> > > pipe %c: %i
> > > > > lanes\n",
> > > > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > > > >  			return false;
> > > > > @@ -5591,7 +5600,7 @@ static bool
> > > > > ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
> > > > >  				      pipe_name(pipe), pipe_config->fdi_lanes);
> > > > >  			return false;
> > > > >  		}
> > > > > -		if (pipe_required_fdi_lanes(dev, PIPE_B) > 2) {
> > > > > +		if (pipe_required_fdi_lanes(state, PIPE_B) > 2) {
> > > > >  			DRM_DEBUG_KMS("fdi link B uses too many lanes to
> > > enable link
> > > > > C\n");
> > > > >  			return false;
> > > > >  		}
> > > > > @@ -5601,15 +5610,41 @@ static bool
> > > > > ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
> > > > >  	}
> > > > >  }
> > > > >
> > > > > +static int add_pipe_b_c_to_state(struct drm_atomic_state *state) {
> > > > > +	struct intel_crtc *pipe_B =
> > > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev,
> PIPE_B));
> > > > > +	struct intel_crtc *pipe_C =
> > > > > +		to_intel_crtc(intel_get_crtc_for_pipe(state->dev,
> PIPE_C));
> > > > > +	struct intel_crtc_state *crtc_state;
> > > > > +
> > > > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_B);
> > > > > +	if (IS_ERR(crtc_state))
> > > > > +		return PTR_ERR(crtc_state);
> > > > > +
> > > > > +	crtc_state = intel_atomic_get_crtc_state(state, pipe_C);
> > > > > +	if (IS_ERR(crtc_state))
> > > > > +		return PTR_ERR(crtc_state);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >  #define RETRY 1
> > > > >  static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> > > > >  				       struct intel_crtc_state *pipe_config)  {
> > > > >  	struct drm_device *dev = intel_crtc->base.dev;
> > > > >  	struct drm_display_mode *adjusted_mode = &pipe_config-
> > > > > >base.adjusted_mode;
> > > > > -	int lane, link_bw, fdi_dotclock;
> > > > > +	int lane, link_bw, fdi_dotclock, ret;
> > > > >  	bool setup_ok, needs_recompute = false;
> > > > >
> > > > > +	if (IS_IVYBRIDGE(dev) &&
> > > > > +	    (intel_crtc->pipe == PIPE_B || intel_crtc->pipe == PIPE_C)) {
> > > > > +		ret = add_pipe_b_c_to_state(pipe_config->base.state);
> > > >
> > > > In this scenario, crtc_states are created for both pipe B & C as
> > > > an operation on one can affect the other. I may be missing
> > > > something here, but where is the other crtc_state being used:
> > > > compute/check flow and/or commit flow?
> > >
> > > The function pipe_required_fdi_lanes() above is changed in this
> > > patch to use the crtc_state in the drm atomic state to determined
> > > FDI lane availability. At this point we don't yet allow changes to
> > > multiple pipes, so the mode set is rejected if the pipe that is not being mode
> set uses too many lanes.
> >
> > If request requires too many lanes then mode set is rejected, that is fine.
> > But my query is when the request requires lanes that can be supported.
> > In that case where the other crtc_state is being used?
> 
> Same place, pipe_required_fdi_lanes() called from ironlake_check_fdi_lanes().

Ok, got it. 

> 
> Ander
> 

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

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

end of thread, other threads:[~2015-03-23 16:57 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-13  9:48 [PATCH v2 00/19] Remove depencies on staged config for atomic transition Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 01/19] drm/i915: Add intel_atomic_get_crtc_state() helper function Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 02/19] drm/i915: Pass acquire ctx also to intel_release_load_detect_pipe() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 03/19] drm/i915: Allocate a drm_atomic_state for the legacy modeset code Ander Conselvan de Oliveira
2015-03-17  6:46   ` [PATCH v3] " Ander Conselvan de Oliveira
2015-03-18  7:57     ` [PATCH v4] " Ander Conselvan de Oliveira
2015-03-18 23:57       ` Konduru, Chandra
2015-03-19  7:50         ` Ander Conselvan De Oliveira
2015-03-19 21:08   ` [PATCH 03/19] " Konduru, Chandra
2015-03-20  7:00     ` Ander Conselvan De Oliveira
2015-03-22 16:28       ` Konduru, Chandra
2015-03-13  9:48 ` [PATCH 04/19] drm/i915: Allocate a crtc_state also when the crtc is being disabled Ander Conselvan de Oliveira
     [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B41B@fmsmsx101.amr.corp.intel.com>
2015-03-19  7:52     ` Ander Conselvan De Oliveira
2015-03-19 23:23       ` Konduru, Chandra
2015-03-20  8:40         ` Ander Conselvan De Oliveira
2015-03-20  9:51           ` Daniel Vetter
2015-03-20 10:06             ` Ander Conselvan De Oliveira
2015-03-20 10:39               ` Daniel Vetter
2015-03-22 16:46           ` Konduru, Chandra
2015-03-13  9:48 ` [PATCH 05/19] drm/i915: Update dummy connector atomic state with current config Ander Conselvan de Oliveira
2015-03-19 20:55   ` Konduru, Chandra
2015-03-20  6:41     ` Ander Conselvan De Oliveira
2015-03-13  9:48 ` [PATCH 06/19] drm/i915: Implement connector state duplication Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 07/19] drm/i915: Copy the staged connector config to the legacy atomic state Ander Conselvan de Oliveira
     [not found]   ` <76A9B330A4D78C4D99CB292C4CC06C0E36F7B6F0@fmsmsx101.amr.corp.intel.com>
2015-03-19  7:52     ` Ander Conselvan De Oliveira
2015-03-19 15:15       ` Daniel Vetter
2015-03-13  9:48 ` [PATCH 08/19] drm/i915: Don't use encoder->new_crtc in intel_modeset_pipe_config() Ander Conselvan de Oliveira
2015-03-19  0:44   ` Konduru, Chandra
2015-03-19  7:52     ` Ander Conselvan De Oliveira
2015-03-13  9:48 ` [PATCH 09/19] drm/i915: Don't use encoder->new_crtc in compute_baseline_pipe_bpp() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 10/19] drm/i915: Don't depend on encoder->new_crtc in intel_dp_compute_config() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 11/19] drm/i915: Don't depend on encoder->new_crtc in intel_hdmi_compute_config Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 12/19] drm/i915: Use atomic state in intel_ddi_crtc_get_new_encoder() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 13/19] drm/i915: Don't use staged config in intel_dp_mst_compute_config() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 14/19] drm/i915: Don't use encoder->new_crtc in intel_lvds_compute_config() Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 15/19] drm/i915: Pass an atomic state to modeset_global_resources() functions Ander Conselvan de Oliveira
2015-03-13  9:48 ` [PATCH 16/19] drm/i915: Check lane sharing between pipes B & C using atomic state Ander Conselvan de Oliveira
2015-03-19 20:58   ` Konduru, Chandra
2015-03-20  6:46     ` Conselvan De Oliveira, Ander
2015-03-22 16:20       ` Konduru, Chandra
2015-03-23  7:33         ` Ander Conselvan De Oliveira
2015-03-23 16:57           ` Konduru, Chandra
2015-03-13  9:49 ` [PATCH 17/19] drm/i915: Convert intel_pipe_will_have_type() to " Ander Conselvan de Oliveira
2015-03-19 19:24   ` Konduru, Chandra
2015-03-20  6:28     ` Ander Conselvan De Oliveira
2015-03-22 16:14       ` Konduru, Chandra
2015-03-13  9:49 ` [PATCH 18/19] drm/i915: Don't look at staged config crtc when changing DRRS state Ander Conselvan de Oliveira
2015-03-13  9:49 ` [PATCH 19/19] drm/i915: Remove usage of encoder->new_crtc from clock computations Ander Conselvan de Oliveira
2015-03-14  0:29   ` shuang.he
2015-03-19 20:39   ` Konduru, Chandra
2015-03-18 23:57 ` [PATCH v2 00/19] Remove depencies on staged config for atomic transition Konduru, Chandra
2015-03-19 15:20   ` 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.