intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] basic infrastructure for pipe_config
@ 2013-02-21 23:56 Daniel Vetter
  2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
                   ` (9 more replies)
  0 siblings, 10 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Hi all,

This adds the basic pipe_config infrastructure and coverts over the various mode
flags plus the pipe bpp handling. On top of that 2 patches to clean up the bpp
handling mess a bit and make the code stricter in enforcing its own rules with a
few BUGs.

Compared to the original submission I've mostly just reordered patches to group
them better, but a few other things have changed, too:
- Updated patches with Ville's feedback.
- vlv has like g4x only 10bpc, not a 12bpc.
- Fix a stupid mistake in the vlv/g4x pipe bpp clamping.

Oh and the stuff is not tested on a few more machines, but not too
through-roughly.

Cheers, Daniel

Daniel Vetter (10):
  drm/i915: introduce struct intel_crtc_config
  drm/i915: compute pipe_config earlier
  drm/i915: add pipe_config->timings_set
  drm/i915: add pipe_config->pixel_multiplier
  drm/i915: drop helper vtable for sdvo encoder
  drm/i915: add pipe_config->has_pch_encoder
  drm/i915: add pipe_config->limited_color_range
  drm/i915: move pipe bpp computation to pipe_config
  drm/i915: clean up plane bpp confusion
  drm/i915: clean up pipe bpp confusion

 drivers/gpu/drm/i915/i915_drv.h      |   4 +-
 drivers/gpu/drm/i915/intel_crt.c     |  12 +-
 drivers/gpu/drm/i915/intel_ddi.c     |  27 +-
 drivers/gpu/drm/i915/intel_display.c | 473 +++++++++++++++--------------------
 drivers/gpu/drm/i915/intel_dp.c      | 125 +++++----
 drivers/gpu/drm/i915/intel_drv.h     |  68 +++--
 drivers/gpu/drm/i915/intel_hdmi.c    |  35 ++-
 drivers/gpu/drm/i915/intel_lvds.c    |  33 ++-
 drivers/gpu/drm/i915/intel_sdvo.c    |  55 ++--
 drivers/gpu/drm/i915/intel_tv.c      |  14 +-
 10 files changed, 406 insertions(+), 440 deletions(-)

-- 
1.7.11.4

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

* [PATCH 01/10] drm/i915: introduce struct intel_crtc_config
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-22 10:23   ` Ville Syrjälä
  2013-02-22 11:05   ` [PATCH] " Daniel Vetter
  2013-02-21 23:56 ` [PATCH 02/10] drm/i915: compute pipe_config earlier Daniel Vetter
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Currently only containing the requested and the adjusted mode. And
only crtc callbacks are converted somewhat to it, encoders will be
done on a as-needed basis (simply too much churn in one patch
otherwise).

Future patches will add tons more useful stuff to this struct,
starting with the very simple.

v2: Store the pipe_config in the intel_crtc, so that the ->mode-set,
->enable and also ->disable have easy access to it.

v3: Store the pipe config in the right crtc ...

v4: Rebased.

v5: Fixup an OOPS when trying to kfree an ERR_PTR.

v6: Used drm_moode_copy and some other small cleanups as suggested
by Ville Syrjälä.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h      |  4 +-
 drivers/gpu/drm/i915/intel_display.c | 83 +++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_drv.h     |  7 +++
 3 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e95337c..8fb14fb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -271,6 +271,8 @@ struct drm_i915_error_state {
 	struct intel_display_error_state *display;
 };
 
+struct intel_crtc_config;
+
 struct drm_i915_display_funcs {
 	bool (*fbc_enabled)(struct drm_device *dev);
 	void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
@@ -284,8 +286,6 @@ struct drm_i915_display_funcs {
 				 struct drm_display_mode *mode);
 	void (*modeset_global_resources)(struct drm_device *dev);
 	int (*crtc_mode_set)(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode,
 			     int x, int y,
 			     struct drm_framebuffer *old_fb);
 	void (*crtc_enable)(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b521198..5a3e231 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
 	return encoder->get_hw_state(encoder, &pipe);
 }
 
-static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+static bool intel_crtc_compute_config(struct drm_crtc *crtc,
+				      struct intel_crtc_config *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (HAS_PCH_SPLIT(dev)) {
 		/* FDI link clock is fixed at 2.7G */
-		if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
+		if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4)
 			return false;
 	}
 
@@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
 }
 
 static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
-			      struct drm_display_mode *mode,
-			      struct drm_display_mode *adjusted_mode,
 			      int x, int y,
 			      struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int refclk, num_connectors = 0;
@@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 }
 
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode,
 				  int x, int y,
 				  struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int num_connectors = 0;
@@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
 }
 
 static int haswell_crtc_mode_set(struct drm_crtc *crtc,
-				 struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode,
 				 int x, int y,
 				 struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int num_connectors = 0;
@@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 }
 
 static int intel_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
 			       int x, int y,
 			       struct drm_framebuffer *fb)
 {
@@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int ret;
 
@@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
 	drm_vblank_pre_modeset(dev, pipe);
 
-	ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
-					      x, y, fb);
+	ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
+
 	drm_vblank_post_modeset(dev, pipe);
 
 	if (ret != 0)
@@ -7478,19 +7482,24 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
 	}
 }
 
-static struct drm_display_mode *
-intel_modeset_adjusted_mode(struct drm_crtc *crtc,
-			    struct drm_display_mode *mode)
+static struct intel_crtc_config *
+intel_modeset_pipe_config(struct drm_crtc *crtc,
+			  struct drm_display_mode *mode)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_display_mode *adjusted_mode;
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
+	struct intel_crtc_config *pipe_config;
 
-	adjusted_mode = drm_mode_duplicate(dev, mode);
-	if (!adjusted_mode)
+	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
+	if (!pipe_config)
 		return ERR_PTR(-ENOMEM);
 
+	drm_mode_copy(&pipe_config->adjusted_mode, mode);
+	pipe_config->adjusted_mode.base.id = 0;
+	drm_mode_copy(&pipe_config->requested_mode, mode);
+	pipe_config->requested_mode.base.id = 0;
+
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -7501,22 +7510,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc,
 		if (&encoder->new_crtc->base != crtc)
 			continue;
 		encoder_funcs = encoder->base.helper_private;
-		if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
-						adjusted_mode))) {
+		if (!(encoder_funcs->mode_fixup(&encoder->base,
+						&pipe_config->requested_mode,
+						&pipe_config->adjusted_mode))) {
 			DRM_DEBUG_KMS("Encoder fixup failed\n");
 			goto fail;
 		}
 	}
 
-	if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
+	if (!(intel_crtc_compute_config(crtc, pipe_config))) {
 		DRM_DEBUG_KMS("CRTC fixup failed\n");
 		goto fail;
 	}
 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
-	return adjusted_mode;
+	return pipe_config;
 fail:
-	drm_mode_destroy(dev, adjusted_mode);
+	kfree(pipe_config);
 	return ERR_PTR(-EINVAL);
 }
 
@@ -7782,7 +7792,8 @@ int intel_set_mode(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode;
+	struct drm_display_mode *saved_mode, *saved_hwmode;
+	struct intel_crtc_config *pipe_config = NULL;
 	struct intel_crtc *intel_crtc;
 	unsigned disable_pipes, prepare_pipes, modeset_pipes;
 	int ret = 0;
@@ -7809,11 +7820,12 @@ int intel_set_mode(struct drm_crtc *crtc,
 	 * Hence simply check whether any bit is set in modeset_pipes in all the
 	 * pieces of code that are not yet converted to deal with mutliple crtcs
 	 * changing their mode at the same time. */
-	adjusted_mode = NULL;
 	if (modeset_pipes) {
-		adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
-		if (IS_ERR(adjusted_mode)) {
-			ret = PTR_ERR(adjusted_mode);
+		pipe_config = intel_modeset_pipe_config(crtc, mode);
+		if (IS_ERR(pipe_config)) {
+			ret = PTR_ERR(pipe_config);
+			pipe_config = NULL;
+
 			goto out;
 		}
 	}
@@ -7826,8 +7838,12 @@ int intel_set_mode(struct drm_crtc *crtc,
 	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
 	 * to set it here already despite that we pass it down the callchain.
 	 */
-	if (modeset_pipes)
+	if (modeset_pipes) {
 		crtc->mode = *mode;
+		/* mode_set/enable/disable functions rely on a correct pipe
+		 * config. */
+		to_intel_crtc(crtc)->config = *pipe_config;
+	}
 
 	/* Only after disabling all output pipelines that will be changed can we
 	 * update the the output configuration. */
@@ -7841,7 +7857,6 @@ int intel_set_mode(struct drm_crtc *crtc,
 	 */
 	for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
 		ret = intel_crtc_mode_set(&intel_crtc->base,
-					  mode, adjusted_mode,
 					  x, y, fb);
 		if (ret)
 			goto done;
@@ -7853,7 +7868,7 @@ int intel_set_mode(struct drm_crtc *crtc,
 
 	if (modeset_pipes) {
 		/* Store real post-adjustment hardware mode. */
-		crtc->hwmode = *adjusted_mode;
+		crtc->hwmode = pipe_config->adjusted_mode;
 
 		/* Calculate and store various constants which
 		 * are later needed by vblank and swap-completion
@@ -7864,7 +7879,6 @@ int intel_set_mode(struct drm_crtc *crtc,
 
 	/* FIXME: add subpixel order */
 done:
-	drm_mode_destroy(dev, adjusted_mode);
 	if (ret && crtc->enabled) {
 		crtc->hwmode = *saved_hwmode;
 		crtc->mode = *saved_mode;
@@ -7873,6 +7887,7 @@ done:
 	}
 
 out:
+	kfree(pipe_config);
 	kfree(saved_mode);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e6f84d0..eca75b6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -199,6 +199,11 @@ struct intel_connector {
 	struct edid *edid;
 };
 
+struct intel_crtc_config {
+	struct drm_display_mode requested_mode;
+	struct drm_display_mode adjusted_mode;
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -232,6 +237,8 @@ struct intel_crtc {
 	bool cursor_visible;
 	unsigned int bpp;
 
+	struct intel_crtc_config config;
+
 	/* We can share PLLs across outputs if the timings match */
 	struct intel_pch_pll *pch_pll;
 	uint32_t ddi_pll_sel;
-- 
1.7.11.4

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

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

* [PATCH 02/10] drm/i915: compute pipe_config earlier
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
  2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-26 17:11   ` Paulo Zanoni
  2013-02-21 23:56 ` [PATCH 03/10] drm/i915: add pipe_config->timings_set Daniel Vetter
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

To make decent modeset state checking possible (e.g. for the check
mode with atomic modesetting) we want to have the full pipe
configuration and state checks done before we touch the hw.

To ensure that all the little bits&pieces that are now moved to the
pipe_config handle this correctly, move its computation to the right
spot now, before we touch the hw in the disable_pipes step.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5a3e231..0f61008 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7806,12 +7806,6 @@ int intel_set_mode(struct drm_crtc *crtc,
 	intel_modeset_affected_pipes(crtc, &modeset_pipes,
 				     &prepare_pipes, &disable_pipes);
 
-	DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
-		      modeset_pipes, prepare_pipes, disable_pipes);
-
-	for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
-		intel_crtc_disable(&intel_crtc->base);
-
 	*saved_hwmode = crtc->hwmode;
 	*saved_mode = crtc->mode;
 
@@ -7830,6 +7824,12 @@ int intel_set_mode(struct drm_crtc *crtc,
 		}
 	}
 
+	DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
+		      modeset_pipes, prepare_pipes, disable_pipes);
+
+	for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
+		intel_crtc_disable(&intel_crtc->base);
+
 	for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
 		if (intel_crtc->base.enabled)
 			dev_priv->display.crtc_disable(&intel_crtc->base);
-- 
1.7.11.4

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

* [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
  2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
  2013-02-21 23:56 ` [PATCH 02/10] drm/i915: compute pipe_config earlier Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-22 13:51   ` Ville Syrjälä
  2013-02-26 17:23   ` Paulo Zanoni
  2013-02-21 23:56 ` [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier Daniel Vetter
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Only used by the lvds encoder. Note that we shouldn't do the same
simple conversion with the FORCE_6BPC flag, since that's much better
handled by moving all the pipe_bpc computation around.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
 drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0f61008..ad03b7f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3930,7 +3930,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
 	/* All interlaced capable intel hw wants timings in frames. Note though
 	 * that intel_lvds_mode_fixup does some funny tricks with the crtc
 	 * timings, so we need to be careful not to clobber these.*/
-	if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
+	if (!pipe_config->timings_set)
 		drm_mode_set_crtcinfo(adjusted_mode, 0);
 
 	/* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
@@ -7509,6 +7509,16 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 
 		if (&encoder->new_crtc->base != crtc)
 			continue;
+
+		if (encoder->compute_config) {
+			if (!(encoder->compute_config(encoder, pipe_config))) {
+				DRM_DEBUG_KMS("Encoder config failure\n");
+				goto fail;
+			}
+
+			continue;
+		}
+
 		encoder_funcs = encoder->base.helper_private;
 		if (!(encoder_funcs->mode_fixup(&encoder->base,
 						&pipe_config->requested_mode,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index eca75b6..edafbef 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -105,10 +105,6 @@
 #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
 #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
 #define INTEL_MODE_DP_FORCE_6BPC (0x10)
-/* This flag must be set by the encoder's mode_fixup if it changes the crtc
- * timings in the mode to prevent the crtc fixup from overwriting them.
- * Currently only lvds needs that. */
-#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
 /*
  * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
  * to be used.
@@ -158,6 +154,8 @@ struct intel_encoder {
 	bool cloneable;
 	bool connectors_active;
 	void (*hot_plug)(struct intel_encoder *);
+	bool (*compute_config)(struct intel_encoder *,
+			       struct intel_crtc_config *);
 	void (*pre_pll_enable)(struct intel_encoder *);
 	void (*pre_enable)(struct intel_encoder *);
 	void (*enable)(struct intel_encoder *);
@@ -202,6 +200,10 @@ struct intel_connector {
 struct intel_crtc_config {
 	struct drm_display_mode requested_mode;
 	struct drm_display_mode adjusted_mode;
+	/* This flag must be set by the encoder's compute_config callback if it
+	 * changes the crtc timings in the mode to prevent the crtc fixup from
+	 * overwriting them.  Currently only lvds needs that. */
+	bool timings_set;
 };
 
 struct intel_crtc {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 3d1d974..1616f53 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -261,8 +261,6 @@ centre_horizontally(struct drm_display_mode *mode,
 
 	mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
 	mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
-
-	mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static void
@@ -284,8 +282,6 @@ centre_vertically(struct drm_display_mode *mode,
 
 	mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
 	mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
-
-	mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
 }
 
 static inline u32 panel_fitter_scaling(u32 source, u32 target)
@@ -301,15 +297,17 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
 	return (FACTOR * ratio + FACTOR/2) / FACTOR;
 }
 
-static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
+				      struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = encoder->dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
+	struct intel_lvds_encoder *lvds_encoder =
+		to_lvds_encoder(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 		&lvds_encoder->attached_connector->base;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->requested_mode;
 	struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
 	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
 	int pipe;
@@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
 		I915_WRITE(BCLRPAT(pipe), 0);
 
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
+	pipe_config->timings_set = true;
 
 	switch (intel_connector->panel.fitting_mode) {
 	case DRM_MODE_SCALE_CENTER:
@@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
 }
 
 static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
-	.mode_fixup = intel_lvds_mode_fixup,
 	.mode_set = intel_lvds_mode_set,
 };
 
@@ -1102,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
 	intel_encoder->enable = intel_enable_lvds;
 	intel_encoder->pre_enable = intel_pre_enable_lvds;
 	intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
+	intel_encoder->compute_config = intel_lvds_compute_config;
 	intel_encoder->disable = intel_disable_lvds;
 	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
-- 
1.7.11.4

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

* [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (2 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 03/10] drm/i915: add pipe_config->timings_set Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-26 17:27   ` Paulo Zanoni
  2013-02-21 23:56 ` [PATCH 05/10] drm/i915: drop helper vtable for sdvo encoder Daniel Vetter
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Used by SDVO (and hopefully, eventually HDMI, if we ever get around
to fixing up the low dotclock CEA modes ...).

This required adding a new encoder->mode_set callback to be able to
pass around the intel_crtc_config.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 80 +++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_drv.h     | 19 ++-------
 drivers/gpu/drm/i915/intel_sdvo.c    | 39 +++++++++---------
 3 files changed, 66 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ad03b7f..3446e2b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4280,14 +4280,15 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
 }
 
 static void vlv_update_pll(struct drm_crtc *crtc,
-			   struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode,
 			   intel_clock_t *clock, intel_clock_t *reduced_clock,
 			   int num_connectors)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	u32 dpll, mdiv, pdiv;
 	u32 bestn, bestm1, bestm2, bestp1, bestp2;
@@ -4354,11 +4355,11 @@ static void vlv_update_pll(struct drm_crtc *crtc,
 
 	temp = 0;
 	if (is_sdvo) {
-		temp = intel_mode_get_pixel_multiplier(adjusted_mode);
-		if (temp > 1)
-			temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
-		else
-			temp = 0;
+		temp = 0;
+		if (intel_crtc->config.pixel_multiplier > 1) {
+			temp = (intel_crtc->config.pixel_multiplier - 1)
+				<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
+		}
 	}
 	I915_WRITE(DPLL_MD(pipe), temp);
 	POSTING_READ(DPLL_MD(pipe));
@@ -4384,14 +4385,15 @@ static void vlv_update_pll(struct drm_crtc *crtc,
 }
 
 static void i9xx_update_pll(struct drm_crtc *crtc,
-			    struct drm_display_mode *mode,
-			    struct drm_display_mode *adjusted_mode,
 			    intel_clock_t *clock, intel_clock_t *reduced_clock,
 			    int num_connectors)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	u32 dpll;
@@ -4408,11 +4410,12 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
 		dpll |= DPLLB_MODE_LVDS;
 	else
 		dpll |= DPLLB_MODE_DAC_SERIAL;
+
 	if (is_sdvo) {
-		int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
-		if (pixel_multiplier > 1) {
-			if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
-				dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
+		if ((intel_crtc->config.pixel_multiplier > 1) &&
+		    (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) {
+			dpll |= (intel_crtc->config.pixel_multiplier - 1)
+				<< SDVO_MULTIPLIER_SHIFT_HIRES;
 		}
 		dpll |= DPLL_DVO_HIGH_SPEED;
 	}
@@ -4477,11 +4480,11 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
 	if (INTEL_INFO(dev)->gen >= 4) {
 		u32 temp = 0;
 		if (is_sdvo) {
-			temp = intel_mode_get_pixel_multiplier(adjusted_mode);
-			if (temp > 1)
-				temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
-			else
-				temp = 0;
+			temp = 0;
+			if (intel_crtc->config.pixel_multiplier > 1) {
+				temp = (intel_crtc->config.pixel_multiplier - 1)
+					<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
+			}
 		}
 		I915_WRITE(DPLL_MD(pipe), temp);
 	} else {
@@ -4691,11 +4694,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 				has_reduced_clock ? &reduced_clock : NULL,
 				num_connectors);
 	else if (IS_VALLEYVIEW(dev))
-		vlv_update_pll(crtc, mode, adjusted_mode, &clock,
+		vlv_update_pll(crtc, &clock,
 				has_reduced_clock ? &reduced_clock : NULL,
 				num_connectors);
 	else
-		i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
+		i9xx_update_pll(crtc, &clock,
 				has_reduced_clock ? &reduced_clock : NULL,
 				num_connectors);
 
@@ -5407,17 +5410,18 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
 	return bps / (link_bw * 8) + 1;
 }
 
-static void ironlake_set_m_n(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode)
+static void ironlake_set_m_n(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
 	struct intel_encoder *intel_encoder, *edp_encoder = NULL;
 	struct intel_link_m_n m_n = {0};
-	int target_clock, pixel_multiplier, lane, link_bw;
+	int target_clock, lane, link_bw;
 	bool is_dp = false, is_cpu_edp = false;
 
 	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
@@ -5435,7 +5439,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
 	}
 
 	/* FDI link */
-	pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
 	lane = 0;
 	/* CPU eDP doesn't require FDI link, so just set DP M/N
 	   according to current link config */
@@ -5466,8 +5469,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
 
 	intel_crtc->fdi_lanes = lane;
 
-	if (pixel_multiplier > 1)
-		link_bw *= pixel_multiplier;
+	if (intel_crtc->config.pixel_multiplier > 1)
+		link_bw *= intel_crtc->config.pixel_multiplier;
 	intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
 
 	I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
@@ -5477,7 +5480,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
 }
 
 static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
-				      struct drm_display_mode *adjusted_mode,
 				      intel_clock_t *clock, u32 fp)
 {
 	struct drm_crtc *crtc = &intel_crtc->base;
@@ -5485,7 +5487,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_encoder *intel_encoder;
 	uint32_t dpll;
-	int factor, pixel_multiplier, num_connectors = 0;
+	int factor, num_connectors = 0;
 	bool is_lvds = false, is_sdvo = false, is_tv = false;
 	bool is_dp = false, is_cpu_edp = false;
 
@@ -5536,9 +5538,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 	else
 		dpll |= DPLLB_MODE_DAC_SERIAL;
 	if (is_sdvo) {
-		pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
-		if (pixel_multiplier > 1) {
-			dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
+		if (intel_crtc->config.pixel_multiplier > 1) {
+			dpll |= (intel_crtc->config.pixel_multiplier - 1)
+				<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
 		}
 		dpll |= DPLL_DVO_HIGH_SPEED;
 	}
@@ -5642,7 +5644,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 		fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
 			reduced_clock.m2;
 
-	dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp);
+	dpll = ironlake_compute_dpll(intel_crtc, &clock, fp);
 
 	DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
 	drm_mode_debug_printmodeline(mode);
@@ -5696,7 +5698,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 
 	/* Note, this also computes intel_crtc->fdi_lanes which is used below in
 	 * ironlake_check_fdi_lanes. */
-	ironlake_set_m_n(crtc, mode, adjusted_mode);
+	ironlake_set_m_n(crtc);
 
 	fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
 
@@ -5812,7 +5814,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 	intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
 
 	if (!is_dp || is_cpu_edp)
-		ironlake_set_m_n(crtc, mode, adjusted_mode);
+		ironlake_set_m_n(crtc);
 
 	haswell_set_pipeconf(crtc, adjusted_mode, dither);
 
@@ -5865,8 +5867,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 			encoder->base.base.id,
 			drm_get_encoder_name(&encoder->base),
 			mode->base.id, mode->name);
-		encoder_funcs = encoder->base.helper_private;
-		encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
+		if (encoder->mode_set) {
+			encoder->mode_set(encoder);
+		} else {
+			encoder_funcs = encoder->base.helper_private;
+			encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
+		}
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index edafbef..ef5111b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -102,8 +102,6 @@
 #define INTEL_DVO_CHIP_TVOUT 4
 
 /* drm_display_mode->private_flags */
-#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
-#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
 #define INTEL_MODE_DP_FORCE_6BPC (0x10)
 /*
  * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
@@ -111,20 +109,6 @@
  */
 #define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
 
-static inline void
-intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
-				int multiplier)
-{
-	mode->clock *= multiplier;
-	mode->private_flags |= multiplier;
-}
-
-static inline int
-intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode)
-{
-	return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT;
-}
-
 struct intel_framebuffer {
 	struct drm_framebuffer base;
 	struct drm_i915_gem_object *obj;
@@ -159,6 +143,7 @@ struct intel_encoder {
 	void (*pre_pll_enable)(struct intel_encoder *);
 	void (*pre_enable)(struct intel_encoder *);
 	void (*enable)(struct intel_encoder *);
+	void (*mode_set)(struct intel_encoder *intel_encoder);
 	void (*disable)(struct intel_encoder *);
 	void (*post_disable)(struct intel_encoder *);
 	/* Read out the current hw state of this connector, returning true if
@@ -204,6 +189,8 @@ struct intel_crtc_config {
 	 * changes the crtc timings in the mode to prevent the crtc fixup from
 	 * overwriting them.  Currently only lvds needs that. */
 	bool timings_set;
+	/* Used by SDVO (and if we ever fix it, HDMI). */
+	unsigned pixel_multiplier;
 };
 
 struct intel_crtc {
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 33b46d9..06bb2e1 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -788,7 +788,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
 	v_sync_offset = mode->vsync_start - mode->vdisplay;
 
 	mode_clock = mode->clock;
-	mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1;
 	mode_clock /= 10;
 	dtd->part1.clock = mode_clock;
 
@@ -1039,12 +1038,12 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
 	return true;
 }
 
-static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
+				      struct intel_crtc_config *pipe_config)
 {
-	struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
-	int multiplier;
+	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->requested_mode;
 
 	/* We need to construct preferred input timings based on our
 	 * output timings.  To do that, we have to set the output
@@ -1071,8 +1070,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 	/* Make the CRTC code factor in the SDVO pixel multiplier.  The
 	 * SDVO device will factor out the multiplier during mode_set.
 	 */
-	multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
-	intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
+	pipe_config->pixel_multiplier =
+		intel_sdvo_get_pixel_multiplier(adjusted_mode);
+	adjusted_mode->clock *= pipe_config->pixel_multiplier;
 
 	if (intel_sdvo->color_range_auto) {
 		/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -1089,19 +1089,19 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 	return true;
 }
 
-static void intel_sdvo_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder)
 {
-	struct drm_device *dev = encoder->dev;
+	struct drm_device *dev = intel_encoder->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_crtc *crtc = encoder->crtc;
+	struct drm_crtc *crtc = intel_encoder->base.crtc;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
+	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
 	struct intel_sdvo_dtd input_dtd, output_dtd;
-	int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
 	int rate;
 
 	if (!mode)
@@ -1161,7 +1161,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 		DRM_INFO("Setting input timings on %s failed\n",
 			 SDVO_NAME(intel_sdvo));
 
-	switch (pixel_multiplier) {
+	switch (intel_crtc->config.pixel_multiplier) {
 	default:
 	case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
 	case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
@@ -1205,7 +1205,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 	} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
 		/* done in crtc_mode_set as it lives inside the dpll register */
 	} else {
-		sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT;
+		sdvox |= (intel_crtc->config.pixel_multiplier - 1)
+			<< SDVO_PORT_MULTIPLY_SHIFT;
 	}
 
 	if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL &&
@@ -2041,8 +2042,6 @@ done:
 }
 
 static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
-	.mode_fixup = intel_sdvo_mode_fixup,
-	.mode_set = intel_sdvo_mode_set,
 };
 
 static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
@@ -2781,7 +2780,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
 
 	drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
 
+	intel_encoder->compute_config = intel_sdvo_compute_config;
 	intel_encoder->disable = intel_disable_sdvo;
+	intel_encoder->mode_set = intel_sdvo_mode_set;
 	intel_encoder->enable = intel_enable_sdvo;
 	intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
 
-- 
1.7.11.4

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

* [PATCH 05/10] drm/i915: drop helper vtable for sdvo encoder
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (3 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-21 23:56 ` [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder Daniel Vetter
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Completely unused by now. Separate patch in case I've missed a
place somewhere which dereferences the helper vtable but actually
shouldn't do so.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_sdvo.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 06bb2e1..3a45be0 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2041,9 +2041,6 @@ done:
 #undef CHECK_PROPERTY
 }
 
-static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
-};
-
 static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
 	.dpms = intel_sdvo_dpms,
 	.detect = intel_sdvo_detect,
@@ -2778,8 +2775,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
 			SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
 	}
 
-	drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
-
 	intel_encoder->compute_config = intel_sdvo_compute_config;
 	intel_encoder->disable = intel_disable_sdvo;
 	intel_encoder->mode_set = intel_sdvo_mode_set;
-- 
1.7.11.4

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

* [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (4 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 05/10] drm/i915: drop helper vtable for sdvo encoder Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-26 17:39   ` Paulo Zanoni
  2013-02-21 23:56 ` [PATCH 07/10] drm/i915: add pipe_config->limited_color_range Daniel Vetter
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

This is used way too often in the enable/disable paths. And will
be even more useful in the future.

Note that correct semantics of this change highly depend upon
correct updating of intel_crtc->config: Like with all other
modeset state, we need to call ->disable with the old config,
but ->mode_set and ->enable with the new config.

v2: Do not yet use the flag in the ->disable callbacks - atm we don't
yet have support for the information stored in the pipe_config in the
hw state readout code, so this will be wrong at boot-up/resume.

v3: Rebased on top of the hdmi/dp ddi encoder merging.

v4: Fixup stupid rebase error which lead to a NULL vfunc deref.

v5: On haswell the VGA port is on the PCH!

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_crt.c     | 12 +++++++----
 drivers/gpu/drm/i915/intel_ddi.c     | 16 +++++++--------
 drivers/gpu/drm/i915/intel_display.c | 40 ++++++++----------------------------
 drivers/gpu/drm/i915/intel_dp.c      | 16 +++++++++------
 drivers/gpu/drm/i915/intel_drv.h     | 13 ++++++------
 drivers/gpu/drm/i915/intel_hdmi.c    | 14 ++++++++-----
 drivers/gpu/drm/i915/intel_lvds.c    |  2 ++
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
 8 files changed, 54 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 969d08c..1bd09a7 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -206,10 +206,14 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_crt_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
+	struct drm_device *dev = encoder->base.dev;
+
+	if (HAS_PCH_SPLIT(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -683,7 +687,6 @@ static void intel_crt_reset(struct drm_connector *connector)
  */
 
 static const struct drm_encoder_helper_funcs crt_encoder_funcs = {
-	.mode_fixup = intel_crt_mode_fixup,
 	.mode_set = intel_crt_mode_set,
 };
 
@@ -774,6 +777,7 @@ void intel_crt_init(struct drm_device *dev)
 	else
 		crt->adpa_reg = ADPA;
 
+	crt->base.compute_config = intel_crt_compute_config;
 	crt->base.disable = intel_disable_crt;
 	crt->base.enable = intel_enable_crt;
 	if (HAS_DDI(dev))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fc95ef0..f5ae79f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1467,19 +1467,17 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
 	intel_dp_encoder_destroy(encoder);
 }
 
-static bool intel_ddi_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_ddi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
-	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-	int type = intel_encoder->type;
+	int type = encoder->type;
 
-	WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n");
+	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
 
 	if (type == INTEL_OUTPUT_HDMI)
-		return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_hdmi_compute_config(encoder, pipe_config);
 	else
-		return intel_dp_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_dp_compute_config(encoder, pipe_config);
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
@@ -1487,7 +1485,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
 };
 
 static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
-	.mode_fixup = intel_ddi_mode_fixup,
 	.mode_set = intel_ddi_mode_set,
 };
 
@@ -1527,6 +1524,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs);
 
+	intel_encoder->compute_config = intel_ddi_compute_config;
 	intel_encoder->enable = intel_enable_ddi;
 	intel_encoder->pre_enable = intel_ddi_pre_enable;
 	intel_encoder->disable = intel_disable_ddi;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3446e2b..c5f7c6e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2947,27 +2947,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 	mutex_unlock(&dev->struct_mutex);
 }
 
-static bool ironlake_crtc_driving_pch(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct intel_encoder *intel_encoder;
-
-	/*
-	 * If there's a non-PCH eDP on this crtc, it must be DP_A, and that
-	 * must be driven by its own crtc; no sharing is possible.
-	 */
-	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
-		switch (intel_encoder->type) {
-		case INTEL_OUTPUT_EDP:
-			if (!intel_encoder_is_pch_edp(&intel_encoder->base))
-				return false;
-			continue;
-		}
-	}
-
-	return true;
-}
-
 static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)
 {
 	return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
@@ -3308,7 +3287,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	u32 temp;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3324,9 +3302,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 			I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
 	}
 
-	is_pch_port = ironlake_crtc_driving_pch(crtc);
 
-	if (is_pch_port) {
+	if (intel_crtc->config.has_pch_encoder) {
 		/* Note: FDI PLL enabling _must_ be done before we enable the
 		 * cpu pipes, hence this is separate from all the other fdi/pch
 		 * enabling. */
@@ -3363,10 +3340,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	 */
 	intel_crtc_load_lut(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		ironlake_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
@@ -3400,7 +3378,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3410,9 +3387,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc->active = true;
 	intel_update_watermarks(dev);
 
-	is_pch_port = haswell_crtc_driving_pch(crtc);
-
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		dev_priv->display.fdi_link_train(crtc);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3443,10 +3418,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_ddi_set_pipe_settings(crtc);
 	intel_ddi_enable_pipe_func(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		lpt_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9b1a969..e851fdd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -689,12 +689,13 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
 }
 
 bool
-intel_dp_mode_fixup(struct drm_encoder *encoder,
-		    const struct drm_display_mode *mode,
-		    struct drm_display_mode *adjusted_mode)
+intel_dp_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = encoder->dev;
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->requested_mode;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	int lane_count, clock;
 	int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
@@ -702,6 +703,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
+	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))
+		pipe_config->has_pch_encoder = true;
+
 	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
 		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 				       adjusted_mode);
@@ -2517,7 +2521,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
-	.mode_fixup = intel_dp_mode_fixup,
 	.mode_set = intel_dp_mode_set,
 };
 
@@ -2937,6 +2940,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
 
+	intel_encoder->compute_config = intel_dp_compute_config;
 	intel_encoder->enable = intel_enable_dp;
 	intel_encoder->pre_enable = intel_pre_enable_dp;
 	intel_encoder->disable = intel_disable_dp;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ef5111b..458e6bd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -189,6 +189,9 @@ struct intel_crtc_config {
 	 * changes the crtc timings in the mode to prevent the crtc fixup from
 	 * overwriting them.  Currently only lvds needs that. */
 	bool timings_set;
+	/* Whether to set up the PCH/FDI. Note that we never allow sharing
+	 * between pch encoders and cpu encoders. */
+	bool has_pch_encoder;
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 };
@@ -444,9 +447,8 @@ extern void intel_hdmi_init(struct drm_device *dev,
 extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 				      struct intel_connector *intel_connector);
 extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
-extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode);
+extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+				      struct intel_crtc_config *);
 extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
 extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
 			    bool is_sdvob);
@@ -470,9 +472,8 @@ extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
-extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
+extern bool intel_dp_compute_config(struct intel_encoder *encoder,
+				    struct intel_crtc_config *pipe_config);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
 extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 92aba3c..cfc9d751 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -772,11 +772,12 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-			   const struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode)
+bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+			       struct intel_crtc_config *pipe_config)
 {
-	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (intel_hdmi->color_range_auto) {
 		/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -790,6 +791,9 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 	if (intel_hdmi->color_range)
 		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
 
+	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -941,7 +945,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
-	.mode_fixup = intel_hdmi_mode_fixup,
 	.mode_set = intel_hdmi_mode_set,
 };
 
@@ -1069,6 +1072,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
 
+	intel_encoder->compute_config = intel_hdmi_compute_config;
 	intel_encoder->enable = intel_enable_hdmi;
 	intel_encoder->disable = intel_disable_hdmi;
 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 1616f53..1f2efac 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -331,6 +331,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 			       adjusted_mode);
 
 	if (HAS_PCH_SPLIT(dev)) {
+		pipe_config->has_pch_encoder = true;
+
 		intel_pch_panel_fitting(dev,
 					intel_connector->panel.fitting_mode,
 					mode, adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3a45be0..7100196 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1045,6 +1045,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 
+	if (HAS_PCH_SPLIT(encoder->base.dev))
+		pipe_config->has_pch_encoder = true;
+
 	/* We need to construct preferred input timings based on our
 	 * output timings.  To do that, we have to set the output
 	 * timings, even though this isn't really the right place in
-- 
1.7.11.4

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

* [PATCH 07/10] drm/i915: add pipe_config->limited_color_range
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (5 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-02-26 17:46   ` Paulo Zanoni
  2013-02-21 23:56 ` [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config Daniel Vetter
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Now that we have a useful struct for this, let's use it. Some neat
pointer-chasing required, but it's all there already.

v2: Rebased on top of the added Haswell limited color range support.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 13 ++++++-------
 drivers/gpu/drm/i915/intel_dp.c      |  2 +-
 drivers/gpu/drm/i915/intel_drv.h     | 12 +++++++-----
 drivers/gpu/drm/i915/intel_hdmi.c    |  5 +++--
 drivers/gpu/drm/i915/intel_sdvo.c    |  5 +++--
 5 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c5f7c6e..a19778c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5131,7 +5131,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
 	else
 		val |= PIPECONF_PROGRESSIVE;
 
-	if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+	if (intel_crtc->config.limited_color_range)
 		val |= PIPECONF_COLOR_RANGE_SELECT;
 	else
 		val &= ~PIPECONF_COLOR_RANGE_SELECT;
@@ -5147,8 +5147,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
  * is supported, but eventually this should handle various
  * RGB<->YCbCr scenarios as well.
  */
-static void intel_set_pipe_csc(struct drm_crtc *crtc,
-			       const struct drm_display_mode *adjusted_mode)
+static void intel_set_pipe_csc(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5163,7 +5162,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
 	 * consideration.
 	 */
 
-	if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+	if (intel_crtc->config.limited_color_range)
 		coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
 
 	/*
@@ -5187,7 +5186,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
 	if (INTEL_INFO(dev)->gen > 6) {
 		uint16_t postoff = 0;
 
-		if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+		if (intel_crtc->config.limited_color_range)
 			postoff = (16 * (1 << 13) / 255) & 0x1fff;
 
 		I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
@@ -5198,7 +5197,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
 	} else {
 		uint32_t mode = CSC_MODE_YUV_TO_RGB;
 
-		if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+		if (intel_crtc->config.limited_color_range)
 			mode |= CSC_BLACK_SCREEN_OFFSET;
 
 		I915_WRITE(PIPE_CSC_MODE(pipe), mode);
@@ -5794,7 +5793,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 
 	haswell_set_pipeconf(crtc, adjusted_mode, dither);
 
-	intel_set_pipe_csc(crtc, adjusted_mode);
+	intel_set_pipe_csc(crtc);
 
 	/* Set up the display plane register */
 	I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e851fdd..0f15513 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -739,7 +739,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	}
 
 	if (intel_dp->color_range)
-		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
+		pipe_config->limited_color_range = true;
 
 	mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 458e6bd..61ce435 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -103,11 +103,6 @@
 
 /* drm_display_mode->private_flags */
 #define INTEL_MODE_DP_FORCE_6BPC (0x10)
-/*
- * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
- * to be used.
- */
-#define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
 
 struct intel_framebuffer {
 	struct drm_framebuffer base;
@@ -192,6 +187,13 @@ struct intel_crtc_config {
 	/* Whether to set up the PCH/FDI. Note that we never allow sharing
 	 * between pch encoders and cpu encoders. */
 	bool has_pch_encoder;
+
+	/*
+	 * Use reduced/limited/broadcast rbg range, compressing from the full
+	 * range fed into the crtcs.
+	 */
+	bool limited_color_range;
+
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 };
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index cfc9d751..a8e7104 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -332,6 +332,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
 					 struct drm_display_mode *adjusted_mode)
 {
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
 	struct dip_infoframe avi_if = {
 		.type = DIP_TYPE_AVI,
 		.ver = DIP_VERSION_AVI,
@@ -342,7 +343,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
 		avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
 
 	if (intel_hdmi->rgb_quant_range_selectable) {
-		if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+		if (intel_crtc->config.limited_color_range)
 			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
 		else
 			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
@@ -789,7 +790,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	}
 
 	if (intel_hdmi->color_range)
-		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
+		pipe_config->limited_color_range = true;
 
 	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
 		pipe_config->has_pch_encoder = true;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 7100196..59a6781 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -956,9 +956,10 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
 		.len = DIP_LEN_AVI,
 	};
 	uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
+	struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc);
 
 	if (intel_sdvo->rgb_quant_range_selectable) {
-		if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
+		if (intel_crtc->config.limited_color_range)
 			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
 		else
 			avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
@@ -1087,7 +1088,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 	}
 
 	if (intel_sdvo->color_range)
-		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
+		pipe_config->limited_color_range = true;
 
 	return true;
 }
-- 
1.7.11.4

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

* [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (6 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 07/10] drm/i915: add pipe_config->limited_color_range Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-03-26 21:12   ` Jesse Barnes
  2013-02-21 23:56 ` [PATCH 09/10] drm/i915: clean up plane bpp confusion Daniel Vetter
  2013-02-21 23:56 ` [PATCH 10/10] drm/i915: clean up pipe " Daniel Vetter
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

The procedure has now 3 steps:

1. Compute the bpp that the plane will output, this is done in
   pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
   this function clamps the pipe_bpp to whatever limit the EDID of any
   connected output specifies.
2. Adjust the pipe_bpp in the encoder and crtc functions, according to
   whatever constraints there are.
3. Decide whether to use dither by comparing the stored plane bpp with
   computed pipe_bpp.

There are a few slight functional changes in this patch:
- LVDS connector are now also going through the EDID clamping. But in
  a 2nd change we now unconditionally force the lvds bpc value - this
  shouldn't matter in reality when the panel setup is consistent, but
  better safe than sorry.
- HDMI now forces the pipe_bpp to the selected value - I think that's
  what we actually want, since otherwise at least the pixelclock
  computations are wrong (I'm not sure whether the port would accept
  e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
  the next higher bpc value, since otherwise there's no way to make
  use of the 12 bpc mode (since the next patch will remove the 12bpc
  plane format, it doesn't exist).

Both of these changes are due to the removal of the

	pipe_bpp = min(display_bpp, plane_bpp);

statement.

Another slight change is the reworking of the dp bpc code:
- For the mode_valid callback it's sufficient to only check whether
  the mode would fit at the lowest bpc.
- The bandwidth computation code is a bit restructured: It now walks
  all available bpp values in an outer loop and the codeblock that
  computes derived values (once a good configuration is found) has been
  moved out of the for loop maze. This is prep work to allow us to
  successively fall back on bpc values, and also correctly support bpc
  values != 8 or 6.

v2: Rebased on top of Paulo Zanoni's little refactoring to use more
drm dp helper functions.

v3: Rebased on top of Jani's eDP bpp fix and Ville's limited color
range work.

v4: Remove the INTEL_MODE_DP_FORCE_6BPC #define, no longer needed.

v5: Remove intel_crtc->bpp, too, and fix up the 12bpc check in the
hdmi code. Also fixup the bpp check in intel_dp.c, it'll get reworked
in a later patch though again.

v6: Fix spelling in a comment.

v7: Debug output improvements for the bpp computation.

v8: Fixup 6bpc lvds check - dual-link and 8bpc mode are different
things!

v9: Reinstate the fix to properly ignore the firmware edp bpp ... this
was lost in a rebase.

v10: Both g4x and vlv lack 12bpc pipes, so don't enforce that we have
that. Still unsure whether this is the way to go, but at least 6bpc
for a 8bpc hdmi output seems to work.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_ddi.c     |  11 +-
 drivers/gpu/drm/i915/intel_display.c | 223 ++++++++++++-----------------------
 drivers/gpu/drm/i915/intel_dp.c      | 105 ++++++++---------
 drivers/gpu/drm/i915/intel_drv.h     |   7 +-
 drivers/gpu/drm/i915/intel_hdmi.c    |  14 ++-
 drivers/gpu/drm/i915/intel_lvds.c    |  12 ++
 6 files changed, 155 insertions(+), 217 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f5ae79f..3a8c0ab 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -928,7 +928,7 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 	if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
 
 		temp = TRANS_MSA_SYNC_CLK;
-		switch (intel_crtc->bpp) {
+		switch (intel_crtc->config.pipe_bpp) {
 		case 18:
 			temp |= TRANS_MSA_6_BPC;
 			break;
@@ -942,9 +942,7 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
 			temp |= TRANS_MSA_12_BPC;
 			break;
 		default:
-			temp |= TRANS_MSA_8_BPC;
-			WARN(1, "%d bpp unsupported by DDI function\n",
-			     intel_crtc->bpp);
+			BUG();
 		}
 		I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
 	}
@@ -966,7 +964,7 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc)
 	temp = TRANS_DDI_FUNC_ENABLE;
 	temp |= TRANS_DDI_SELECT_PORT(port);
 
-	switch (intel_crtc->bpp) {
+	switch (intel_crtc->config.pipe_bpp) {
 	case 18:
 		temp |= TRANS_DDI_BPC_6;
 		break;
@@ -980,8 +978,7 @@ void intel_ddi_enable_pipe_func(struct drm_crtc *crtc)
 		temp |= TRANS_DDI_BPC_12;
 		break;
 	default:
-		WARN(1, "%d bpp unsupported by transcoder DDI function\n",
-		     intel_crtc->bpp);
+		BUG();
 	}
 
 	if (crtc->mode.flags & DRM_MODE_FLAG_PVSYNC)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a19778c..04ae8ae 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4019,142 +4019,6 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
 		&& !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
 }
 
-/**
- * intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send
- * @crtc: CRTC structure
- * @mode: requested mode
- *
- * A pipe may be connected to one or more outputs.  Based on the depth of the
- * attached framebuffer, choose a good color depth to use on the pipe.
- *
- * If possible, match the pipe depth to the fb depth.  In some cases, this
- * isn't ideal, because the connected output supports a lesser or restricted
- * set of depths.  Resolve that here:
- *    LVDS typically supports only 6bpc, so clamp down in that case
- *    HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc
- *    Displays may support a restricted set as well, check EDID and clamp as
- *      appropriate.
- *    DP may want to dither down to 6bpc to fit larger modes
- *
- * RETURNS:
- * Dithering requirement (i.e. false if display bpc and pipe bpc match,
- * true if they don't match).
- */
-static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
-					 struct drm_framebuffer *fb,
-					 unsigned int *pipe_bpp,
-					 struct drm_display_mode *mode)
-{
-	struct drm_device *dev = crtc->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_connector *connector;
-	struct intel_encoder *intel_encoder;
-	unsigned int display_bpc = UINT_MAX, bpc;
-
-	/* Walk the encoders & connectors on this crtc, get min bpc */
-	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
-
-		if (intel_encoder->type == INTEL_OUTPUT_LVDS) {
-			unsigned int lvds_bpc;
-
-			if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) ==
-			    LVDS_A3_POWER_UP)
-				lvds_bpc = 8;
-			else
-				lvds_bpc = 6;
-
-			if (lvds_bpc < display_bpc) {
-				DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc);
-				display_bpc = lvds_bpc;
-			}
-			continue;
-		}
-
-		/* Not one of the known troublemakers, check the EDID */
-		list_for_each_entry(connector, &dev->mode_config.connector_list,
-				    head) {
-			if (connector->encoder != &intel_encoder->base)
-				continue;
-
-			/* Don't use an invalid EDID bpc value */
-			if (connector->display_info.bpc &&
-			    connector->display_info.bpc < display_bpc) {
-				DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc);
-				display_bpc = connector->display_info.bpc;
-			}
-		}
-
-		if (intel_encoder->type == INTEL_OUTPUT_EDP) {
-			/* Use VBT settings if we have an eDP panel */
-			unsigned int edp_bpc = dev_priv->edp.bpp / 3;
-
-			if (edp_bpc && edp_bpc < display_bpc) {
-				DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
-				display_bpc = edp_bpc;
-			}
-			continue;
-		}
-
-		/*
-		 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
-		 * through, clamp it down.  (Note: >12bpc will be caught below.)
-		 */
-		if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-			if (display_bpc > 8 && display_bpc < 12) {
-				DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
-				display_bpc = 12;
-			} else {
-				DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
-				display_bpc = 8;
-			}
-		}
-	}
-
-	if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
-		DRM_DEBUG_KMS("Dithering DP to 6bpc\n");
-		display_bpc = 6;
-	}
-
-	/*
-	 * We could just drive the pipe at the highest bpc all the time and
-	 * enable dithering as needed, but that costs bandwidth.  So choose
-	 * the minimum value that expresses the full color range of the fb but
-	 * also stays within the max display bpc discovered above.
-	 */
-
-	switch (fb->depth) {
-	case 8:
-		bpc = 8; /* since we go through a colormap */
-		break;
-	case 15:
-	case 16:
-		bpc = 6; /* min is 18bpp */
-		break;
-	case 24:
-		bpc = 8;
-		break;
-	case 30:
-		bpc = 10;
-		break;
-	case 48:
-		bpc = 12;
-		break;
-	default:
-		DRM_DEBUG("unsupported depth, assuming 24 bits\n");
-		bpc = min((unsigned int)8, display_bpc);
-		break;
-	}
-
-	display_bpc = min(display_bpc, bpc);
-
-	DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n",
-		      bpc, display_bpc);
-
-	*pipe_bpp = display_bpc * 3;
-
-	return display_bpc != bpc;
-}
-
 static int vlv_get_refclk(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -4706,7 +4570,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	/* default to 8bpc */
 	pipeconf &= ~(PIPECONF_BPC_MASK | PIPECONF_DITHER_EN);
 	if (is_dp) {
-		if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
+		if (intel_crtc->config.dither) {
 			pipeconf |= PIPECONF_6BPC |
 				    PIPECONF_DITHER_EN |
 				    PIPECONF_DITHER_TYPE_SP;
@@ -4714,7 +4578,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	}
 
 	if (IS_VALLEYVIEW(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
-		if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
+		if (intel_crtc->config.dither) {
 			pipeconf |= PIPECONF_6BPC |
 					PIPECONF_ENABLE |
 					I965_PIPECONF_ACTIVE;
@@ -5103,7 +4967,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
 	val = I915_READ(PIPECONF(pipe));
 
 	val &= ~PIPECONF_BPC_MASK;
-	switch (intel_crtc->bpp) {
+	switch (intel_crtc->config.pipe_bpp) {
 	case 18:
 		val |= PIPECONF_6BPC;
 		break;
@@ -5440,13 +5304,14 @@ static void ironlake_set_m_n(struct drm_crtc *crtc)
 
 	if (!lane)
 		lane = ironlake_get_lanes_required(target_clock, link_bw,
-						   intel_crtc->bpp);
+						   intel_crtc->config.pipe_bpp);
 
 	intel_crtc->fdi_lanes = lane;
 
 	if (intel_crtc->config.pixel_multiplier > 1)
 		link_bw *= intel_crtc->config.pixel_multiplier;
-	intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
+	intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane, target_clock,
+			       link_bw, &m_n);
 
 	I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
 	I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n);
@@ -5609,8 +5474,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 	intel_crtc_update_cursor(crtc, true);
 
 	/* determine panel color depth */
-	dither = intel_choose_pipe_bpp_dither(crtc, fb, &intel_crtc->bpp,
-					      adjusted_mode);
+	dither = intel_crtc->config.dither;
 	if (is_lvds && dev_priv->lvds_dither)
 		dither = true;
 
@@ -5775,8 +5639,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 	intel_crtc_update_cursor(crtc, true);
 
 	/* determine panel color depth */
-	dither = intel_choose_pipe_bpp_dither(crtc, fb, &intel_crtc->bpp,
-					      adjusted_mode);
+	dither = intel_crtc->config.dither;
 
 	DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
 	drm_mode_debug_printmodeline(mode);
@@ -7463,14 +7326,72 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
 	}
 }
 
+static int
+pipe_config_set_bpp(struct drm_crtc *crtc,
+		    struct drm_framebuffer *fb,
+		    struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_connector *connector;
+	int bpp;
+
+	switch (fb->depth) {
+	case 8:
+		bpp = 8*3; /* since we go through a colormap */
+		break;
+	case 15:
+	case 16:
+		bpp = 6*3; /* min is 18bpp */
+		break;
+	case 24:
+		bpp = 8*3;
+		break;
+	case 30:
+		bpp = 10*3;
+		break;
+	case 48:
+		bpp = 12*3;
+		break;
+	default:
+		DRM_DEBUG_KMS("unsupported depth\n");
+		return -EINVAL;
+	}
+
+	if (fb->depth > 24 && !HAS_PCH_SPLIT(dev)) {
+		DRM_DEBUG_KMS("high depth not supported on gmch platforms\n");
+		return -EINVAL;
+	}
+
+	pipe_config->pipe_bpp = bpp;
+
+	/* Clamp display bpp to EDID value */
+	list_for_each_entry(connector, &dev->mode_config.connector_list,
+			    head) {
+		if (connector->encoder && connector->encoder->crtc != crtc)
+			continue;
+
+		/* Don't use an invalid EDID bpc value */
+		if (connector->display_info.bpc &&
+		    connector->display_info.bpc * 3 < bpp) {
+			DRM_DEBUG_KMS("clamping display bpp (was %d) to EDID reported max of %d\n",
+				      bpp, connector->display_info.bpc*3);
+			pipe_config->pipe_bpp = connector->display_info.bpc*3;
+		}
+	}
+
+	return bpp;
+}
+
 static struct intel_crtc_config *
 intel_modeset_pipe_config(struct drm_crtc *crtc,
+			  struct drm_framebuffer *fb,
 			  struct drm_display_mode *mode)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
 	struct intel_crtc_config *pipe_config;
+	int plane_bpp;
 
 	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
 	if (!pipe_config)
@@ -7481,6 +7402,10 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 	drm_mode_copy(&pipe_config->requested_mode, mode);
 	pipe_config->requested_mode.base.id = 0;
 
+	plane_bpp = pipe_config_set_bpp(crtc, fb, pipe_config);
+	if (plane_bpp < 0)
+		goto fail;
+
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -7515,6 +7440,10 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
 	}
 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
+	pipe_config->dither = pipe_config->pipe_bpp != plane_bpp;
+	DRM_DEBUG_KMS("plane bpp: %i, pipe bpp: %i, dithering: %i\n",
+		      plane_bpp, pipe_config->pipe_bpp, pipe_config->dither);
+
 	return pipe_config;
 fail:
 	kfree(pipe_config);
@@ -7806,7 +7735,7 @@ int intel_set_mode(struct drm_crtc *crtc,
 	 * pieces of code that are not yet converted to deal with mutliple crtcs
 	 * changing their mode at the same time. */
 	if (modeset_pipes) {
-		pipe_config = intel_modeset_pipe_config(crtc, mode);
+		pipe_config = intel_modeset_pipe_config(crtc, fb, mode);
 		if (IS_ERR(pipe_config)) {
 			ret = PTR_ERR(pipe_config);
 			pipe_config = NULL;
@@ -8245,8 +8174,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
 	dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
 
-	intel_crtc->bpp = 24; /* default for pre-Ironlake */
-
 	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0f15513..a4c9858 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -177,34 +177,6 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return (max_link_clock * max_lanes * 8) / 10;
 }
 
-static bool
-intel_dp_adjust_dithering(struct intel_dp *intel_dp,
-			  struct drm_display_mode *mode,
-			  bool adjust_mode)
-{
-	int max_link_clock =
-		drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
-	int max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
-	int max_rate, mode_rate;
-
-	mode_rate = intel_dp_link_required(mode->clock, 24);
-	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
-
-	if (mode_rate > max_rate) {
-		mode_rate = intel_dp_link_required(mode->clock, 18);
-		if (mode_rate > max_rate)
-			return false;
-
-		if (adjust_mode)
-			mode->private_flags
-				|= INTEL_MODE_DP_FORCE_6BPC;
-
-		return true;
-	}
-
-	return true;
-}
-
 static int
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -212,6 +184,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
+	int target_clock = mode->clock;
+	int max_rate, mode_rate, max_lanes, max_link_clock;
 
 	if (is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
@@ -221,7 +195,13 @@ intel_dp_mode_valid(struct drm_connector *connector,
 			return MODE_PANEL;
 	}
 
-	if (!intel_dp_adjust_dithering(intel_dp, mode, false))
+	max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
+	max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
+
+	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+	mode_rate = intel_dp_link_required(target_clock, 18);
+
+	if (mode_rate > max_rate)
 		return MODE_CLOCK_HIGH;
 
 	if (mode->clock < 10000)
@@ -693,6 +673,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_config *pipe_config)
 {
 	struct drm_device *dev = encoder->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@ -702,6 +683,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
+	int target_clock, link_avail, link_clock;
 
 	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))
 		pipe_config->has_pch_encoder = true;
@@ -713,6 +695,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 					intel_connector->panel.fitting_mode,
 					mode, adjusted_mode);
 	}
+	/* We need to take the panel's fixed mode into account. */
+	target_clock = adjusted_mode->clock;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
 		return false;
@@ -721,11 +705,31 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 		      "max bw %02x pixel clock %iKHz\n",
 		      max_lane_count, bws[max_clock], adjusted_mode->clock);
 
-	if (!intel_dp_adjust_dithering(intel_dp, adjusted_mode, true))
-		return false;
+	/* Walk through all bpp values. Luckily they're all nicely spaced with 2
+	 * bpc in between. */
+	bpp = 8*3;
+	if (is_edp(intel_dp) && dev_priv->edp.bpp)
+		bpp = min_t(int, bpp, dev_priv->edp.bpp);
+
+	for (; bpp >= 6*3; bpp -= 2*3) {
+		mode_rate = intel_dp_link_required(target_clock, bpp);
+
+		for (clock = 0; clock <= max_clock; clock++) {
+			for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
+				link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
+				link_avail = intel_dp_max_data_rate(link_clock,
+								    lane_count);
+
+				if (mode_rate <= link_avail) {
+					goto found;
+				}
+			}
+		}
+	}
 
-	bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+	return false;
 
+found:
 	if (intel_dp->color_range_auto) {
 		/*
 		 * See:
@@ -741,31 +745,18 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	if (intel_dp->color_range)
 		pipe_config->limited_color_range = true;
 
-	mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
-
-	for (clock = 0; clock <= max_clock; clock++) {
-		for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
-			int link_bw_clock =
-				drm_dp_bw_code_to_link_rate(bws[clock]);
-			int link_avail = intel_dp_max_data_rate(link_bw_clock,
-								lane_count);
-
-			if (mode_rate <= link_avail) {
-				intel_dp->link_bw = bws[clock];
-				intel_dp->lane_count = lane_count;
-				adjusted_mode->clock = link_bw_clock;
-				DRM_DEBUG_KMS("DP link bw %02x lane "
-						"count %d clock %d bpp %d\n",
-				       intel_dp->link_bw, intel_dp->lane_count,
-				       adjusted_mode->clock, bpp);
-				DRM_DEBUG_KMS("DP link bw required %i available %i\n",
-					      mode_rate, link_avail);
-				return true;
-			}
-		}
-	}
+	intel_dp->link_bw = bws[clock];
+	intel_dp->lane_count = lane_count;
+	adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
+	pipe_config->pipe_bpp = bpp;
 
-	return false;
+	DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n",
+		      intel_dp->link_bw, intel_dp->lane_count,
+		      adjusted_mode->clock, bpp);
+	DRM_DEBUG_KMS("DP link bw required %i available %i\n",
+		      mode_rate, link_avail);
+
+	return true;
 }
 
 void
@@ -801,7 +792,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 	 * the number of bytes_per_pixel post-LUT, which we always
 	 * set up for 8-bits of R/G/B, or 3 bytes total.
 	 */
-	intel_link_compute_m_n(intel_crtc->bpp, lane_count,
+	intel_link_compute_m_n(intel_crtc->config.pipe_bpp, lane_count,
 			       mode->clock, adjusted_mode->clock, &m_n);
 
 	if (HAS_DDI(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 61ce435..e43155a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -101,9 +101,6 @@
 #define INTEL_DVO_CHIP_TMDS 2
 #define INTEL_DVO_CHIP_TVOUT 4
 
-/* drm_display_mode->private_flags */
-#define INTEL_MODE_DP_FORCE_6BPC (0x10)
-
 struct intel_framebuffer {
 	struct drm_framebuffer base;
 	struct drm_i915_gem_object *obj;
@@ -194,6 +191,9 @@ struct intel_crtc_config {
 	 */
 	bool limited_color_range;
 
+	bool dither;
+	int pipe_bpp;
+
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 };
@@ -229,7 +229,6 @@ struct intel_crtc {
 	int16_t cursor_x, cursor_y;
 	int16_t cursor_width, cursor_height;
 	bool cursor_visible;
-	unsigned int bpp;
 
 	struct intel_crtc_config config;
 
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index a8e7104..47d3a21 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -608,7 +608,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
 	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
 		hdmi_val |= SDVO_HSYNC_ACTIVE_HIGH;
 
-	if (intel_crtc->bpp > 24)
+	if (intel_crtc->config.pipe_bpp > 24)
 		hdmi_val |= COLOR_FORMAT_12bpc;
 	else
 		hdmi_val |= COLOR_FORMAT_8bpc;
@@ -795,6 +795,18 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
 		pipe_config->has_pch_encoder = true;
 
+	/*
+	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
+	 * through, clamp it down.
+	 */
+	if (pipe_config->pipe_bpp > 8*3) {
+		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
+		pipe_config->pipe_bpp = 12*3;
+	} else {
+		DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n");
+		pipe_config->pipe_bpp = 8*3;
+	}
+
 	return true;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 1f2efac..4eb57de 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -310,6 +310,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 	struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
 	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
+	unsigned int lvds_bpp;
 	int pipe;
 
 	/* Should never happen!! */
@@ -321,6 +322,17 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 	if (intel_encoder_check_is_cloned(&lvds_encoder->base))
 		return false;
 
+	if ((I915_READ(lvds_encoder->reg) & LVDS_A3_POWER_MASK) ==
+	    LVDS_A3_POWER_UP)
+		lvds_bpp = 8*3;
+	else
+		lvds_bpp = 6*3;
+
+	if (lvds_bpp != pipe_config->pipe_bpp) {
+		DRM_DEBUG_KMS("forcing display bpp (was %d) to LVDS (%d)\n",
+			      pipe_config->pipe_bpp, lvds_bpp);
+		pipe_config->pipe_bpp = lvds_bpp;
+	}
 	/*
 	 * We have timings from the BIOS for the panel, put them in
 	 * to the adjusted mode.  The CRTC will be set up for this mode,
-- 
1.7.11.4

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

* [PATCH 09/10] drm/i915: clean up plane bpp confusion
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (7 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-03-26 21:04   ` Jesse Barnes
  2013-02-21 23:56 ` [PATCH 10/10] drm/i915: clean up pipe " Daniel Vetter
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

- There is no 16bpc linear color format in our hw. gen4+ has a 16 bpc
  float layout, but we don't really support it.
- 10bpc is a gen4+ feature, fix up the support for it.
- Update_plane should never see a wrong fb bpp value, BUG in the
  corresponding cases.

v2: Rebase on top of Ville's plane pixel layout changes.

v3: Actually drop the old gen4 check for 10bpc planes, spotted
by Ville Syrjälä.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 04ae8ae..1258883 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2083,8 +2083,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 		dspcntr |= DISPPLANE_RGBX101010;
 		break;
 	default:
-		DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
-		return -EINVAL;
+		BUG();
 	}
 
 	if (INTEL_INFO(dev)->gen >= 4) {
@@ -2177,8 +2176,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
 		dspcntr |= DISPPLANE_RGBX101010;
 		break;
 	default:
-		DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
-		return -EINVAL;
+		BUG();
 	}
 
 	if (obj->tiling_mode != I915_TILING_NONE)
@@ -7347,21 +7345,19 @@ pipe_config_set_bpp(struct drm_crtc *crtc,
 		bpp = 8*3;
 		break;
 	case 30:
+		if (INTEL_INFO(dev)->gen < 4) {
+			DRM_DEBUG_KMS("10 bpc not supported on gen2/3\n");
+			return -EINVAL;
+		}
+
 		bpp = 10*3;
 		break;
-	case 48:
-		bpp = 12*3;
-		break;
+	/* TODO: gen4+ supports 16 bpc floating point, too. */
 	default:
 		DRM_DEBUG_KMS("unsupported depth\n");
 		return -EINVAL;
 	}
 
-	if (fb->depth > 24 && !HAS_PCH_SPLIT(dev)) {
-		DRM_DEBUG_KMS("high depth not supported on gmch platforms\n");
-		return -EINVAL;
-	}
-
 	pipe_config->pipe_bpp = bpp;
 
 	/* Clamp display bpp to EDID value */
-- 
1.7.11.4

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

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

* [PATCH 10/10] drm/i915: clean up pipe bpp confusion
  2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
                   ` (8 preceding siblings ...)
  2013-02-21 23:56 ` [PATCH 09/10] drm/i915: clean up plane bpp confusion Daniel Vetter
@ 2013-02-21 23:56 ` Daniel Vetter
  2013-03-26 21:06   ` Jesse Barnes
  9 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-21 23:56 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

- gen4 and earlier (save for g4x) only really have a 8bpc pipe, with
  the possibility to dither to 6bpc using the panel fitter
- g4x has hdmi, but no 12 bpc pipe ... !? Clamp hdmi accordingly.
- TV/SDVO out are the only connectors available on platforms with
  a pipe bpp != 8, add code to force the pipe to 8bpc unconditionally.

<rant>
The dither handling on gmch platforms is one giant disaster. I'm hoping
somewhat that vlv enabling will fix this up, but given that the 6bpc
handling for edp was simply added with another quick hack, I don't have
high hopes ...
</rant>

v2: Neither vlv nor g4x have 12bpc pipes. Still set pipe_bpp to 12*3,
but let the crtc code clamp things down to 10bpc on these platforms.

v3: Fix a bpc vs. bpp mixup in the gen4 and earlier pipe_bpp limiter
code.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c |  8 ++++++++
 drivers/gpu/drm/i915/intel_hdmi.c    |  4 +++-
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
 drivers/gpu/drm/i915/intel_tv.c      | 14 ++++++++------
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1258883..f1d47dd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3914,6 +3914,14 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
 		adjusted_mode->hsync_start == adjusted_mode->hdisplay)
 		return false;
 
+	if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10) {
+		pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */
+	} else if (INTEL_INFO(dev)->gen <= 4 && pipe_config->pipe_bpp > 8) {
+		/* only a 8bpc pipe, with 6bpc dither through the panel fitter
+		 * for lvds. */
+		pipe_config->pipe_bpp = 8*3;
+	}
+
 	return true;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 47d3a21..0e51b2b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -797,7 +797,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
 
 	/*
 	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
-	 * through, clamp it down.
+	 * through, clamp it down. Note that only pch_split platforms have 12bpc
+	 * pipes, g4x and vlv only has a 10bpc pipe, all earlier platforms have
+	 * only 8bpc.
 	 */
 	if (pipe_config->pipe_bpp > 8*3) {
 		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 59a6781..a443086 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1046,6 +1046,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 
+	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
+	pipe_config->pipe_bpp = 8*3;
+
 	if (HAS_PCH_SPLIT(encoder->base.dev))
 		pipe_config->has_pch_encoder = true;
 
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index d808421..6673726 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -905,11 +905,10 @@ intel_tv_mode_valid(struct drm_connector *connector,
 
 
 static bool
-intel_tv_mode_fixup(struct drm_encoder *encoder,
-		    const struct drm_display_mode *mode,
-		    struct drm_display_mode *adjusted_mode)
+intel_tv_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_config *pipe_config)
 {
-	struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
+	struct intel_tv *intel_tv = enc_to_intel_tv(&encoder->base);
 	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
 
 	if (!tv_mode)
@@ -918,7 +917,10 @@ intel_tv_mode_fixup(struct drm_encoder *encoder,
 	if (intel_encoder_check_is_cloned(&intel_tv->base))
 		return false;
 
-	adjusted_mode->clock = tv_mode->clock;
+	pipe_config->adjusted_mode.clock = tv_mode->clock;
+	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
+	pipe_config->pipe_bpp = 8*3;
+
 	return true;
 }
 
@@ -1485,7 +1487,6 @@ out:
 }
 
 static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
-	.mode_fixup = intel_tv_mode_fixup,
 	.mode_set = intel_tv_mode_set,
 };
 
@@ -1620,6 +1621,7 @@ intel_tv_init(struct drm_device *dev)
 	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
 			 DRM_MODE_ENCODER_TVDAC);
 
+	intel_encoder->compute_config = intel_tv_compute_config;
 	intel_encoder->enable = intel_enable_tv;
 	intel_encoder->disable = intel_disable_tv;
 	intel_encoder->get_hw_state = intel_tv_get_hw_state;
-- 
1.7.11.4

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

* Re: [PATCH 01/10] drm/i915: introduce struct intel_crtc_config
  2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
@ 2013-02-22 10:23   ` Ville Syrjälä
  2013-02-22 11:05   ` [PATCH] " Daniel Vetter
  1 sibling, 0 replies; 31+ messages in thread
From: Ville Syrjälä @ 2013-02-22 10:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

On Fri, Feb 22, 2013 at 12:56:45AM +0100, Daniel Vetter wrote:
> Currently only containing the requested and the adjusted mode. And
> only crtc callbacks are converted somewhat to it, encoders will be
> done on a as-needed basis (simply too much churn in one patch
> otherwise).
> 
> Future patches will add tons more useful stuff to this struct,
> starting with the very simple.
> 
> v2: Store the pipe_config in the intel_crtc, so that the ->mode-set,
> ->enable and also ->disable have easy access to it.
> 
> v3: Store the pipe config in the right crtc ...
> 
> v4: Rebased.
> 
> v5: Fixup an OOPS when trying to kfree an ERR_PTR.
> 
> v6: Used drm_moode_copy and some other small cleanups as suggested
> by Ville Syrjälä.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  4 +-
>  drivers/gpu/drm/i915/intel_display.c | 83 +++++++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_drv.h     |  7 +++
>  3 files changed, 58 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e95337c..8fb14fb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -271,6 +271,8 @@ struct drm_i915_error_state {
>  	struct intel_display_error_state *display;
>  };
>  
> +struct intel_crtc_config;
> +
>  struct drm_i915_display_funcs {
>  	bool (*fbc_enabled)(struct drm_device *dev);
>  	void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
> @@ -284,8 +286,6 @@ struct drm_i915_display_funcs {
>  				 struct drm_display_mode *mode);
>  	void (*modeset_global_resources)(struct drm_device *dev);
>  	int (*crtc_mode_set)(struct drm_crtc *crtc,
> -			     struct drm_display_mode *mode,
> -			     struct drm_display_mode *adjusted_mode,
>  			     int x, int y,
>  			     struct drm_framebuffer *old_fb);
>  	void (*crtc_enable)(struct drm_crtc *crtc);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b521198..5a3e231 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
>  	return encoder->get_hw_state(encoder, &pipe);
>  }
>  
> -static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
> -				  const struct drm_display_mode *mode,
> -				  struct drm_display_mode *adjusted_mode)
> +static bool intel_crtc_compute_config(struct drm_crtc *crtc,
> +				      struct intel_crtc_config *pipe_config)
>  {
>  	struct drm_device *dev = crtc->dev;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>  
>  	if (HAS_PCH_SPLIT(dev)) {
>  		/* FDI link clock is fixed at 2.7G */
> -		if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
> +		if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4)
>  			return false;
>  	}
>  
> @@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
>  }
>  
>  static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> -			      struct drm_display_mode *mode,
> -			      struct drm_display_mode *adjusted_mode,
>  			      int x, int y,
>  			      struct drm_framebuffer *fb)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&intel_crtc->config.adjusted_mode;
> +	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>  	int pipe = intel_crtc->pipe;
>  	int plane = intel_crtc->plane;
>  	int refclk, num_connectors = 0;
> @@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>  }
>  
>  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> -				  struct drm_display_mode *mode,
> -				  struct drm_display_mode *adjusted_mode,
>  				  int x, int y,
>  				  struct drm_framebuffer *fb)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&intel_crtc->config.adjusted_mode;
> +	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>  	int pipe = intel_crtc->pipe;
>  	int plane = intel_crtc->plane;
>  	int num_connectors = 0;
> @@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
>  }
>  
>  static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> -				 struct drm_display_mode *mode,
> -				 struct drm_display_mode *adjusted_mode,
>  				 int x, int y,
>  				 struct drm_framebuffer *fb)
>  {
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&intel_crtc->config.adjusted_mode;
> +	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>  	int pipe = intel_crtc->pipe;
>  	int plane = intel_crtc->plane;
>  	int num_connectors = 0;
> @@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>  }
>  
>  static int intel_crtc_mode_set(struct drm_crtc *crtc,
> -			       struct drm_display_mode *mode,
> -			       struct drm_display_mode *adjusted_mode,
>  			       int x, int y,
>  			       struct drm_framebuffer *fb)
>  {
> @@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>  	struct drm_encoder_helper_funcs *encoder_funcs;
>  	struct intel_encoder *encoder;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	struct drm_display_mode *adjusted_mode =
> +		&intel_crtc->config.adjusted_mode;
> +	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>  	int pipe = intel_crtc->pipe;
>  	int ret;
>  
> @@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>  
>  	drm_vblank_pre_modeset(dev, pipe);
>  
> -	ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
> -					      x, y, fb);
> +	ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
> +
>  	drm_vblank_post_modeset(dev, pipe);
>  
>  	if (ret != 0)
> @@ -7478,19 +7482,24 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
>  	}
>  }
>  
> -static struct drm_display_mode *
> -intel_modeset_adjusted_mode(struct drm_crtc *crtc,
> -			    struct drm_display_mode *mode)
> +static struct intel_crtc_config *
> +intel_modeset_pipe_config(struct drm_crtc *crtc,
> +			  struct drm_display_mode *mode)
>  {
>  	struct drm_device *dev = crtc->dev;
> -	struct drm_display_mode *adjusted_mode;
>  	struct drm_encoder_helper_funcs *encoder_funcs;
>  	struct intel_encoder *encoder;
> +	struct intel_crtc_config *pipe_config;
>  
> -	adjusted_mode = drm_mode_duplicate(dev, mode);
> -	if (!adjusted_mode)
> +	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> +	if (!pipe_config)
>  		return ERR_PTR(-ENOMEM);
>  
> +	drm_mode_copy(&pipe_config->adjusted_mode, mode);
> +	pipe_config->adjusted_mode.base.id = 0;
> +	drm_mode_copy(&pipe_config->requested_mode, mode);
> +	pipe_config->requested_mode.base.id = 0;

drm_mode_copy() preserves the destination mode's id, and since you
kzalloc() the whole thing there's no need to zero the ids explicitly.
That was pretty much why I suggeted it.

The rest looks good to me.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

-- 
Ville Syrjälä
Intel OTC

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

* [PATCH] drm/i915: introduce struct intel_crtc_config
  2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
  2013-02-22 10:23   ` Ville Syrjälä
@ 2013-02-22 11:05   ` Daniel Vetter
  2013-02-26 17:09     ` Paulo Zanoni
  1 sibling, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-02-22 11:05 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

Currently only containing the requested and the adjusted mode. And
only crtc callbacks are converted somewhat to it, encoders will be
done on a as-needed basis (simply too much churn in one patch
otherwise).

Future patches will add tons more useful stuff to this struct,
starting with the very simple.

v2: Store the pipe_config in the intel_crtc, so that the ->mode-set,
->enable and also ->disable have easy access to it.

v3: Store the pipe config in the right crtc ...

v4: Rebased.

v5: Fixup an OOPS when trying to kfree an ERR_PTR.

v6: Used drm_moode_copy and some other small cleanups as suggested
by Ville Syrjälä.

v7: drm_mode_copy preserves the mode id of the destination, so no need
to clear it again (Ville).

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h      |  4 +-
 drivers/gpu/drm/i915/intel_display.c | 81 +++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_drv.h     |  7 ++++
 3 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e95337c..8fb14fb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -271,6 +271,8 @@ struct drm_i915_error_state {
 	struct intel_display_error_state *display;
 };
 
+struct intel_crtc_config;
+
 struct drm_i915_display_funcs {
 	bool (*fbc_enabled)(struct drm_device *dev);
 	void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
@@ -284,8 +286,6 @@ struct drm_i915_display_funcs {
 				 struct drm_display_mode *mode);
 	void (*modeset_global_resources)(struct drm_device *dev);
 	int (*crtc_mode_set)(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode,
 			     int x, int y,
 			     struct drm_framebuffer *old_fb);
 	void (*crtc_enable)(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b521198..a02c6a7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
 	return encoder->get_hw_state(encoder, &pipe);
 }
 
-static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode)
+static bool intel_crtc_compute_config(struct drm_crtc *crtc,
+				      struct intel_crtc_config *pipe_config)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (HAS_PCH_SPLIT(dev)) {
 		/* FDI link clock is fixed at 2.7G */
-		if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
+		if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4)
 			return false;
 	}
 
@@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
 }
 
 static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
-			      struct drm_display_mode *mode,
-			      struct drm_display_mode *adjusted_mode,
 			      int x, int y,
 			      struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int refclk, num_connectors = 0;
@@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
 }
 
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
-				  struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode,
 				  int x, int y,
 				  struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int num_connectors = 0;
@@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
 }
 
 static int haswell_crtc_mode_set(struct drm_crtc *crtc,
-				 struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode,
 				 int x, int y,
 				 struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	int num_connectors = 0;
@@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
 }
 
 static int intel_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
 			       int x, int y,
 			       struct drm_framebuffer *fb)
 {
@@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct drm_display_mode *adjusted_mode =
+		&intel_crtc->config.adjusted_mode;
+	struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
 	int pipe = intel_crtc->pipe;
 	int ret;
 
@@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
 	drm_vblank_pre_modeset(dev, pipe);
 
-	ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
-					      x, y, fb);
+	ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
+
 	drm_vblank_post_modeset(dev, pipe);
 
 	if (ret != 0)
@@ -7478,19 +7482,22 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
 	}
 }
 
-static struct drm_display_mode *
-intel_modeset_adjusted_mode(struct drm_crtc *crtc,
-			    struct drm_display_mode *mode)
+static struct intel_crtc_config *
+intel_modeset_pipe_config(struct drm_crtc *crtc,
+			  struct drm_display_mode *mode)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_display_mode *adjusted_mode;
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct intel_encoder *encoder;
+	struct intel_crtc_config *pipe_config;
 
-	adjusted_mode = drm_mode_duplicate(dev, mode);
-	if (!adjusted_mode)
+	pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
+	if (!pipe_config)
 		return ERR_PTR(-ENOMEM);
 
+	drm_mode_copy(&pipe_config->adjusted_mode, mode);
+	drm_mode_copy(&pipe_config->requested_mode, mode);
+
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
@@ -7501,22 +7508,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc,
 		if (&encoder->new_crtc->base != crtc)
 			continue;
 		encoder_funcs = encoder->base.helper_private;
-		if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
-						adjusted_mode))) {
+		if (!(encoder_funcs->mode_fixup(&encoder->base,
+						&pipe_config->requested_mode,
+						&pipe_config->adjusted_mode))) {
 			DRM_DEBUG_KMS("Encoder fixup failed\n");
 			goto fail;
 		}
 	}
 
-	if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
+	if (!(intel_crtc_compute_config(crtc, pipe_config))) {
 		DRM_DEBUG_KMS("CRTC fixup failed\n");
 		goto fail;
 	}
 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
-	return adjusted_mode;
+	return pipe_config;
 fail:
-	drm_mode_destroy(dev, adjusted_mode);
+	kfree(pipe_config);
 	return ERR_PTR(-EINVAL);
 }
 
@@ -7782,7 +7790,8 @@ int intel_set_mode(struct drm_crtc *crtc,
 {
 	struct drm_device *dev = crtc->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode;
+	struct drm_display_mode *saved_mode, *saved_hwmode;
+	struct intel_crtc_config *pipe_config = NULL;
 	struct intel_crtc *intel_crtc;
 	unsigned disable_pipes, prepare_pipes, modeset_pipes;
 	int ret = 0;
@@ -7809,11 +7818,12 @@ int intel_set_mode(struct drm_crtc *crtc,
 	 * Hence simply check whether any bit is set in modeset_pipes in all the
 	 * pieces of code that are not yet converted to deal with mutliple crtcs
 	 * changing their mode at the same time. */
-	adjusted_mode = NULL;
 	if (modeset_pipes) {
-		adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
-		if (IS_ERR(adjusted_mode)) {
-			ret = PTR_ERR(adjusted_mode);
+		pipe_config = intel_modeset_pipe_config(crtc, mode);
+		if (IS_ERR(pipe_config)) {
+			ret = PTR_ERR(pipe_config);
+			pipe_config = NULL;
+
 			goto out;
 		}
 	}
@@ -7826,8 +7836,12 @@ int intel_set_mode(struct drm_crtc *crtc,
 	/* crtc->mode is already used by the ->mode_set callbacks, hence we need
 	 * to set it here already despite that we pass it down the callchain.
 	 */
-	if (modeset_pipes)
+	if (modeset_pipes) {
 		crtc->mode = *mode;
+		/* mode_set/enable/disable functions rely on a correct pipe
+		 * config. */
+		to_intel_crtc(crtc)->config = *pipe_config;
+	}
 
 	/* Only after disabling all output pipelines that will be changed can we
 	 * update the the output configuration. */
@@ -7841,7 +7855,6 @@ int intel_set_mode(struct drm_crtc *crtc,
 	 */
 	for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
 		ret = intel_crtc_mode_set(&intel_crtc->base,
-					  mode, adjusted_mode,
 					  x, y, fb);
 		if (ret)
 			goto done;
@@ -7853,7 +7866,7 @@ int intel_set_mode(struct drm_crtc *crtc,
 
 	if (modeset_pipes) {
 		/* Store real post-adjustment hardware mode. */
-		crtc->hwmode = *adjusted_mode;
+		crtc->hwmode = pipe_config->adjusted_mode;
 
 		/* Calculate and store various constants which
 		 * are later needed by vblank and swap-completion
@@ -7864,7 +7877,6 @@ int intel_set_mode(struct drm_crtc *crtc,
 
 	/* FIXME: add subpixel order */
 done:
-	drm_mode_destroy(dev, adjusted_mode);
 	if (ret && crtc->enabled) {
 		crtc->hwmode = *saved_hwmode;
 		crtc->mode = *saved_mode;
@@ -7873,6 +7885,7 @@ done:
 	}
 
 out:
+	kfree(pipe_config);
 	kfree(saved_mode);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e6f84d0..eca75b6 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -199,6 +199,11 @@ struct intel_connector {
 	struct edid *edid;
 };
 
+struct intel_crtc_config {
+	struct drm_display_mode requested_mode;
+	struct drm_display_mode adjusted_mode;
+};
+
 struct intel_crtc {
 	struct drm_crtc base;
 	enum pipe pipe;
@@ -232,6 +237,8 @@ struct intel_crtc {
 	bool cursor_visible;
 	unsigned int bpp;
 
+	struct intel_crtc_config config;
+
 	/* We can share PLLs across outputs if the timings match */
 	struct intel_pch_pll *pch_pll;
 	uint32_t ddi_pll_sel;
-- 
1.7.11.4

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

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

* Re: [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-02-21 23:56 ` [PATCH 03/10] drm/i915: add pipe_config->timings_set Daniel Vetter
@ 2013-02-22 13:51   ` Ville Syrjälä
  2013-03-03 18:01     ` Daniel Vetter
  2013-02-26 17:23   ` Paulo Zanoni
  1 sibling, 1 reply; 31+ messages in thread
From: Ville Syrjälä @ 2013-02-22 13:51 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

On Fri, Feb 22, 2013 at 12:56:47AM +0100, Daniel Vetter wrote:
> Only used by the lvds encoder. Note that we shouldn't do the same
> simple conversion with the FORCE_6BPC flag, since that's much better
> handled by moving all the pipe_bpc computation around.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
>  drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
>  3 files changed, 26 insertions(+), 15 deletions(-)
> 
<snip>
> @@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
>  		I915_WRITE(BCLRPAT(pipe), 0);
>  
>  	drm_mode_set_crtcinfo(adjusted_mode, 0);
> +	pipe_config->timings_set = true;

This changes the behaviour a bit. Previously the flag was only set from
the centering funcs, but now it's set always. Is that intentional?

>  
>  	switch (intel_connector->panel.fitting_mode) {
>  	case DRM_MODE_SCALE_CENTER:
> @@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
>  }
>  
>  static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
> -	.mode_fixup = intel_lvds_mode_fixup,
>  	.mode_set = intel_lvds_mode_set,
>  };
>  
> @@ -1102,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
>  	intel_encoder->enable = intel_enable_lvds;
>  	intel_encoder->pre_enable = intel_pre_enable_lvds;
>  	intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
> +	intel_encoder->compute_config = intel_lvds_compute_config;
>  	intel_encoder->disable = intel_disable_lvds;
>  	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
>  	intel_connector->get_hw_state = intel_connector_get_hw_state;
> -- 
> 1.7.11.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

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

* Re: [PATCH] drm/i915: introduce struct intel_crtc_config
  2013-02-22 11:05   ` [PATCH] " Daniel Vetter
@ 2013-02-26 17:09     ` Paulo Zanoni
  0 siblings, 0 replies; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:09 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

2013/2/22 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Currently only containing the requested and the adjusted mode. And
> only crtc callbacks are converted somewhat to it, encoders will be
> done on a as-needed basis (simply too much churn in one patch
> otherwise).
>
> Future patches will add tons more useful stuff to this struct,
> starting with the very simple.
>
> v2: Store the pipe_config in the intel_crtc, so that the ->mode-set,
> ->enable and also ->disable have easy access to it.
>
> v3: Store the pipe config in the right crtc ...
>
> v4: Rebased.
>
> v5: Fixup an OOPS when trying to kfree an ERR_PTR.
>
> v6: Used drm_moode_copy and some other small cleanups as suggested
> by Ville Syrjälä.
>
> v7: drm_mode_copy preserves the mode id of the destination, so no need
> to clear it again (Ville).
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |  4 +-
>  drivers/gpu/drm/i915/intel_display.c | 81 +++++++++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_drv.h     |  7 ++++
>  3 files changed, 56 insertions(+), 36 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e95337c..8fb14fb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -271,6 +271,8 @@ struct drm_i915_error_state {
>         struct intel_display_error_state *display;
>  };
>
> +struct intel_crtc_config;
> +
>  struct drm_i915_display_funcs {
>         bool (*fbc_enabled)(struct drm_device *dev);
>         void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
> @@ -284,8 +286,6 @@ struct drm_i915_display_funcs {
>                                  struct drm_display_mode *mode);
>         void (*modeset_global_resources)(struct drm_device *dev);
>         int (*crtc_mode_set)(struct drm_crtc *crtc,
> -                            struct drm_display_mode *mode,
> -                            struct drm_display_mode *adjusted_mode,
>                              int x, int y,
>                              struct drm_framebuffer *old_fb);
>         void (*crtc_enable)(struct drm_crtc *crtc);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index b521198..a02c6a7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3915,15 +3915,15 @@ bool intel_connector_get_hw_state(struct intel_connector *connector)
>         return encoder->get_hw_state(encoder, &pipe);
>  }
>
> -static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
> -                                 const struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode)
> +static bool intel_crtc_compute_config(struct drm_crtc *crtc,
> +                                     struct intel_crtc_config *pipe_config)
>  {
>         struct drm_device *dev = crtc->dev;
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>
>         if (HAS_PCH_SPLIT(dev)) {
>                 /* FDI link clock is fixed at 2.7G */
> -               if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4)
> +               if (pipe_config->requested_mode.clock * 3 > IRONLAKE_FDI_FREQ * 4)

Checkpatch.pl complains about this line (considering you've already
rejected some of my patches based on checkpatch.pl errors, I feel I
have to run checkpatch.pl on your patches too :D )

With that fixed:
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

>                         return false;
>         }
>
> @@ -4609,14 +4609,15 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc,
>  }
>
>  static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> -                             struct drm_display_mode *mode,
> -                             struct drm_display_mode *adjusted_mode,
>                               int x, int y,
>                               struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int refclk, num_connectors = 0;
> @@ -5579,14 +5580,15 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>  }
>
>  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> -                                 struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode,
>                                   int x, int y,
>                                   struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int num_connectors = 0;
> @@ -5745,14 +5747,15 @@ static void haswell_modeset_global_resources(struct drm_device *dev)
>  }
>
>  static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> -                                struct drm_display_mode *mode,
> -                                struct drm_display_mode *adjusted_mode,
>                                  int x, int y,
>                                  struct drm_framebuffer *fb)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         int num_connectors = 0;
> @@ -5829,8 +5832,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>  }
>
>  static int intel_crtc_mode_set(struct drm_crtc *crtc,
> -                              struct drm_display_mode *mode,
> -                              struct drm_display_mode *adjusted_mode,
>                                int x, int y,
>                                struct drm_framebuffer *fb)
>  {
> @@ -5839,6 +5840,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>         struct drm_encoder_helper_funcs *encoder_funcs;
>         struct intel_encoder *encoder;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         int ret;
>
> @@ -5849,8 +5853,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>
>         drm_vblank_pre_modeset(dev, pipe);
>
> -       ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
> -                                             x, y, fb);
> +       ret = dev_priv->display.crtc_mode_set(crtc, x, y, fb);
> +
>         drm_vblank_post_modeset(dev, pipe);
>
>         if (ret != 0)
> @@ -7478,19 +7482,22 @@ static void intel_modeset_commit_output_state(struct drm_device *dev)
>         }
>  }
>
> -static struct drm_display_mode *
> -intel_modeset_adjusted_mode(struct drm_crtc *crtc,
> -                           struct drm_display_mode *mode)
> +static struct intel_crtc_config *
> +intel_modeset_pipe_config(struct drm_crtc *crtc,
> +                         struct drm_display_mode *mode)
>  {
>         struct drm_device *dev = crtc->dev;
> -       struct drm_display_mode *adjusted_mode;
>         struct drm_encoder_helper_funcs *encoder_funcs;
>         struct intel_encoder *encoder;
> +       struct intel_crtc_config *pipe_config;
>
> -       adjusted_mode = drm_mode_duplicate(dev, mode);
> -       if (!adjusted_mode)
> +       pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
> +       if (!pipe_config)
>                 return ERR_PTR(-ENOMEM);
>
> +       drm_mode_copy(&pipe_config->adjusted_mode, mode);
> +       drm_mode_copy(&pipe_config->requested_mode, mode);
> +
>         /* Pass our mode to the connectors and the CRTC to give them a chance to
>          * adjust it according to limitations or connector properties, and also
>          * a chance to reject the mode entirely.
> @@ -7501,22 +7508,23 @@ intel_modeset_adjusted_mode(struct drm_crtc *crtc,
>                 if (&encoder->new_crtc->base != crtc)
>                         continue;
>                 encoder_funcs = encoder->base.helper_private;
> -               if (!(encoder_funcs->mode_fixup(&encoder->base, mode,
> -                                               adjusted_mode))) {
> +               if (!(encoder_funcs->mode_fixup(&encoder->base,
> +                                               &pipe_config->requested_mode,
> +                                               &pipe_config->adjusted_mode))) {
>                         DRM_DEBUG_KMS("Encoder fixup failed\n");
>                         goto fail;
>                 }
>         }
>
> -       if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) {
> +       if (!(intel_crtc_compute_config(crtc, pipe_config))) {
>                 DRM_DEBUG_KMS("CRTC fixup failed\n");
>                 goto fail;
>         }
>         DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
>
> -       return adjusted_mode;
> +       return pipe_config;
>  fail:
> -       drm_mode_destroy(dev, adjusted_mode);
> +       kfree(pipe_config);
>         return ERR_PTR(-EINVAL);
>  }
>
> @@ -7782,7 +7790,8 @@ int intel_set_mode(struct drm_crtc *crtc,
>  {
>         struct drm_device *dev = crtc->dev;
>         drm_i915_private_t *dev_priv = dev->dev_private;
> -       struct drm_display_mode *adjusted_mode, *saved_mode, *saved_hwmode;
> +       struct drm_display_mode *saved_mode, *saved_hwmode;
> +       struct intel_crtc_config *pipe_config = NULL;
>         struct intel_crtc *intel_crtc;
>         unsigned disable_pipes, prepare_pipes, modeset_pipes;
>         int ret = 0;
> @@ -7809,11 +7818,12 @@ int intel_set_mode(struct drm_crtc *crtc,
>          * Hence simply check whether any bit is set in modeset_pipes in all the
>          * pieces of code that are not yet converted to deal with mutliple crtcs
>          * changing their mode at the same time. */
> -       adjusted_mode = NULL;
>         if (modeset_pipes) {
> -               adjusted_mode = intel_modeset_adjusted_mode(crtc, mode);
> -               if (IS_ERR(adjusted_mode)) {
> -                       ret = PTR_ERR(adjusted_mode);
> +               pipe_config = intel_modeset_pipe_config(crtc, mode);
> +               if (IS_ERR(pipe_config)) {
> +                       ret = PTR_ERR(pipe_config);
> +                       pipe_config = NULL;
> +
>                         goto out;
>                 }
>         }
> @@ -7826,8 +7836,12 @@ int intel_set_mode(struct drm_crtc *crtc,
>         /* crtc->mode is already used by the ->mode_set callbacks, hence we need
>          * to set it here already despite that we pass it down the callchain.
>          */
> -       if (modeset_pipes)
> +       if (modeset_pipes) {
>                 crtc->mode = *mode;
> +               /* mode_set/enable/disable functions rely on a correct pipe
> +                * config. */
> +               to_intel_crtc(crtc)->config = *pipe_config;
> +       }
>
>         /* Only after disabling all output pipelines that will be changed can we
>          * update the the output configuration. */
> @@ -7841,7 +7855,6 @@ int intel_set_mode(struct drm_crtc *crtc,
>          */
>         for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) {
>                 ret = intel_crtc_mode_set(&intel_crtc->base,
> -                                         mode, adjusted_mode,
>                                           x, y, fb);
>                 if (ret)
>                         goto done;
> @@ -7853,7 +7866,7 @@ int intel_set_mode(struct drm_crtc *crtc,
>
>         if (modeset_pipes) {
>                 /* Store real post-adjustment hardware mode. */
> -               crtc->hwmode = *adjusted_mode;
> +               crtc->hwmode = pipe_config->adjusted_mode;
>
>                 /* Calculate and store various constants which
>                  * are later needed by vblank and swap-completion
> @@ -7864,7 +7877,6 @@ int intel_set_mode(struct drm_crtc *crtc,
>
>         /* FIXME: add subpixel order */
>  done:
> -       drm_mode_destroy(dev, adjusted_mode);
>         if (ret && crtc->enabled) {
>                 crtc->hwmode = *saved_hwmode;
>                 crtc->mode = *saved_mode;
> @@ -7873,6 +7885,7 @@ done:
>         }
>
>  out:
> +       kfree(pipe_config);
>         kfree(saved_mode);
>         return ret;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index e6f84d0..eca75b6 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -199,6 +199,11 @@ struct intel_connector {
>         struct edid *edid;
>  };
>
> +struct intel_crtc_config {
> +       struct drm_display_mode requested_mode;
> +       struct drm_display_mode adjusted_mode;
> +};
> +
>  struct intel_crtc {
>         struct drm_crtc base;
>         enum pipe pipe;
> @@ -232,6 +237,8 @@ struct intel_crtc {
>         bool cursor_visible;
>         unsigned int bpp;
>
> +       struct intel_crtc_config config;
> +
>         /* We can share PLLs across outputs if the timings match */
>         struct intel_pch_pll *pch_pll;
>         uint32_t ddi_pll_sel;
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 02/10] drm/i915: compute pipe_config earlier
  2013-02-21 23:56 ` [PATCH 02/10] drm/i915: compute pipe_config earlier Daniel Vetter
@ 2013-02-26 17:11   ` Paulo Zanoni
  0 siblings, 0 replies; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:11 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> To make decent modeset state checking possible (e.g. for the check
> mode with atomic modesetting) we want to have the full pipe
> configuration and state checks done before we touch the hw.
>
> To ensure that all the little bits&pieces that are now moved to the
> pipe_config handle this correctly, move its computation to the right
> spot now, before we touch the hw in the disable_pipes step.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 5a3e231..0f61008 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7806,12 +7806,6 @@ int intel_set_mode(struct drm_crtc *crtc,
>         intel_modeset_affected_pipes(crtc, &modeset_pipes,
>                                      &prepare_pipes, &disable_pipes);
>
> -       DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
> -                     modeset_pipes, prepare_pipes, disable_pipes);
> -
> -       for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
> -               intel_crtc_disable(&intel_crtc->base);
> -
>         *saved_hwmode = crtc->hwmode;
>         *saved_mode = crtc->mode;
>
> @@ -7830,6 +7824,12 @@ int intel_set_mode(struct drm_crtc *crtc,
>                 }
>         }
>
> +       DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n",
> +                     modeset_pipes, prepare_pipes, disable_pipes);
> +
> +       for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc)
> +               intel_crtc_disable(&intel_crtc->base);
> +
>         for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) {
>                 if (intel_crtc->base.enabled)
>                         dev_priv->display.crtc_disable(&intel_crtc->base);
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-02-21 23:56 ` [PATCH 03/10] drm/i915: add pipe_config->timings_set Daniel Vetter
  2013-02-22 13:51   ` Ville Syrjälä
@ 2013-02-26 17:23   ` Paulo Zanoni
  2013-03-03 17:58     ` Daniel Vetter
  1 sibling, 1 reply; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Only used by the lvds encoder. Note that we shouldn't do the same
> simple conversion with the FORCE_6BPC flag, since that's much better
> handled by moving all the pipe_bpc computation around.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

In addition to Ville's question (which makes sense):

This patch does 2 things: it adds pipe_config->timings_set, but it
also adds the encoder->compute_config function. Even though I can see
intel_encoder->compute_config is just like drm_encoder->mode_fixup but
with different arguments, I don't think this is a trivial thing to
notice (imagine a future code reader, not someone looking at this
specific patch). It would be really nice if you could add the
compute_config callback on a separate patch and give a detailed
documentation of the expected behavior of the function for our future
readers. Bonus points if you could also add documentation for all the
other intel_encoder callbacks you've created and document their
relationship with the drm callbacks.

Also, if we agree to create a separate patch for the compute_config
callbacks, why don't we just convert all encoders to use
compute_config instead of mode_fixup in the very first patch? Looks
simpler to me.

Also, I notice that this patch series doesn't apply to
drm-intel-next-queued, only to drm-intel-nightly. I'm not sure what's
your plan regarding this, just noticing :)

> ---
>  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
>  drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
>  drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
>  3 files changed, 26 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0f61008..ad03b7f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3930,7 +3930,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
>         /* All interlaced capable intel hw wants timings in frames. Note though
>          * that intel_lvds_mode_fixup does some funny tricks with the crtc
>          * timings, so we need to be careful not to clobber these.*/
> -       if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
> +       if (!pipe_config->timings_set)
>                 drm_mode_set_crtcinfo(adjusted_mode, 0);
>
>         /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
> @@ -7509,6 +7509,16 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
>
>                 if (&encoder->new_crtc->base != crtc)
>                         continue;
> +
> +               if (encoder->compute_config) {
> +                       if (!(encoder->compute_config(encoder, pipe_config))) {
> +                               DRM_DEBUG_KMS("Encoder config failure\n");
> +                               goto fail;
> +                       }
> +
> +                       continue;
> +               }
> +
>                 encoder_funcs = encoder->base.helper_private;
>                 if (!(encoder_funcs->mode_fixup(&encoder->base,
>                                                 &pipe_config->requested_mode,
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index eca75b6..edafbef 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -105,10 +105,6 @@
>  #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
>  #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
>  #define INTEL_MODE_DP_FORCE_6BPC (0x10)
> -/* This flag must be set by the encoder's mode_fixup if it changes the crtc
> - * timings in the mode to prevent the crtc fixup from overwriting them.
> - * Currently only lvds needs that. */
> -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
>  /*
>   * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
>   * to be used.
> @@ -158,6 +154,8 @@ struct intel_encoder {
>         bool cloneable;
>         bool connectors_active;
>         void (*hot_plug)(struct intel_encoder *);
> +       bool (*compute_config)(struct intel_encoder *,
> +                              struct intel_crtc_config *);
>         void (*pre_pll_enable)(struct intel_encoder *);
>         void (*pre_enable)(struct intel_encoder *);
>         void (*enable)(struct intel_encoder *);
> @@ -202,6 +200,10 @@ struct intel_connector {
>  struct intel_crtc_config {
>         struct drm_display_mode requested_mode;
>         struct drm_display_mode adjusted_mode;
> +       /* This flag must be set by the encoder's compute_config callback if it
> +        * changes the crtc timings in the mode to prevent the crtc fixup from
> +        * overwriting them.  Currently only lvds needs that. */
> +       bool timings_set;
>  };
>
>  struct intel_crtc {
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 3d1d974..1616f53 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -261,8 +261,6 @@ centre_horizontally(struct drm_display_mode *mode,
>
>         mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
>         mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
> -
> -       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
>  }
>
>  static void
> @@ -284,8 +282,6 @@ centre_vertically(struct drm_display_mode *mode,
>
>         mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
>         mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
> -
> -       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
>  }
>
>  static inline u32 panel_fitter_scaling(u32 source, u32 target)
> @@ -301,15 +297,17 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
>         return (FACTOR * ratio + FACTOR/2) / FACTOR;
>  }
>
> -static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> -                                 const struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode)
> +static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
> +                                     struct intel_crtc_config *pipe_config)
>  {
> -       struct drm_device *dev = encoder->dev;
> +       struct drm_device *dev = intel_encoder->base.dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
> +       struct intel_lvds_encoder *lvds_encoder =
> +               to_lvds_encoder(&intel_encoder->base);
>         struct intel_connector *intel_connector =
>                 &lvds_encoder->attached_connector->base;
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> +       struct drm_display_mode *mode = &pipe_config->requested_mode;
>         struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
>         u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
>         int pipe;
> @@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
>                 I915_WRITE(BCLRPAT(pipe), 0);
>
>         drm_mode_set_crtcinfo(adjusted_mode, 0);
> +       pipe_config->timings_set = true;
>
>         switch (intel_connector->panel.fitting_mode) {
>         case DRM_MODE_SCALE_CENTER:
> @@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
>  }
>
>  static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
> -       .mode_fixup = intel_lvds_mode_fixup,
>         .mode_set = intel_lvds_mode_set,
>  };
>
> @@ -1102,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
>         intel_encoder->enable = intel_enable_lvds;
>         intel_encoder->pre_enable = intel_pre_enable_lvds;
>         intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
> +       intel_encoder->compute_config = intel_lvds_compute_config;
>         intel_encoder->disable = intel_disable_lvds;
>         intel_encoder->get_hw_state = intel_lvds_get_hw_state;
>         intel_connector->get_hw_state = intel_connector_get_hw_state;
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier
  2013-02-21 23:56 ` [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier Daniel Vetter
@ 2013-02-26 17:27   ` Paulo Zanoni
  2013-03-03 18:05     ` Daniel Vetter
  0 siblings, 1 reply; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:27 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Used by SDVO (and hopefully, eventually HDMI, if we ever get around
> to fixing up the low dotclock CEA modes ...).
>
> This required adding a new encoder->mode_set callback to be able to
> pass around the intel_crtc_config.

Again, can we please separate the callback in another patch and add
some nice documentation explaining what's this callback, why it's
called and what's its relationship with the other mode_set callbacks
(again, think about future code readers, not people reading the
patch)? Also, why not just convert every encoder to this callback
right now?

The pixel_multiplier part of the patch looks correct.

>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 80 +++++++++++++++++++-----------------
>  drivers/gpu/drm/i915/intel_drv.h     | 19 ++-------
>  drivers/gpu/drm/i915/intel_sdvo.c    | 39 +++++++++---------
>  3 files changed, 66 insertions(+), 72 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ad03b7f..3446e2b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4280,14 +4280,15 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
>  }
>
>  static void vlv_update_pll(struct drm_crtc *crtc,
> -                          struct drm_display_mode *mode,
> -                          struct drm_display_mode *adjusted_mode,
>                            intel_clock_t *clock, intel_clock_t *reduced_clock,
>                            int num_connectors)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         int pipe = intel_crtc->pipe;
>         u32 dpll, mdiv, pdiv;
>         u32 bestn, bestm1, bestm2, bestp1, bestp2;
> @@ -4354,11 +4355,11 @@ static void vlv_update_pll(struct drm_crtc *crtc,
>
>         temp = 0;
>         if (is_sdvo) {
> -               temp = intel_mode_get_pixel_multiplier(adjusted_mode);
> -               if (temp > 1)
> -                       temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> -               else
> -                       temp = 0;
> +               temp = 0;
> +               if (intel_crtc->config.pixel_multiplier > 1) {
> +                       temp = (intel_crtc->config.pixel_multiplier - 1)
> +                               << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> +               }
>         }
>         I915_WRITE(DPLL_MD(pipe), temp);
>         POSTING_READ(DPLL_MD(pipe));
> @@ -4384,14 +4385,15 @@ static void vlv_update_pll(struct drm_crtc *crtc,
>  }
>
>  static void i9xx_update_pll(struct drm_crtc *crtc,
> -                           struct drm_display_mode *mode,
> -                           struct drm_display_mode *adjusted_mode,
>                             intel_clock_t *clock, intel_clock_t *reduced_clock,
>                             int num_connectors)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         struct intel_encoder *encoder;
>         int pipe = intel_crtc->pipe;
>         u32 dpll;
> @@ -4408,11 +4410,12 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
>                 dpll |= DPLLB_MODE_LVDS;
>         else
>                 dpll |= DPLLB_MODE_DAC_SERIAL;
> +
>         if (is_sdvo) {
> -               int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> -               if (pixel_multiplier > 1) {
> -                       if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
> -                               dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
> +               if ((intel_crtc->config.pixel_multiplier > 1) &&
> +                   (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) {
> +                       dpll |= (intel_crtc->config.pixel_multiplier - 1)
> +                               << SDVO_MULTIPLIER_SHIFT_HIRES;
>                 }
>                 dpll |= DPLL_DVO_HIGH_SPEED;
>         }
> @@ -4477,11 +4480,11 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
>         if (INTEL_INFO(dev)->gen >= 4) {
>                 u32 temp = 0;
>                 if (is_sdvo) {
> -                       temp = intel_mode_get_pixel_multiplier(adjusted_mode);
> -                       if (temp > 1)
> -                               temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> -                       else
> -                               temp = 0;
> +                       temp = 0;
> +                       if (intel_crtc->config.pixel_multiplier > 1) {
> +                               temp = (intel_crtc->config.pixel_multiplier - 1)
> +                                       << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> +                       }
>                 }
>                 I915_WRITE(DPLL_MD(pipe), temp);
>         } else {
> @@ -4691,11 +4694,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
>                                 has_reduced_clock ? &reduced_clock : NULL,
>                                 num_connectors);
>         else if (IS_VALLEYVIEW(dev))
> -               vlv_update_pll(crtc, mode, adjusted_mode, &clock,
> +               vlv_update_pll(crtc, &clock,
>                                 has_reduced_clock ? &reduced_clock : NULL,
>                                 num_connectors);
>         else
> -               i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
> +               i9xx_update_pll(crtc, &clock,
>                                 has_reduced_clock ? &reduced_clock : NULL,
>                                 num_connectors);
>
> @@ -5407,17 +5410,18 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
>         return bps / (link_bw * 8) + 1;
>  }
>
> -static void ironlake_set_m_n(struct drm_crtc *crtc,
> -                            struct drm_display_mode *mode,
> -                            struct drm_display_mode *adjusted_mode)
> +static void ironlake_set_m_n(struct drm_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
>         enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
>         struct intel_encoder *intel_encoder, *edp_encoder = NULL;
>         struct intel_link_m_n m_n = {0};
> -       int target_clock, pixel_multiplier, lane, link_bw;
> +       int target_clock, lane, link_bw;
>         bool is_dp = false, is_cpu_edp = false;
>
>         for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> @@ -5435,7 +5439,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
>         }
>
>         /* FDI link */
> -       pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
>         lane = 0;
>         /* CPU eDP doesn't require FDI link, so just set DP M/N
>            according to current link config */
> @@ -5466,8 +5469,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
>
>         intel_crtc->fdi_lanes = lane;
>
> -       if (pixel_multiplier > 1)
> -               link_bw *= pixel_multiplier;
> +       if (intel_crtc->config.pixel_multiplier > 1)
> +               link_bw *= intel_crtc->config.pixel_multiplier;
>         intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
>
>         I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
> @@ -5477,7 +5480,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
>  }
>
>  static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
> -                                     struct drm_display_mode *adjusted_mode,
>                                       intel_clock_t *clock, u32 fp)
>  {
>         struct drm_crtc *crtc = &intel_crtc->base;
> @@ -5485,7 +5487,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_encoder *intel_encoder;
>         uint32_t dpll;
> -       int factor, pixel_multiplier, num_connectors = 0;
> +       int factor, num_connectors = 0;
>         bool is_lvds = false, is_sdvo = false, is_tv = false;
>         bool is_dp = false, is_cpu_edp = false;
>
> @@ -5536,9 +5538,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
>         else
>                 dpll |= DPLLB_MODE_DAC_SERIAL;
>         if (is_sdvo) {
> -               pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> -               if (pixel_multiplier > 1) {
> -                       dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> +               if (intel_crtc->config.pixel_multiplier > 1) {
> +                       dpll |= (intel_crtc->config.pixel_multiplier - 1)
> +                               << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
>                 }
>                 dpll |= DPLL_DVO_HIGH_SPEED;
>         }
> @@ -5642,7 +5644,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>                 fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
>                         reduced_clock.m2;
>
> -       dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp);
> +       dpll = ironlake_compute_dpll(intel_crtc, &clock, fp);
>
>         DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
>         drm_mode_debug_printmodeline(mode);
> @@ -5696,7 +5698,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>
>         /* Note, this also computes intel_crtc->fdi_lanes which is used below in
>          * ironlake_check_fdi_lanes. */
> -       ironlake_set_m_n(crtc, mode, adjusted_mode);
> +       ironlake_set_m_n(crtc);
>
>         fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
>
> @@ -5812,7 +5814,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>         intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>
>         if (!is_dp || is_cpu_edp)
> -               ironlake_set_m_n(crtc, mode, adjusted_mode);
> +               ironlake_set_m_n(crtc);
>
>         haswell_set_pipeconf(crtc, adjusted_mode, dither);
>
> @@ -5865,8 +5867,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
>                         encoder->base.base.id,
>                         drm_get_encoder_name(&encoder->base),
>                         mode->base.id, mode->name);
> -               encoder_funcs = encoder->base.helper_private;
> -               encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
> +               if (encoder->mode_set) {
> +                       encoder->mode_set(encoder);
> +               } else {
> +                       encoder_funcs = encoder->base.helper_private;
> +                       encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
> +               }
>         }
>
>         return 0;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index edafbef..ef5111b 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -102,8 +102,6 @@
>  #define INTEL_DVO_CHIP_TVOUT 4
>
>  /* drm_display_mode->private_flags */
> -#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
> -#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
>  #define INTEL_MODE_DP_FORCE_6BPC (0x10)
>  /*
>   * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
> @@ -111,20 +109,6 @@
>   */
>  #define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
>
> -static inline void
> -intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
> -                               int multiplier)
> -{
> -       mode->clock *= multiplier;
> -       mode->private_flags |= multiplier;
> -}
> -
> -static inline int
> -intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode)
> -{
> -       return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT;
> -}
> -
>  struct intel_framebuffer {
>         struct drm_framebuffer base;
>         struct drm_i915_gem_object *obj;
> @@ -159,6 +143,7 @@ struct intel_encoder {
>         void (*pre_pll_enable)(struct intel_encoder *);
>         void (*pre_enable)(struct intel_encoder *);
>         void (*enable)(struct intel_encoder *);
> +       void (*mode_set)(struct intel_encoder *intel_encoder);
>         void (*disable)(struct intel_encoder *);
>         void (*post_disable)(struct intel_encoder *);
>         /* Read out the current hw state of this connector, returning true if
> @@ -204,6 +189,8 @@ struct intel_crtc_config {
>          * changes the crtc timings in the mode to prevent the crtc fixup from
>          * overwriting them.  Currently only lvds needs that. */
>         bool timings_set;
> +       /* Used by SDVO (and if we ever fix it, HDMI). */
> +       unsigned pixel_multiplier;
>  };
>
>  struct intel_crtc {
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 33b46d9..06bb2e1 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -788,7 +788,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
>         v_sync_offset = mode->vsync_start - mode->vdisplay;
>
>         mode_clock = mode->clock;
> -       mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1;
>         mode_clock /= 10;
>         dtd->part1.clock = mode_clock;
>
> @@ -1039,12 +1038,12 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>         return true;
>  }
>
> -static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> -                                 const struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode)
> +static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
> +                                     struct intel_crtc_config *pipe_config)
>  {
> -       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
> -       int multiplier;
> +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> +       struct drm_display_mode *mode = &pipe_config->requested_mode;
>
>         /* We need to construct preferred input timings based on our
>          * output timings.  To do that, we have to set the output
> @@ -1071,8 +1070,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
>         /* Make the CRTC code factor in the SDVO pixel multiplier.  The
>          * SDVO device will factor out the multiplier during mode_set.
>          */
> -       multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
> -       intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
> +       pipe_config->pixel_multiplier =
> +               intel_sdvo_get_pixel_multiplier(adjusted_mode);
> +       adjusted_mode->clock *= pipe_config->pixel_multiplier;
>
>         if (intel_sdvo->color_range_auto) {
>                 /* See CEA-861-E - 5.1 Default Encoding Parameters */
> @@ -1089,19 +1089,19 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
>         return true;
>  }
>
> -static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> -                               struct drm_display_mode *mode,
> -                               struct drm_display_mode *adjusted_mode)
> +static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder)
>  {
> -       struct drm_device *dev = encoder->dev;
> +       struct drm_device *dev = intel_encoder->base.dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> -       struct drm_crtc *crtc = encoder->crtc;
> +       struct drm_crtc *crtc = intel_encoder->base.crtc;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
> +       struct drm_display_mode *adjusted_mode =
> +               &intel_crtc->config.adjusted_mode;
> +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
> +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base);
>         u32 sdvox;
>         struct intel_sdvo_in_out_map in_out;
>         struct intel_sdvo_dtd input_dtd, output_dtd;
> -       int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
>         int rate;
>
>         if (!mode)
> @@ -1161,7 +1161,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
>                 DRM_INFO("Setting input timings on %s failed\n",
>                          SDVO_NAME(intel_sdvo));
>
> -       switch (pixel_multiplier) {
> +       switch (intel_crtc->config.pixel_multiplier) {
>         default:
>         case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
>         case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
> @@ -1205,7 +1205,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
>         } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
>                 /* done in crtc_mode_set as it lives inside the dpll register */
>         } else {
> -               sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT;
> +               sdvox |= (intel_crtc->config.pixel_multiplier - 1)
> +                       << SDVO_PORT_MULTIPLY_SHIFT;
>         }
>
>         if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL &&
> @@ -2041,8 +2042,6 @@ done:
>  }
>
>  static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
> -       .mode_fixup = intel_sdvo_mode_fixup,
> -       .mode_set = intel_sdvo_mode_set,
>  };
>
>  static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
> @@ -2781,7 +2780,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
>
>         drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
>
> +       intel_encoder->compute_config = intel_sdvo_compute_config;
>         intel_encoder->disable = intel_disable_sdvo;
> +       intel_encoder->mode_set = intel_sdvo_mode_set;
>         intel_encoder->enable = intel_enable_sdvo;
>         intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
>
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder
  2013-02-21 23:56 ` [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder Daniel Vetter
@ 2013-02-26 17:39   ` Paulo Zanoni
  2013-03-03 18:13     ` Daniel Vetter
  0 siblings, 1 reply; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:39 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

A few chunks down below:

2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> This is used way too often in the enable/disable paths. And will
> be even more useful in the future.
>
> Note that correct semantics of this change highly depend upon
> correct updating of intel_crtc->config: Like with all other
> modeset state, we need to call ->disable with the old config,
> but ->mode_set and ->enable with the new config.
>
> v2: Do not yet use the flag in the ->disable callbacks - atm we don't
> yet have support for the information stored in the pipe_config in the
> hw state readout code, so this will be wrong at boot-up/resume.
>
> v3: Rebased on top of the hdmi/dp ddi encoder merging.
>
> v4: Fixup stupid rebase error which lead to a NULL vfunc deref.
>
> v5: On haswell the VGA port is on the PCH!
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_crt.c     | 12 +++++++----
>  drivers/gpu/drm/i915/intel_ddi.c     | 16 +++++++--------
>  drivers/gpu/drm/i915/intel_display.c | 40 ++++++++----------------------------
>  drivers/gpu/drm/i915/intel_dp.c      | 16 +++++++++------
>  drivers/gpu/drm/i915/intel_drv.h     | 13 ++++++------
>  drivers/gpu/drm/i915/intel_hdmi.c    | 14 ++++++++-----
>  drivers/gpu/drm/i915/intel_lvds.c    |  2 ++
>  drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
>  8 files changed, 54 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 969d08c..1bd09a7 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -206,10 +206,14 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
>         return MODE_OK;
>  }
>
> -static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
> -                                const struct drm_display_mode *mode,
> -                                struct drm_display_mode *adjusted_mode)
> +static bool intel_crt_compute_config(struct intel_encoder *encoder,
> +                                    struct intel_crtc_config *pipe_config)
>  {
> +       struct drm_device *dev = encoder->base.dev;
> +
> +       if (HAS_PCH_SPLIT(dev))
> +               pipe_config->has_pch_encoder = true;
> +
>         return true;
>  }
>
> @@ -683,7 +687,6 @@ static void intel_crt_reset(struct drm_connector *connector)
>   */
>
>  static const struct drm_encoder_helper_funcs crt_encoder_funcs = {
> -       .mode_fixup = intel_crt_mode_fixup,
>         .mode_set = intel_crt_mode_set,
>  };
>
> @@ -774,6 +777,7 @@ void intel_crt_init(struct drm_device *dev)
>         else
>                 crt->adpa_reg = ADPA;
>
> +       crt->base.compute_config = intel_crt_compute_config;
>         crt->base.disable = intel_disable_crt;
>         crt->base.enable = intel_enable_crt;
>         if (HAS_DDI(dev))
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index fc95ef0..f5ae79f 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1467,19 +1467,17 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
>         intel_dp_encoder_destroy(encoder);
>  }
>
> -static bool intel_ddi_mode_fixup(struct drm_encoder *encoder,
> -                                const struct drm_display_mode *mode,
> -                                struct drm_display_mode *adjusted_mode)
> +static bool intel_ddi_compute_config(struct intel_encoder *encoder,
> +                                    struct intel_crtc_config *pipe_config)
>  {
> -       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> -       int type = intel_encoder->type;
> +       int type = encoder->type;
>
> -       WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n");
> +       WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
>
>         if (type == INTEL_OUTPUT_HDMI)
> -               return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode);
> +               return intel_hdmi_compute_config(encoder, pipe_config);
>         else
> -               return intel_dp_mode_fixup(encoder, mode, adjusted_mode);
> +               return intel_dp_compute_config(encoder, pipe_config);
>  }
>
>  static const struct drm_encoder_funcs intel_ddi_funcs = {
> @@ -1487,7 +1485,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
>  };
>
>  static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
> -       .mode_fixup = intel_ddi_mode_fixup,
>         .mode_set = intel_ddi_mode_set,
>  };
>
> @@ -1527,6 +1524,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>                          DRM_MODE_ENCODER_TMDS);
>         drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs);
>
> +       intel_encoder->compute_config = intel_ddi_compute_config;
>         intel_encoder->enable = intel_enable_ddi;
>         intel_encoder->pre_enable = intel_ddi_pre_enable;
>         intel_encoder->disable = intel_disable_ddi;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 3446e2b..c5f7c6e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2947,27 +2947,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
>         mutex_unlock(&dev->struct_mutex);
>  }
>
> -static bool ironlake_crtc_driving_pch(struct drm_crtc *crtc)
> -{
> -       struct drm_device *dev = crtc->dev;
> -       struct intel_encoder *intel_encoder;
> -
> -       /*
> -        * If there's a non-PCH eDP on this crtc, it must be DP_A, and that
> -        * must be driven by its own crtc; no sharing is possible.
> -        */
> -       for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> -               switch (intel_encoder->type) {
> -               case INTEL_OUTPUT_EDP:
> -                       if (!intel_encoder_is_pch_edp(&intel_encoder->base))
> -                               return false;
> -                       continue;
> -               }
> -       }
> -
> -       return true;
> -}
> -
>  static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)

You forgot to kill haswell_crtc_driving_pch and replace its usage
inside haswell_crtc_disable.


>  {
>         return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
> @@ -3308,7 +3287,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
>         u32 temp;
> -       bool is_pch_port;
>
>         WARN_ON(!crtc->enabled);
>
> @@ -3324,9 +3302,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>                         I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
>         }
>
> -       is_pch_port = ironlake_crtc_driving_pch(crtc);
>
> -       if (is_pch_port) {
> +       if (intel_crtc->config.has_pch_encoder) {
>                 /* Note: FDI PLL enabling _must_ be done before we enable the
>                  * cpu pipes, hence this is separate from all the other fdi/pch
>                  * enabling. */
> @@ -3363,10 +3340,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
>          */
>         intel_crtc_load_lut(crtc);
>
> -       intel_enable_pipe(dev_priv, pipe, is_pch_port);
> +       intel_enable_pipe(dev_priv, pipe,
> +                         intel_crtc->config.has_pch_encoder);
>         intel_enable_plane(dev_priv, plane, pipe);
>
> -       if (is_pch_port)
> +       if (intel_crtc->config.has_pch_encoder)
>                 ironlake_pch_enable(crtc);
>
>         mutex_lock(&dev->struct_mutex);
> @@ -3400,7 +3378,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         struct intel_encoder *encoder;
>         int pipe = intel_crtc->pipe;
>         int plane = intel_crtc->plane;
> -       bool is_pch_port;
>
>         WARN_ON(!crtc->enabled);
>
> @@ -3410,9 +3387,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         intel_crtc->active = true;
>         intel_update_watermarks(dev);
>
> -       is_pch_port = haswell_crtc_driving_pch(crtc);
> -
> -       if (is_pch_port)
> +       if (intel_crtc->config.has_pch_encoder)
>                 dev_priv->display.fdi_link_train(crtc);
>
>         for_each_encoder_on_crtc(dev, crtc, encoder)
> @@ -3443,10 +3418,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
>         intel_ddi_set_pipe_settings(crtc);
>         intel_ddi_enable_pipe_func(crtc);
>
> -       intel_enable_pipe(dev_priv, pipe, is_pch_port);
> +       intel_enable_pipe(dev_priv, pipe,
> +                         intel_crtc->config.has_pch_encoder);
>         intel_enable_plane(dev_priv, plane, pipe);
>
> -       if (is_pch_port)
> +       if (intel_crtc->config.has_pch_encoder)
>                 lpt_pch_enable(crtc);
>
>         mutex_lock(&dev->struct_mutex);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 9b1a969..e851fdd 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -689,12 +689,13 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
>  }
>
>  bool
> -intel_dp_mode_fixup(struct drm_encoder *encoder,
> -                   const struct drm_display_mode *mode,
> -                   struct drm_display_mode *adjusted_mode)
> +intel_dp_compute_config(struct intel_encoder *encoder,
> +                       struct intel_crtc_config *pipe_config)
>  {
> -       struct drm_device *dev = encoder->dev;
> -       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +       struct drm_device *dev = encoder->base.dev;
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> +       struct drm_display_mode *mode = &pipe_config->requested_mode;
> +       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>         struct intel_connector *intel_connector = intel_dp->attached_connector;
>         int lane_count, clock;
>         int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
> @@ -702,6 +703,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
>         int bpp, mode_rate;
>         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
>
> +       if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))

s/IS_HASWELL/HAS_DDI/ ?


> +               pipe_config->has_pch_encoder = true;
> +
>         if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
>                 intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
>                                        adjusted_mode);
> @@ -2517,7 +2521,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
>  }
>
>  static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
> -       .mode_fixup = intel_dp_mode_fixup,
>         .mode_set = intel_dp_mode_set,
>  };
>
> @@ -2937,6 +2940,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
>                          DRM_MODE_ENCODER_TMDS);
>         drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
>
> +       intel_encoder->compute_config = intel_dp_compute_config;
>         intel_encoder->enable = intel_enable_dp;
>         intel_encoder->pre_enable = intel_pre_enable_dp;
>         intel_encoder->disable = intel_disable_dp;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index ef5111b..458e6bd 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -189,6 +189,9 @@ struct intel_crtc_config {
>          * changes the crtc timings in the mode to prevent the crtc fixup from
>          * overwriting them.  Currently only lvds needs that. */
>         bool timings_set;
> +       /* Whether to set up the PCH/FDI. Note that we never allow sharing
> +        * between pch encoders and cpu encoders. */
> +       bool has_pch_encoder;
>         /* Used by SDVO (and if we ever fix it, HDMI). */
>         unsigned pixel_multiplier;
>  };
> @@ -444,9 +447,8 @@ extern void intel_hdmi_init(struct drm_device *dev,
>  extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
>                                       struct intel_connector *intel_connector);
>  extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
> -extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> -                                 const struct drm_display_mode *mode,
> -                                 struct drm_display_mode *adjusted_mode);
> +extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> +                                     struct intel_crtc_config *);

To keep the coding style consistent, "struct intel_crtc_config *pipe_config);" ?


>  extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
>  extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
>                             bool is_sdvob);
> @@ -470,9 +472,8 @@ extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
>  extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
>  extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
>  extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
> -extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
> -                               const struct drm_display_mode *mode,
> -                               struct drm_display_mode *adjusted_mode);
> +extern bool intel_dp_compute_config(struct intel_encoder *encoder,
> +                                   struct intel_crtc_config *pipe_config);
>  extern bool intel_dpd_is_edp(struct drm_device *dev);
>  extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
>  extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 92aba3c..cfc9d751 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -772,11 +772,12 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
>         return MODE_OK;
>  }
>
> -bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> -                          const struct drm_display_mode *mode,
> -                          struct drm_display_mode *adjusted_mode)
> +bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> +                              struct intel_crtc_config *pipe_config)
>  {
> -       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> +       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> +       struct drm_device *dev = encoder->base.dev;
> +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>
>         if (intel_hdmi->color_range_auto) {
>                 /* See CEA-861-E - 5.1 Default Encoding Parameters */
> @@ -790,6 +791,9 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
>         if (intel_hdmi->color_range)
>                 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
>
> +       if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))

s/IS_HASWELL/HAS_DDI/ ?


> +               pipe_config->has_pch_encoder = true;
> +
>         return true;
>  }
>
> @@ -941,7 +945,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
>  }
>
>  static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
> -       .mode_fixup = intel_hdmi_mode_fixup,
>         .mode_set = intel_hdmi_mode_set,
>  };
>
> @@ -1069,6 +1072,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
>                          DRM_MODE_ENCODER_TMDS);
>         drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
>
> +       intel_encoder->compute_config = intel_hdmi_compute_config;
>         intel_encoder->enable = intel_enable_hdmi;
>         intel_encoder->disable = intel_disable_hdmi;
>         intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 1616f53..1f2efac 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -331,6 +331,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
>                                adjusted_mode);
>
>         if (HAS_PCH_SPLIT(dev)) {
> +               pipe_config->has_pch_encoder = true;
> +
>                 intel_pch_panel_fitting(dev,
>                                         intel_connector->panel.fitting_mode,
>                                         mode, adjusted_mode);
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 3a45be0..7100196 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -1045,6 +1045,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
>         struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>         struct drm_display_mode *mode = &pipe_config->requested_mode;
>
> +       if (HAS_PCH_SPLIT(encoder->base.dev))
> +               pipe_config->has_pch_encoder = true;
> +
>         /* We need to construct preferred input timings based on our
>          * output timings.  To do that, we have to set the output
>          * timings, even though this isn't really the right place in
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 07/10] drm/i915: add pipe_config->limited_color_range
  2013-02-21 23:56 ` [PATCH 07/10] drm/i915: add pipe_config->limited_color_range Daniel Vetter
@ 2013-02-26 17:46   ` Paulo Zanoni
  0 siblings, 0 replies; 31+ messages in thread
From: Paulo Zanoni @ 2013-02-26 17:46 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

Hi

2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Now that we have a useful struct for this, let's use it. Some neat
> pointer-chasing required, but it's all there already.
>
> v2: Rebased on top of the added Haswell limited color range support.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

This one looks good, except for the error message produced by checkpatch.pl :)

With that fixed:
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_display.c | 13 ++++++-------
>  drivers/gpu/drm/i915/intel_dp.c      |  2 +-
>  drivers/gpu/drm/i915/intel_drv.h     | 12 +++++++-----
>  drivers/gpu/drm/i915/intel_hdmi.c    |  5 +++--
>  drivers/gpu/drm/i915/intel_sdvo.c    |  5 +++--
>  5 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index c5f7c6e..a19778c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -5131,7 +5131,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
>         else
>                 val |= PIPECONF_PROGRESSIVE;
>
> -       if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +       if (intel_crtc->config.limited_color_range)
>                 val |= PIPECONF_COLOR_RANGE_SELECT;
>         else
>                 val &= ~PIPECONF_COLOR_RANGE_SELECT;
> @@ -5147,8 +5147,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
>   * is supported, but eventually this should handle various
>   * RGB<->YCbCr scenarios as well.
>   */
> -static void intel_set_pipe_csc(struct drm_crtc *crtc,
> -                              const struct drm_display_mode *adjusted_mode)
> +static void intel_set_pipe_csc(struct drm_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -5163,7 +5162,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
>          * consideration.
>          */
>
> -       if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +       if (intel_crtc->config.limited_color_range)
>                 coeff = ((235 - 16) * (1 << 12) / 255) & 0xff8; /* 0.xxx... */
>
>         /*
> @@ -5187,7 +5186,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
>         if (INTEL_INFO(dev)->gen > 6) {
>                 uint16_t postoff = 0;
>
> -               if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +               if (intel_crtc->config.limited_color_range)
>                         postoff = (16 * (1 << 13) / 255) & 0x1fff;
>
>                 I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff);
> @@ -5198,7 +5197,7 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc,
>         } else {
>                 uint32_t mode = CSC_MODE_YUV_TO_RGB;
>
> -               if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +               if (intel_crtc->config.limited_color_range)
>                         mode |= CSC_BLACK_SCREEN_OFFSET;
>
>                 I915_WRITE(PIPE_CSC_MODE(pipe), mode);
> @@ -5794,7 +5793,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
>
>         haswell_set_pipeconf(crtc, adjusted_mode, dither);
>
> -       intel_set_pipe_csc(crtc, adjusted_mode);
> +       intel_set_pipe_csc(crtc);
>
>         /* Set up the display plane register */
>         I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index e851fdd..0f15513 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -739,7 +739,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>         }
>
>         if (intel_dp->color_range)
> -               adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
> +               pipe_config->limited_color_range = true;
>
>         mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 458e6bd..61ce435 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -103,11 +103,6 @@
>
>  /* drm_display_mode->private_flags */
>  #define INTEL_MODE_DP_FORCE_6BPC (0x10)
> -/*
> - * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
> - * to be used.
> - */
> -#define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
>
>  struct intel_framebuffer {
>         struct drm_framebuffer base;
> @@ -192,6 +187,13 @@ struct intel_crtc_config {
>         /* Whether to set up the PCH/FDI. Note that we never allow sharing
>          * between pch encoders and cpu encoders. */
>         bool has_pch_encoder;
> +
> +       /*
> +        * Use reduced/limited/broadcast rbg range, compressing from the full
> +        * range fed into the crtcs.
> +        */
> +       bool limited_color_range;
> +
>         /* Used by SDVO (and if we ever fix it, HDMI). */
>         unsigned pixel_multiplier;
>  };
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index cfc9d751..a8e7104 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -332,6 +332,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
>                                          struct drm_display_mode *adjusted_mode)
>  {
>         struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> +       struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
>         struct dip_infoframe avi_if = {
>                 .type = DIP_TYPE_AVI,
>                 .ver = DIP_VERSION_AVI,
> @@ -342,7 +343,7 @@ static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
>                 avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
>
>         if (intel_hdmi->rgb_quant_range_selectable) {
> -               if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +               if (intel_crtc->config.limited_color_range)
>                         avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
>                 else
>                         avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
> @@ -789,7 +790,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>         }
>
>         if (intel_hdmi->color_range)
> -               adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
> +               pipe_config->limited_color_range = true;
>
>         if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
>                 pipe_config->has_pch_encoder = true;
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 7100196..59a6781 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -956,9 +956,10 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
>                 .len = DIP_LEN_AVI,
>         };
>         uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
> +       struct intel_crtc *intel_crtc = to_intel_crtc(intel_sdvo->base.base.crtc);
>
>         if (intel_sdvo->rgb_quant_range_selectable) {
> -               if (adjusted_mode->private_flags & INTEL_MODE_LIMITED_COLOR_RANGE)
> +               if (intel_crtc->config.limited_color_range)
>                         avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
>                 else
>                         avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
> @@ -1087,7 +1088,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
>         }
>
>         if (intel_sdvo->color_range)
> -               adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
> +               pipe_config->limited_color_range = true;
>
>         return true;
>  }
> --
> 1.7.11.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-02-26 17:23   ` Paulo Zanoni
@ 2013-03-03 17:58     ` Daniel Vetter
  0 siblings, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-03 17:58 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Daniel Vetter, Intel Graphics Development

On Tue, Feb 26, 2013 at 02:23:23PM -0300, Paulo Zanoni wrote:
> Hi
> 
> 2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> > Only used by the lvds encoder. Note that we shouldn't do the same
> > simple conversion with the FORCE_6BPC flag, since that's much better
> > handled by moving all the pipe_bpc computation around.
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> In addition to Ville's question (which makes sense):
> 
> This patch does 2 things: it adds pipe_config->timings_set, but it
> also adds the encoder->compute_config function. Even though I can see
> intel_encoder->compute_config is just like drm_encoder->mode_fixup but
> with different arguments, I don't think this is a trivial thing to
> notice (imagine a future code reader, not someone looking at this
> specific patch). It would be really nice if you could add the
> compute_config callback on a separate patch and give a detailed
> documentation of the expected behavior of the function for our future
> readers. Bonus points if you could also add documentation for all the
> other intel_encoder callbacks you've created and document their
> relationship with the drm callbacks.
> 
> Also, if we agree to create a separate patch for the compute_config
> callbacks, why don't we just convert all encoders to use
> compute_config instead of mode_fixup in the very first patch? Looks
> simpler to me.

The patch set is pretty old (well, a few months at least), and when I've
started it I kinda expected it to not get merged right away. So I eshewed
doing tree-wide refactorings if not required.

The second reason is that it's almost exactly the same callback as before,
the only difference is that the mode/adjusted_mode argumentes are grouped
together into pipe_config. With a few things tacked on top. So
documentation is "it's like mode_fixup, but better".

Last but not least the current pipe configuration computation code is
really hapzardous and there's a lot of interdependent stuff going on. So
right now I think nothing short of just reading the entire modeset code is
documentation enough. So I don't think adding documentation for this in
the middle of the core reorg makes much sense. I've tried to add useful
documentation for most of the new pipe_config attributes though.

Can I bribe you with the promise that I'll supply a nice blog post and
documenatation patches once the basic infrastructure has settled instead?

Cheers, Daniel

> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
> >  drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
> >  drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
> >  3 files changed, 26 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 0f61008..ad03b7f 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -3930,7 +3930,7 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
> >         /* All interlaced capable intel hw wants timings in frames. Note though
> >          * that intel_lvds_mode_fixup does some funny tricks with the crtc
> >          * timings, so we need to be careful not to clobber these.*/
> > -       if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET))
> > +       if (!pipe_config->timings_set)
> >                 drm_mode_set_crtcinfo(adjusted_mode, 0);
> >
> >         /* WaPruneModeWithIncorrectHsyncOffset: Cantiga+ cannot handle modes
> > @@ -7509,6 +7509,16 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
> >
> >                 if (&encoder->new_crtc->base != crtc)
> >                         continue;
> > +
> > +               if (encoder->compute_config) {
> > +                       if (!(encoder->compute_config(encoder, pipe_config))) {
> > +                               DRM_DEBUG_KMS("Encoder config failure\n");
> > +                               goto fail;
> > +                       }
> > +
> > +                       continue;
> > +               }
> > +
> >                 encoder_funcs = encoder->base.helper_private;
> >                 if (!(encoder_funcs->mode_fixup(&encoder->base,
> >                                                 &pipe_config->requested_mode,
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index eca75b6..edafbef 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -105,10 +105,6 @@
> >  #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
> >  #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
> >  #define INTEL_MODE_DP_FORCE_6BPC (0x10)
> > -/* This flag must be set by the encoder's mode_fixup if it changes the crtc
> > - * timings in the mode to prevent the crtc fixup from overwriting them.
> > - * Currently only lvds needs that. */
> > -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20)
> >  /*
> >   * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
> >   * to be used.
> > @@ -158,6 +154,8 @@ struct intel_encoder {
> >         bool cloneable;
> >         bool connectors_active;
> >         void (*hot_plug)(struct intel_encoder *);
> > +       bool (*compute_config)(struct intel_encoder *,
> > +                              struct intel_crtc_config *);
> >         void (*pre_pll_enable)(struct intel_encoder *);
> >         void (*pre_enable)(struct intel_encoder *);
> >         void (*enable)(struct intel_encoder *);
> > @@ -202,6 +200,10 @@ struct intel_connector {
> >  struct intel_crtc_config {
> >         struct drm_display_mode requested_mode;
> >         struct drm_display_mode adjusted_mode;
> > +       /* This flag must be set by the encoder's compute_config callback if it
> > +        * changes the crtc timings in the mode to prevent the crtc fixup from
> > +        * overwriting them.  Currently only lvds needs that. */
> > +       bool timings_set;
> >  };
> >
> >  struct intel_crtc {
> > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> > index 3d1d974..1616f53 100644
> > --- a/drivers/gpu/drm/i915/intel_lvds.c
> > +++ b/drivers/gpu/drm/i915/intel_lvds.c
> > @@ -261,8 +261,6 @@ centre_horizontally(struct drm_display_mode *mode,
> >
> >         mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos;
> >         mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width;
> > -
> > -       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
> >  }
> >
> >  static void
> > @@ -284,8 +282,6 @@ centre_vertically(struct drm_display_mode *mode,
> >
> >         mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos;
> >         mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width;
> > -
> > -       mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET;
> >  }
> >
> >  static inline u32 panel_fitter_scaling(u32 source, u32 target)
> > @@ -301,15 +297,17 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
> >         return (FACTOR * ratio + FACTOR/2) / FACTOR;
> >  }
> >
> > -static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> > -                                 const struct drm_display_mode *mode,
> > -                                 struct drm_display_mode *adjusted_mode)
> > +static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
> > +                                     struct intel_crtc_config *pipe_config)
> >  {
> > -       struct drm_device *dev = encoder->dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
> > +       struct intel_lvds_encoder *lvds_encoder =
> > +               to_lvds_encoder(&intel_encoder->base);
> >         struct intel_connector *intel_connector =
> >                 &lvds_encoder->attached_connector->base;
> > +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> > +       struct drm_display_mode *mode = &pipe_config->requested_mode;
> >         struct intel_crtc *intel_crtc = lvds_encoder->base.new_crtc;
> >         u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
> >         int pipe;
> > @@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> >                 I915_WRITE(BCLRPAT(pipe), 0);
> >
> >         drm_mode_set_crtcinfo(adjusted_mode, 0);
> > +       pipe_config->timings_set = true;
> >
> >         switch (intel_connector->panel.fitting_mode) {
> >         case DRM_MODE_SCALE_CENTER:
> > @@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
> >  }
> >
> >  static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
> > -       .mode_fixup = intel_lvds_mode_fixup,
> >         .mode_set = intel_lvds_mode_set,
> >  };
> >
> > @@ -1102,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
> >         intel_encoder->enable = intel_enable_lvds;
> >         intel_encoder->pre_enable = intel_pre_enable_lvds;
> >         intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
> > +       intel_encoder->compute_config = intel_lvds_compute_config;
> >         intel_encoder->disable = intel_disable_lvds;
> >         intel_encoder->get_hw_state = intel_lvds_get_hw_state;
> >         intel_connector->get_hw_state = intel_connector_get_hw_state;
> > --
> > 1.7.11.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-02-22 13:51   ` Ville Syrjälä
@ 2013-03-03 18:01     ` Daniel Vetter
  2013-03-04 14:18       ` Ville Syrjälä
  0 siblings, 1 reply; 31+ messages in thread
From: Daniel Vetter @ 2013-03-03 18:01 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Daniel Vetter, Intel Graphics Development

On Fri, Feb 22, 2013 at 03:51:15PM +0200, Ville Syrjälä wrote:
> On Fri, Feb 22, 2013 at 12:56:47AM +0100, Daniel Vetter wrote:
> > Only used by the lvds encoder. Note that we shouldn't do the same
> > simple conversion with the FORCE_6BPC flag, since that's much better
> > handled by moving all the pipe_bpc computation around.
> > 
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
> >  drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
> >  drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
> >  3 files changed, 26 insertions(+), 15 deletions(-)
> > 
> <snip>
> > @@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> >  		I915_WRITE(BCLRPAT(pipe), 0);
> >  
> >  	drm_mode_set_crtcinfo(adjusted_mode, 0);
> > +	pipe_config->timings_set = true;
> 
> This changes the behaviour a bit. Previously the flag was only set from
> the centering funcs, but now it's set always. Is that intentional?

The crtc code also calls drm_mode_set_crtcinfo(adjusted_mode, 0) if
->timings_set is false, so doesn't result in any behaviour change. Hence
I've figure that fewer lines of code should be better. Want me to change
it back or just add a bit of text to the commit message? E.g.

"Note that since the lvds code unconditionally sets the crtc timings, we
can also unconditionally set the respective flag and not just when we set
special timings like the old code did."

Cheers, Daniel

> 
> >  
> >  	switch (intel_connector->panel.fitting_mode) {
> >  	case DRM_MODE_SCALE_CENTER:
> > @@ -661,7 +660,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
> >  }
> >  
> >  static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
> > -	.mode_fixup = intel_lvds_mode_fixup,
> >  	.mode_set = intel_lvds_mode_set,
> >  };
> >  
> > @@ -1102,6 +1100,7 @@ bool intel_lvds_init(struct drm_device *dev)
> >  	intel_encoder->enable = intel_enable_lvds;
> >  	intel_encoder->pre_enable = intel_pre_enable_lvds;
> >  	intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
> > +	intel_encoder->compute_config = intel_lvds_compute_config;
> >  	intel_encoder->disable = intel_disable_lvds;
> >  	intel_encoder->get_hw_state = intel_lvds_get_hw_state;
> >  	intel_connector->get_hw_state = intel_connector_get_hw_state;
> > -- 
> > 1.7.11.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel OTC

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier
  2013-02-26 17:27   ` Paulo Zanoni
@ 2013-03-03 18:05     ` Daniel Vetter
  0 siblings, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-03 18:05 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Daniel Vetter, Intel Graphics Development

On Tue, Feb 26, 2013 at 02:27:36PM -0300, Paulo Zanoni wrote:
> Hi
> 
> 2013/2/21 Daniel Vetter <daniel.vetter@ffwll.ch>:
> > Used by SDVO (and hopefully, eventually HDMI, if we ever get around
> > to fixing up the low dotclock CEA modes ...).
> >
> > This required adding a new encoder->mode_set callback to be able to
> > pass around the intel_crtc_config.
> 
> Again, can we please separate the callback in another patch and add
> some nice documentation explaining what's this callback, why it's
> called and what's its relationship with the other mode_set callbacks
> (again, think about future code readers, not people reading the
> patch)? Also, why not just convert every encoder to this callback
> right now?

Same reasons as for the ->compute_config part - less potential for
conflicts and it's really the same function. The only difference is that
the old ->mode_set only gets mode&adjusted mode, but since without further
changes that's all they're interested in.

On a quick survey of the final state after all patches only sdvo/tv
encoders have such a new mode_set callback. For the compute_config
callback only dvo still uses ->mode_fixup.

I guess we could convert all the leftover ones to the new interfaces once
things settle a bit. But for now I'd like to avoid changing things just
because to avoid needless conflicts.
-Daniel

> 
> The pixel_multiplier part of the patch looks correct.
> 
> >
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 80 +++++++++++++++++++-----------------
> >  drivers/gpu/drm/i915/intel_drv.h     | 19 ++-------
> >  drivers/gpu/drm/i915/intel_sdvo.c    | 39 +++++++++---------
> >  3 files changed, 66 insertions(+), 72 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index ad03b7f..3446e2b 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -4280,14 +4280,15 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
> >  }
> >
> >  static void vlv_update_pll(struct drm_crtc *crtc,
> > -                          struct drm_display_mode *mode,
> > -                          struct drm_display_mode *adjusted_mode,
> >                            intel_clock_t *clock, intel_clock_t *reduced_clock,
> >                            int num_connectors)
> >  {
> >         struct drm_device *dev = crtc->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +       struct drm_display_mode *adjusted_mode =
> > +               &intel_crtc->config.adjusted_mode;
> > +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
> >         int pipe = intel_crtc->pipe;
> >         u32 dpll, mdiv, pdiv;
> >         u32 bestn, bestm1, bestm2, bestp1, bestp2;
> > @@ -4354,11 +4355,11 @@ static void vlv_update_pll(struct drm_crtc *crtc,
> >
> >         temp = 0;
> >         if (is_sdvo) {
> > -               temp = intel_mode_get_pixel_multiplier(adjusted_mode);
> > -               if (temp > 1)
> > -                       temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> > -               else
> > -                       temp = 0;
> > +               temp = 0;
> > +               if (intel_crtc->config.pixel_multiplier > 1) {
> > +                       temp = (intel_crtc->config.pixel_multiplier - 1)
> > +                               << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> > +               }
> >         }
> >         I915_WRITE(DPLL_MD(pipe), temp);
> >         POSTING_READ(DPLL_MD(pipe));
> > @@ -4384,14 +4385,15 @@ static void vlv_update_pll(struct drm_crtc *crtc,
> >  }
> >
> >  static void i9xx_update_pll(struct drm_crtc *crtc,
> > -                           struct drm_display_mode *mode,
> > -                           struct drm_display_mode *adjusted_mode,
> >                             intel_clock_t *clock, intel_clock_t *reduced_clock,
> >                             int num_connectors)
> >  {
> >         struct drm_device *dev = crtc->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +       struct drm_display_mode *adjusted_mode =
> > +               &intel_crtc->config.adjusted_mode;
> > +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
> >         struct intel_encoder *encoder;
> >         int pipe = intel_crtc->pipe;
> >         u32 dpll;
> > @@ -4408,11 +4410,12 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
> >                 dpll |= DPLLB_MODE_LVDS;
> >         else
> >                 dpll |= DPLLB_MODE_DAC_SERIAL;
> > +
> >         if (is_sdvo) {
> > -               int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> > -               if (pixel_multiplier > 1) {
> > -                       if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
> > -                               dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
> > +               if ((intel_crtc->config.pixel_multiplier > 1) &&
> > +                   (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))) {
> > +                       dpll |= (intel_crtc->config.pixel_multiplier - 1)
> > +                               << SDVO_MULTIPLIER_SHIFT_HIRES;
> >                 }
> >                 dpll |= DPLL_DVO_HIGH_SPEED;
> >         }
> > @@ -4477,11 +4480,11 @@ static void i9xx_update_pll(struct drm_crtc *crtc,
> >         if (INTEL_INFO(dev)->gen >= 4) {
> >                 u32 temp = 0;
> >                 if (is_sdvo) {
> > -                       temp = intel_mode_get_pixel_multiplier(adjusted_mode);
> > -                       if (temp > 1)
> > -                               temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> > -                       else
> > -                               temp = 0;
> > +                       temp = 0;
> > +                       if (intel_crtc->config.pixel_multiplier > 1) {
> > +                               temp = (intel_crtc->config.pixel_multiplier - 1)
> > +                                       << DPLL_MD_UDI_MULTIPLIER_SHIFT;
> > +                       }
> >                 }
> >                 I915_WRITE(DPLL_MD(pipe), temp);
> >         } else {
> > @@ -4691,11 +4694,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
> >                                 has_reduced_clock ? &reduced_clock : NULL,
> >                                 num_connectors);
> >         else if (IS_VALLEYVIEW(dev))
> > -               vlv_update_pll(crtc, mode, adjusted_mode, &clock,
> > +               vlv_update_pll(crtc, &clock,
> >                                 has_reduced_clock ? &reduced_clock : NULL,
> >                                 num_connectors);
> >         else
> > -               i9xx_update_pll(crtc, mode, adjusted_mode, &clock,
> > +               i9xx_update_pll(crtc, &clock,
> >                                 has_reduced_clock ? &reduced_clock : NULL,
> >                                 num_connectors);
> >
> > @@ -5407,17 +5410,18 @@ int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp)
> >         return bps / (link_bw * 8) + 1;
> >  }
> >
> > -static void ironlake_set_m_n(struct drm_crtc *crtc,
> > -                            struct drm_display_mode *mode,
> > -                            struct drm_display_mode *adjusted_mode)
> > +static void ironlake_set_m_n(struct drm_crtc *crtc)
> >  {
> >         struct drm_device *dev = crtc->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > +       struct drm_display_mode *adjusted_mode =
> > +               &intel_crtc->config.adjusted_mode;
> > +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
> >         enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
> >         struct intel_encoder *intel_encoder, *edp_encoder = NULL;
> >         struct intel_link_m_n m_n = {0};
> > -       int target_clock, pixel_multiplier, lane, link_bw;
> > +       int target_clock, lane, link_bw;
> >         bool is_dp = false, is_cpu_edp = false;
> >
> >         for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> > @@ -5435,7 +5439,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
> >         }
> >
> >         /* FDI link */
> > -       pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> >         lane = 0;
> >         /* CPU eDP doesn't require FDI link, so just set DP M/N
> >            according to current link config */
> > @@ -5466,8 +5469,8 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
> >
> >         intel_crtc->fdi_lanes = lane;
> >
> > -       if (pixel_multiplier > 1)
> > -               link_bw *= pixel_multiplier;
> > +       if (intel_crtc->config.pixel_multiplier > 1)
> > +               link_bw *= intel_crtc->config.pixel_multiplier;
> >         intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
> >
> >         I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
> > @@ -5477,7 +5480,6 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
> >  }
> >
> >  static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
> > -                                     struct drm_display_mode *adjusted_mode,
> >                                       intel_clock_t *clock, u32 fp)
> >  {
> >         struct drm_crtc *crtc = &intel_crtc->base;
> > @@ -5485,7 +5487,7 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_encoder *intel_encoder;
> >         uint32_t dpll;
> > -       int factor, pixel_multiplier, num_connectors = 0;
> > +       int factor, num_connectors = 0;
> >         bool is_lvds = false, is_sdvo = false, is_tv = false;
> >         bool is_dp = false, is_cpu_edp = false;
> >
> > @@ -5536,9 +5538,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
> >         else
> >                 dpll |= DPLLB_MODE_DAC_SERIAL;
> >         if (is_sdvo) {
> > -               pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> > -               if (pixel_multiplier > 1) {
> > -                       dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> > +               if (intel_crtc->config.pixel_multiplier > 1) {
> > +                       dpll |= (intel_crtc->config.pixel_multiplier - 1)
> > +                               << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
> >                 }
> >                 dpll |= DPLL_DVO_HIGH_SPEED;
> >         }
> > @@ -5642,7 +5644,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> >                 fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
> >                         reduced_clock.m2;
> >
> > -       dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp);
> > +       dpll = ironlake_compute_dpll(intel_crtc, &clock, fp);
> >
> >         DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
> >         drm_mode_debug_printmodeline(mode);
> > @@ -5696,7 +5698,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
> >
> >         /* Note, this also computes intel_crtc->fdi_lanes which is used below in
> >          * ironlake_check_fdi_lanes. */
> > -       ironlake_set_m_n(crtc, mode, adjusted_mode);
> > +       ironlake_set_m_n(crtc);
> >
> >         fdi_config_ok = ironlake_check_fdi_lanes(intel_crtc);
> >
> > @@ -5812,7 +5814,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
> >         intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
> >
> >         if (!is_dp || is_cpu_edp)
> > -               ironlake_set_m_n(crtc, mode, adjusted_mode);
> > +               ironlake_set_m_n(crtc);
> >
> >         haswell_set_pipeconf(crtc, adjusted_mode, dither);
> >
> > @@ -5865,8 +5867,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> >                         encoder->base.base.id,
> >                         drm_get_encoder_name(&encoder->base),
> >                         mode->base.id, mode->name);
> > -               encoder_funcs = encoder->base.helper_private;
> > -               encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
> > +               if (encoder->mode_set) {
> > +                       encoder->mode_set(encoder);
> > +               } else {
> > +                       encoder_funcs = encoder->base.helper_private;
> > +                       encoder_funcs->mode_set(&encoder->base, mode, adjusted_mode);
> > +               }
> >         }
> >
> >         return 0;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index edafbef..ef5111b 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -102,8 +102,6 @@
> >  #define INTEL_DVO_CHIP_TVOUT 4
> >
> >  /* drm_display_mode->private_flags */
> > -#define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0)
> > -#define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT)
> >  #define INTEL_MODE_DP_FORCE_6BPC (0x10)
> >  /*
> >   * Set when limited 16-235 (as opposed to full 0-255) RGB color range is
> > @@ -111,20 +109,6 @@
> >   */
> >  #define INTEL_MODE_LIMITED_COLOR_RANGE (0x40)
> >
> > -static inline void
> > -intel_mode_set_pixel_multiplier(struct drm_display_mode *mode,
> > -                               int multiplier)
> > -{
> > -       mode->clock *= multiplier;
> > -       mode->private_flags |= multiplier;
> > -}
> > -
> > -static inline int
> > -intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode)
> > -{
> > -       return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT;
> > -}
> > -
> >  struct intel_framebuffer {
> >         struct drm_framebuffer base;
> >         struct drm_i915_gem_object *obj;
> > @@ -159,6 +143,7 @@ struct intel_encoder {
> >         void (*pre_pll_enable)(struct intel_encoder *);
> >         void (*pre_enable)(struct intel_encoder *);
> >         void (*enable)(struct intel_encoder *);
> > +       void (*mode_set)(struct intel_encoder *intel_encoder);
> >         void (*disable)(struct intel_encoder *);
> >         void (*post_disable)(struct intel_encoder *);
> >         /* Read out the current hw state of this connector, returning true if
> > @@ -204,6 +189,8 @@ struct intel_crtc_config {
> >          * changes the crtc timings in the mode to prevent the crtc fixup from
> >          * overwriting them.  Currently only lvds needs that. */
> >         bool timings_set;
> > +       /* Used by SDVO (and if we ever fix it, HDMI). */
> > +       unsigned pixel_multiplier;
> >  };
> >
> >  struct intel_crtc {
> > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> > index 33b46d9..06bb2e1 100644
> > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > @@ -788,7 +788,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
> >         v_sync_offset = mode->vsync_start - mode->vdisplay;
> >
> >         mode_clock = mode->clock;
> > -       mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1;
> >         mode_clock /= 10;
> >         dtd->part1.clock = mode_clock;
> >
> > @@ -1039,12 +1038,12 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
> >         return true;
> >  }
> >
> > -static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> > -                                 const struct drm_display_mode *mode,
> > -                                 struct drm_display_mode *adjusted_mode)
> > +static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
> > +                                     struct intel_crtc_config *pipe_config)
> >  {
> > -       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
> > -       int multiplier;
> > +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
> > +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> > +       struct drm_display_mode *mode = &pipe_config->requested_mode;
> >
> >         /* We need to construct preferred input timings based on our
> >          * output timings.  To do that, we have to set the output
> > @@ -1071,8 +1070,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >         /* Make the CRTC code factor in the SDVO pixel multiplier.  The
> >          * SDVO device will factor out the multiplier during mode_set.
> >          */
> > -       multiplier = intel_sdvo_get_pixel_multiplier(adjusted_mode);
> > -       intel_mode_set_pixel_multiplier(adjusted_mode, multiplier);
> > +       pipe_config->pixel_multiplier =
> > +               intel_sdvo_get_pixel_multiplier(adjusted_mode);
> > +       adjusted_mode->clock *= pipe_config->pixel_multiplier;
> >
> >         if (intel_sdvo->color_range_auto) {
> >                 /* See CEA-861-E - 5.1 Default Encoding Parameters */
> > @@ -1089,19 +1089,19 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >         return true;
> >  }
> >
> > -static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> > -                               struct drm_display_mode *mode,
> > -                               struct drm_display_mode *adjusted_mode)
> > +static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder)
> >  {
> > -       struct drm_device *dev = encoder->dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct drm_crtc *crtc = encoder->crtc;
> > +       struct drm_crtc *crtc = intel_encoder->base.crtc;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -       struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);
> > +       struct drm_display_mode *adjusted_mode =
> > +               &intel_crtc->config.adjusted_mode;
> > +       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
> > +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&intel_encoder->base);
> >         u32 sdvox;
> >         struct intel_sdvo_in_out_map in_out;
> >         struct intel_sdvo_dtd input_dtd, output_dtd;
> > -       int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
> >         int rate;
> >
> >         if (!mode)
> > @@ -1161,7 +1161,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >                 DRM_INFO("Setting input timings on %s failed\n",
> >                          SDVO_NAME(intel_sdvo));
> >
> > -       switch (pixel_multiplier) {
> > +       switch (intel_crtc->config.pixel_multiplier) {
> >         default:
> >         case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
> >         case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
> > @@ -1205,7 +1205,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >         } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
> >                 /* done in crtc_mode_set as it lives inside the dpll register */
> >         } else {
> > -               sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT;
> > +               sdvox |= (intel_crtc->config.pixel_multiplier - 1)
> > +                       << SDVO_PORT_MULTIPLY_SHIFT;
> >         }
> >
> >         if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL &&
> > @@ -2041,8 +2042,6 @@ done:
> >  }
> >
> >  static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
> > -       .mode_fixup = intel_sdvo_mode_fixup,
> > -       .mode_set = intel_sdvo_mode_set,
> >  };
> >
> >  static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
> > @@ -2781,7 +2780,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
> >
> >         drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
> >
> > +       intel_encoder->compute_config = intel_sdvo_compute_config;
> >         intel_encoder->disable = intel_disable_sdvo;
> > +       intel_encoder->mode_set = intel_sdvo_mode_set;
> >         intel_encoder->enable = intel_enable_sdvo;
> >         intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
> >
> > --
> > 1.7.11.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* Re: [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder
  2013-02-26 17:39   ` Paulo Zanoni
@ 2013-03-03 18:13     ` Daniel Vetter
  2013-03-03 18:16       ` [PATCH] " Daniel Vetter
  2013-03-04 22:24       ` Daniel Vetter
  0 siblings, 2 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-03 18:13 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: Daniel Vetter, Intel Graphics Development

On Tue, Feb 26, 2013 at 02:39:15PM -0300, Paulo Zanoni wrote:
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 3446e2b..c5f7c6e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -2947,27 +2947,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
> >         mutex_unlock(&dev->struct_mutex);
> >  }
> >
> > -static bool ironlake_crtc_driving_pch(struct drm_crtc *crtc)
> > -{
> > -       struct drm_device *dev = crtc->dev;
> > -       struct intel_encoder *intel_encoder;
> > -
> > -       /*
> > -        * If there's a non-PCH eDP on this crtc, it must be DP_A, and that
> > -        * must be driven by its own crtc; no sharing is possible.
> > -        */
> > -       for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
> > -               switch (intel_encoder->type) {
> > -               case INTEL_OUTPUT_EDP:
> > -                       if (!intel_encoder_is_pch_edp(&intel_encoder->base))
> > -                               return false;
> > -                       continue;
> > -               }
> > -       }
> > -
> > -       return true;
> > -}
> > -
> >  static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)
> 
> You forgot to kill haswell_crtc_driving_pch and replace its usage
> inside haswell_crtc_disable.

Nope, see the v2 comment in the commit message: Due to missing hw state
readout support we can't use that flag in the disable paths yet, hence
that code needs to stay for now. Note that I replace all usages of
haswell_crtc_driving_pch outside of the haswell crtc disable functions.

Ack for the other comments below, the IS_HASWELL/HAS_DDI is simply rebase
fail.

Thanks, Daniel

> 
> 
> >  {
> >         return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
> > @@ -3308,7 +3287,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
> >         int pipe = intel_crtc->pipe;
> >         int plane = intel_crtc->plane;
> >         u32 temp;
> > -       bool is_pch_port;
> >
> >         WARN_ON(!crtc->enabled);
> >
> > @@ -3324,9 +3302,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
> >                         I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
> >         }
> >
> > -       is_pch_port = ironlake_crtc_driving_pch(crtc);
> >
> > -       if (is_pch_port) {
> > +       if (intel_crtc->config.has_pch_encoder) {
> >                 /* Note: FDI PLL enabling _must_ be done before we enable the
> >                  * cpu pipes, hence this is separate from all the other fdi/pch
> >                  * enabling. */
> > @@ -3363,10 +3340,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
> >          */
> >         intel_crtc_load_lut(crtc);
> >
> > -       intel_enable_pipe(dev_priv, pipe, is_pch_port);
> > +       intel_enable_pipe(dev_priv, pipe,
> > +                         intel_crtc->config.has_pch_encoder);
> >         intel_enable_plane(dev_priv, plane, pipe);
> >
> > -       if (is_pch_port)
> > +       if (intel_crtc->config.has_pch_encoder)
> >                 ironlake_pch_enable(crtc);
> >
> >         mutex_lock(&dev->struct_mutex);
> > @@ -3400,7 +3378,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >         struct intel_encoder *encoder;
> >         int pipe = intel_crtc->pipe;
> >         int plane = intel_crtc->plane;
> > -       bool is_pch_port;
> >
> >         WARN_ON(!crtc->enabled);
> >
> > @@ -3410,9 +3387,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >         intel_crtc->active = true;
> >         intel_update_watermarks(dev);
> >
> > -       is_pch_port = haswell_crtc_driving_pch(crtc);
> > -
> > -       if (is_pch_port)
> > +       if (intel_crtc->config.has_pch_encoder)
> >                 dev_priv->display.fdi_link_train(crtc);
> >
> >         for_each_encoder_on_crtc(dev, crtc, encoder)
> > @@ -3443,10 +3418,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
> >         intel_ddi_set_pipe_settings(crtc);
> >         intel_ddi_enable_pipe_func(crtc);
> >
> > -       intel_enable_pipe(dev_priv, pipe, is_pch_port);
> > +       intel_enable_pipe(dev_priv, pipe,
> > +                         intel_crtc->config.has_pch_encoder);
> >         intel_enable_plane(dev_priv, plane, pipe);
> >
> > -       if (is_pch_port)
> > +       if (intel_crtc->config.has_pch_encoder)
> >                 lpt_pch_enable(crtc);
> >
> >         mutex_lock(&dev->struct_mutex);
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 9b1a969..e851fdd 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -689,12 +689,13 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
> >  }
> >
> >  bool
> > -intel_dp_mode_fixup(struct drm_encoder *encoder,
> > -                   const struct drm_display_mode *mode,
> > -                   struct drm_display_mode *adjusted_mode)
> > +intel_dp_compute_config(struct intel_encoder *encoder,
> > +                       struct intel_crtc_config *pipe_config)
> >  {
> > -       struct drm_device *dev = encoder->dev;
> > -       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +       struct drm_device *dev = encoder->base.dev;
> > +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> > +       struct drm_display_mode *mode = &pipe_config->requested_mode;
> > +       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> >         struct intel_connector *intel_connector = intel_dp->attached_connector;
> >         int lane_count, clock;
> >         int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
> > @@ -702,6 +703,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
> >         int bpp, mode_rate;
> >         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
> >
> > +       if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))
> 
> s/IS_HASWELL/HAS_DDI/ ?
> 
> 
> > +               pipe_config->has_pch_encoder = true;
> > +
> >         if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
> >                 intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
> >                                        adjusted_mode);
> > @@ -2517,7 +2521,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
> >  }
> >
> >  static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
> > -       .mode_fixup = intel_dp_mode_fixup,
> >         .mode_set = intel_dp_mode_set,
> >  };
> >
> > @@ -2937,6 +2940,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
> >                          DRM_MODE_ENCODER_TMDS);
> >         drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
> >
> > +       intel_encoder->compute_config = intel_dp_compute_config;
> >         intel_encoder->enable = intel_enable_dp;
> >         intel_encoder->pre_enable = intel_pre_enable_dp;
> >         intel_encoder->disable = intel_disable_dp;
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index ef5111b..458e6bd 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -189,6 +189,9 @@ struct intel_crtc_config {
> >          * changes the crtc timings in the mode to prevent the crtc fixup from
> >          * overwriting them.  Currently only lvds needs that. */
> >         bool timings_set;
> > +       /* Whether to set up the PCH/FDI. Note that we never allow sharing
> > +        * between pch encoders and cpu encoders. */
> > +       bool has_pch_encoder;
> >         /* Used by SDVO (and if we ever fix it, HDMI). */
> >         unsigned pixel_multiplier;
> >  };
> > @@ -444,9 +447,8 @@ extern void intel_hdmi_init(struct drm_device *dev,
> >  extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
> >                                       struct intel_connector *intel_connector);
> >  extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
> > -extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> > -                                 const struct drm_display_mode *mode,
> > -                                 struct drm_display_mode *adjusted_mode);
> > +extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> > +                                     struct intel_crtc_config *);
> 
> To keep the coding style consistent, "struct intel_crtc_config *pipe_config);" ?
> 
> 
> >  extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
> >  extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
> >                             bool is_sdvob);
> > @@ -470,9 +472,8 @@ extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
> >  extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
> >  extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
> >  extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
> > -extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
> > -                               const struct drm_display_mode *mode,
> > -                               struct drm_display_mode *adjusted_mode);
> > +extern bool intel_dp_compute_config(struct intel_encoder *encoder,
> > +                                   struct intel_crtc_config *pipe_config);
> >  extern bool intel_dpd_is_edp(struct drm_device *dev);
> >  extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
> >  extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 92aba3c..cfc9d751 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -772,11 +772,12 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
> >         return MODE_OK;
> >  }
> >
> > -bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> > -                          const struct drm_display_mode *mode,
> > -                          struct drm_display_mode *adjusted_mode)
> > +bool intel_hdmi_compute_config(struct intel_encoder *encoder,
> > +                              struct intel_crtc_config *pipe_config)
> >  {
> > -       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
> > +       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> > +       struct drm_device *dev = encoder->base.dev;
> > +       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> >
> >         if (intel_hdmi->color_range_auto) {
> >                 /* See CEA-861-E - 5.1 Default Encoding Parameters */
> > @@ -790,6 +791,9 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> >         if (intel_hdmi->color_range)
> >                 adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
> >
> > +       if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
> 
> s/IS_HASWELL/HAS_DDI/ ?
> 
> 
> > +               pipe_config->has_pch_encoder = true;
> > +
> >         return true;
> >  }
> >
> > @@ -941,7 +945,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
> >  }
> >
> >  static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
> > -       .mode_fixup = intel_hdmi_mode_fixup,
> >         .mode_set = intel_hdmi_mode_set,
> >  };
> >
> > @@ -1069,6 +1072,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
> >                          DRM_MODE_ENCODER_TMDS);
> >         drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
> >
> > +       intel_encoder->compute_config = intel_hdmi_compute_config;
> >         intel_encoder->enable = intel_enable_hdmi;
> >         intel_encoder->disable = intel_disable_hdmi;
> >         intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
> > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> > index 1616f53..1f2efac 100644
> > --- a/drivers/gpu/drm/i915/intel_lvds.c
> > +++ b/drivers/gpu/drm/i915/intel_lvds.c
> > @@ -331,6 +331,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
> >                                adjusted_mode);
> >
> >         if (HAS_PCH_SPLIT(dev)) {
> > +               pipe_config->has_pch_encoder = true;
> > +
> >                 intel_pch_panel_fitting(dev,
> >                                         intel_connector->panel.fitting_mode,
> >                                         mode, adjusted_mode);
> > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> > index 3a45be0..7100196 100644
> > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > @@ -1045,6 +1045,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
> >         struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
> >         struct drm_display_mode *mode = &pipe_config->requested_mode;
> >
> > +       if (HAS_PCH_SPLIT(encoder->base.dev))
> > +               pipe_config->has_pch_encoder = true;
> > +
> >         /* We need to construct preferred input timings based on our
> >          * output timings.  To do that, we have to set the output
> >          * timings, even though this isn't really the right place in
> > --
> > 1.7.11.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* [PATCH] drm/i915: add pipe_config->has_pch_encoder
  2013-03-03 18:13     ` Daniel Vetter
@ 2013-03-03 18:16       ` Daniel Vetter
  2013-03-04 22:24       ` Daniel Vetter
  1 sibling, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-03 18:16 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

This is used way too often in the enable/disable paths. And will
be even more useful in the future.

Note that correct semantics of this change highly depend upon
correct updating of intel_crtc->config: Like with all other
modeset state, we need to call ->disable with the old config,
but ->mode_set and ->enable with the new config.

v2: Do not yet use the flag in the ->disable callbacks - atm we don't
yet have support for the information stored in the pipe_config in the
hw state readout code, so this will be wrong at boot-up/resume.

v3: Rebased on top of the hdmi/dp ddi encoder merging.

v4: Fixup stupid rebase error which lead to a NULL vfunc deref.

v5: On haswell the VGA port is on the PCH!

v6: s/IS_HASWELL/HAS_DDI/, spotted by Paulo Zanoni. Also add a missing
parameter name in a function declaration.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_crt.c     | 12 +++++++----
 drivers/gpu/drm/i915/intel_ddi.c     | 16 +++++++--------
 drivers/gpu/drm/i915/intel_display.c | 40 ++++++++----------------------------
 drivers/gpu/drm/i915/intel_dp.c      | 16 +++++++++------
 drivers/gpu/drm/i915/intel_drv.h     | 13 ++++++------
 drivers/gpu/drm/i915/intel_hdmi.c    | 14 ++++++++-----
 drivers/gpu/drm/i915/intel_lvds.c    |  2 ++
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
 8 files changed, 54 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 969d08c..1bd09a7 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -206,10 +206,14 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_crt_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
+	struct drm_device *dev = encoder->base.dev;
+
+	if (HAS_PCH_SPLIT(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -683,7 +687,6 @@ static void intel_crt_reset(struct drm_connector *connector)
  */
 
 static const struct drm_encoder_helper_funcs crt_encoder_funcs = {
-	.mode_fixup = intel_crt_mode_fixup,
 	.mode_set = intel_crt_mode_set,
 };
 
@@ -774,6 +777,7 @@ void intel_crt_init(struct drm_device *dev)
 	else
 		crt->adpa_reg = ADPA;
 
+	crt->base.compute_config = intel_crt_compute_config;
 	crt->base.disable = intel_disable_crt;
 	crt->base.enable = intel_enable_crt;
 	if (HAS_DDI(dev))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fc95ef0..f5ae79f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1467,19 +1467,17 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
 	intel_dp_encoder_destroy(encoder);
 }
 
-static bool intel_ddi_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_ddi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
-	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-	int type = intel_encoder->type;
+	int type = encoder->type;
 
-	WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n");
+	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
 
 	if (type == INTEL_OUTPUT_HDMI)
-		return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_hdmi_compute_config(encoder, pipe_config);
 	else
-		return intel_dp_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_dp_compute_config(encoder, pipe_config);
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
@@ -1487,7 +1485,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
 };
 
 static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
-	.mode_fixup = intel_ddi_mode_fixup,
 	.mode_set = intel_ddi_mode_set,
 };
 
@@ -1527,6 +1524,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs);
 
+	intel_encoder->compute_config = intel_ddi_compute_config;
 	intel_encoder->enable = intel_enable_ddi;
 	intel_encoder->pre_enable = intel_ddi_pre_enable;
 	intel_encoder->disable = intel_disable_ddi;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e7cc17c..5ed3a9b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2947,27 +2947,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 	mutex_unlock(&dev->struct_mutex);
 }
 
-static bool ironlake_crtc_driving_pch(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct intel_encoder *intel_encoder;
-
-	/*
-	 * If there's a non-PCH eDP on this crtc, it must be DP_A, and that
-	 * must be driven by its own crtc; no sharing is possible.
-	 */
-	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
-		switch (intel_encoder->type) {
-		case INTEL_OUTPUT_EDP:
-			if (!intel_encoder_is_pch_edp(&intel_encoder->base))
-				return false;
-			continue;
-		}
-	}
-
-	return true;
-}
-
 static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)
 {
 	return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
@@ -3308,7 +3287,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	u32 temp;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3324,9 +3302,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 			I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
 	}
 
-	is_pch_port = ironlake_crtc_driving_pch(crtc);
 
-	if (is_pch_port) {
+	if (intel_crtc->config.has_pch_encoder) {
 		/* Note: FDI PLL enabling _must_ be done before we enable the
 		 * cpu pipes, hence this is separate from all the other fdi/pch
 		 * enabling. */
@@ -3363,10 +3340,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	 */
 	intel_crtc_load_lut(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		ironlake_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
@@ -3400,7 +3378,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3410,9 +3387,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc->active = true;
 	intel_update_watermarks(dev);
 
-	is_pch_port = haswell_crtc_driving_pch(crtc);
-
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		dev_priv->display.fdi_link_train(crtc);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3443,10 +3418,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_ddi_set_pipe_settings(crtc);
 	intel_ddi_enable_pipe_func(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		lpt_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9b1a969..e851fdd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -689,12 +689,13 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
 }
 
 bool
-intel_dp_mode_fixup(struct drm_encoder *encoder,
-		    const struct drm_display_mode *mode,
-		    struct drm_display_mode *adjusted_mode)
+intel_dp_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = encoder->dev;
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->requested_mode;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	int lane_count, clock;
 	int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
@@ -702,6 +703,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
+	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev) && !is_cpu_edp(intel_dp))
+		pipe_config->has_pch_encoder = true;
+
 	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
 		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 				       adjusted_mode);
@@ -2517,7 +2521,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
-	.mode_fixup = intel_dp_mode_fixup,
 	.mode_set = intel_dp_mode_set,
 };
 
@@ -2937,6 +2940,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
 
+	intel_encoder->compute_config = intel_dp_compute_config;
 	intel_encoder->enable = intel_enable_dp;
 	intel_encoder->pre_enable = intel_pre_enable_dp;
 	intel_encoder->disable = intel_disable_dp;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ef5111b..458e6bd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -189,6 +189,9 @@ struct intel_crtc_config {
 	 * changes the crtc timings in the mode to prevent the crtc fixup from
 	 * overwriting them.  Currently only lvds needs that. */
 	bool timings_set;
+	/* Whether to set up the PCH/FDI. Note that we never allow sharing
+	 * between pch encoders and cpu encoders. */
+	bool has_pch_encoder;
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 };
@@ -444,9 +447,8 @@ extern void intel_hdmi_init(struct drm_device *dev,
 extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 				      struct intel_connector *intel_connector);
 extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
-extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode);
+extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+				      struct intel_crtc_config *);
 extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
 extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
 			    bool is_sdvob);
@@ -470,9 +472,8 @@ extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
-extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
+extern bool intel_dp_compute_config(struct intel_encoder *encoder,
+				    struct intel_crtc_config *pipe_config);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
 extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 92aba3c..cfc9d751 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -772,11 +772,12 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-			   const struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode)
+bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+			       struct intel_crtc_config *pipe_config)
 {
-	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (intel_hdmi->color_range_auto) {
 		/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -790,6 +791,9 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 	if (intel_hdmi->color_range)
 		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
 
+	if (HAS_PCH_SPLIT(dev) && !IS_HASWELL(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -941,7 +945,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
-	.mode_fixup = intel_hdmi_mode_fixup,
 	.mode_set = intel_hdmi_mode_set,
 };
 
@@ -1069,6 +1072,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
 
+	intel_encoder->compute_config = intel_hdmi_compute_config;
 	intel_encoder->enable = intel_enable_hdmi;
 	intel_encoder->disable = intel_disable_hdmi;
 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 1616f53..1f2efac 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -331,6 +331,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 			       adjusted_mode);
 
 	if (HAS_PCH_SPLIT(dev)) {
+		pipe_config->has_pch_encoder = true;
+
 		intel_pch_panel_fitting(dev,
 					intel_connector->panel.fitting_mode,
 					mode, adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3a45be0..7100196 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1045,6 +1045,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 
+	if (HAS_PCH_SPLIT(encoder->base.dev))
+		pipe_config->has_pch_encoder = true;
+
 	/* We need to construct preferred input timings based on our
 	 * output timings.  To do that, we have to set the output
 	 * timings, even though this isn't really the right place in
-- 
1.7.11.4

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

* Re: [PATCH 03/10] drm/i915: add pipe_config->timings_set
  2013-03-03 18:01     ` Daniel Vetter
@ 2013-03-04 14:18       ` Ville Syrjälä
  0 siblings, 0 replies; 31+ messages in thread
From: Ville Syrjälä @ 2013-03-04 14:18 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development

On Sun, Mar 03, 2013 at 07:01:12PM +0100, Daniel Vetter wrote:
> On Fri, Feb 22, 2013 at 03:51:15PM +0200, Ville Syrjälä wrote:
> > On Fri, Feb 22, 2013 at 12:56:47AM +0100, Daniel Vetter wrote:
> > > Only used by the lvds encoder. Note that we shouldn't do the same
> > > simple conversion with the FORCE_6BPC flag, since that's much better
> > > handled by moving all the pipe_bpc computation around.
> > > 
> > > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > > ---
> > >  drivers/gpu/drm/i915/intel_display.c | 12 +++++++++++-
> > >  drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++----
> > >  drivers/gpu/drm/i915/intel_lvds.c    | 19 +++++++++----------
> > >  3 files changed, 26 insertions(+), 15 deletions(-)
> > > 
> > <snip>
> > > @@ -359,6 +357,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> > >  		I915_WRITE(BCLRPAT(pipe), 0);
> > >  
> > >  	drm_mode_set_crtcinfo(adjusted_mode, 0);
> > > +	pipe_config->timings_set = true;
> > 
> > This changes the behaviour a bit. Previously the flag was only set from
> > the centering funcs, but now it's set always. Is that intentional?
> 
> The crtc code also calls drm_mode_set_crtcinfo(adjusted_mode, 0) if
> ->timings_set is false, so doesn't result in any behaviour change. Hence
> I've figure that fewer lines of code should be better. Want me to change
> it back or just add a bit of text to the commit message? E.g.
> 
> "Note that since the lvds code unconditionally sets the crtc timings, we
> can also unconditionally set the respective flag and not just when we set
> special timings like the old code did."

Right, I should have actually read the code with some thought instead
of blindly looking at the changes. I think amending the commit message
with the proposed text would be enough.

-- 
Ville Syrjälä
Intel OTC

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

* [PATCH] drm/i915: add pipe_config->has_pch_encoder
  2013-03-03 18:13     ` Daniel Vetter
  2013-03-03 18:16       ` [PATCH] " Daniel Vetter
@ 2013-03-04 22:24       ` Daniel Vetter
  1 sibling, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-04 22:24 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter

This is used way too often in the enable/disable paths. And will
be even more useful in the future.

Note that correct semantics of this change highly depend upon
correct updating of intel_crtc->config: Like with all other
modeset state, we need to call ->disable with the old config,
but ->mode_set and ->enable with the new config.

v2: Do not yet use the flag in the ->disable callbacks - atm we don't
yet have support for the information stored in the pipe_config in the
hw state readout code, so this will be wrong at boot-up/resume.

v3: Rebased on top of the hdmi/dp ddi encoder merging.

v4: Fixup stupid rebase error which lead to a NULL vfunc deref.

v5: On haswell the VGA port is on the PCH!

v6: s/IS_HASWELL/HAS_DDI/, spotted by Paulo Zanoni. Also add a missing
parameter name in a function declaration.

v7: Don't forget to git add ...

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_crt.c     | 12 +++++++----
 drivers/gpu/drm/i915/intel_ddi.c     | 16 +++++++--------
 drivers/gpu/drm/i915/intel_display.c | 40 ++++++++----------------------------
 drivers/gpu/drm/i915/intel_dp.c      | 16 +++++++++------
 drivers/gpu/drm/i915/intel_drv.h     | 13 ++++++------
 drivers/gpu/drm/i915/intel_hdmi.c    | 14 ++++++++-----
 drivers/gpu/drm/i915/intel_lvds.c    |  2 ++
 drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
 8 files changed, 54 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 969d08c..1bd09a7 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -206,10 +206,14 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_crt_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
+	struct drm_device *dev = encoder->base.dev;
+
+	if (HAS_PCH_SPLIT(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -683,7 +687,6 @@ static void intel_crt_reset(struct drm_connector *connector)
  */
 
 static const struct drm_encoder_helper_funcs crt_encoder_funcs = {
-	.mode_fixup = intel_crt_mode_fixup,
 	.mode_set = intel_crt_mode_set,
 };
 
@@ -774,6 +777,7 @@ void intel_crt_init(struct drm_device *dev)
 	else
 		crt->adpa_reg = ADPA;
 
+	crt->base.compute_config = intel_crt_compute_config;
 	crt->base.disable = intel_disable_crt;
 	crt->base.enable = intel_enable_crt;
 	if (HAS_DDI(dev))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fc95ef0..f5ae79f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1467,19 +1467,17 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
 	intel_dp_encoder_destroy(encoder);
 }
 
-static bool intel_ddi_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
+static bool intel_ddi_compute_config(struct intel_encoder *encoder,
+				     struct intel_crtc_config *pipe_config)
 {
-	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-	int type = intel_encoder->type;
+	int type = encoder->type;
 
-	WARN(type == INTEL_OUTPUT_UNKNOWN, "mode_fixup() on unknown output!\n");
+	WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
 
 	if (type == INTEL_OUTPUT_HDMI)
-		return intel_hdmi_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_hdmi_compute_config(encoder, pipe_config);
 	else
-		return intel_dp_mode_fixup(encoder, mode, adjusted_mode);
+		return intel_dp_compute_config(encoder, pipe_config);
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
@@ -1487,7 +1485,6 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
 };
 
 static const struct drm_encoder_helper_funcs intel_ddi_helper_funcs = {
-	.mode_fixup = intel_ddi_mode_fixup,
 	.mode_set = intel_ddi_mode_set,
 };
 
@@ -1527,6 +1524,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(encoder, &intel_ddi_helper_funcs);
 
+	intel_encoder->compute_config = intel_ddi_compute_config;
 	intel_encoder->enable = intel_enable_ddi;
 	intel_encoder->pre_enable = intel_ddi_pre_enable;
 	intel_encoder->disable = intel_disable_ddi;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e7cc17c..5ed3a9b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2947,27 +2947,6 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 	mutex_unlock(&dev->struct_mutex);
 }
 
-static bool ironlake_crtc_driving_pch(struct drm_crtc *crtc)
-{
-	struct drm_device *dev = crtc->dev;
-	struct intel_encoder *intel_encoder;
-
-	/*
-	 * If there's a non-PCH eDP on this crtc, it must be DP_A, and that
-	 * must be driven by its own crtc; no sharing is possible.
-	 */
-	for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
-		switch (intel_encoder->type) {
-		case INTEL_OUTPUT_EDP:
-			if (!intel_encoder_is_pch_edp(&intel_encoder->base))
-				return false;
-			continue;
-		}
-	}
-
-	return true;
-}
-
 static bool haswell_crtc_driving_pch(struct drm_crtc *crtc)
 {
 	return intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG);
@@ -3308,7 +3287,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	u32 temp;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3324,9 +3302,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 			I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
 	}
 
-	is_pch_port = ironlake_crtc_driving_pch(crtc);
 
-	if (is_pch_port) {
+	if (intel_crtc->config.has_pch_encoder) {
 		/* Note: FDI PLL enabling _must_ be done before we enable the
 		 * cpu pipes, hence this is separate from all the other fdi/pch
 		 * enabling. */
@@ -3363,10 +3340,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 	 */
 	intel_crtc_load_lut(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		ironlake_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
@@ -3400,7 +3378,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	struct intel_encoder *encoder;
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	bool is_pch_port;
 
 	WARN_ON(!crtc->enabled);
 
@@ -3410,9 +3387,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc->active = true;
 	intel_update_watermarks(dev);
 
-	is_pch_port = haswell_crtc_driving_pch(crtc);
-
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		dev_priv->display.fdi_link_train(crtc);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3443,10 +3418,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 	intel_ddi_set_pipe_settings(crtc);
 	intel_ddi_enable_pipe_func(crtc);
 
-	intel_enable_pipe(dev_priv, pipe, is_pch_port);
+	intel_enable_pipe(dev_priv, pipe,
+			  intel_crtc->config.has_pch_encoder);
 	intel_enable_plane(dev_priv, plane, pipe);
 
-	if (is_pch_port)
+	if (intel_crtc->config.has_pch_encoder)
 		lpt_pch_enable(crtc);
 
 	mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 9b1a969..4943187 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -689,12 +689,13 @@ intel_dp_i2c_init(struct intel_dp *intel_dp,
 }
 
 bool
-intel_dp_mode_fixup(struct drm_encoder *encoder,
-		    const struct drm_display_mode *mode,
-		    struct drm_display_mode *adjusted_mode)
+intel_dp_compute_config(struct intel_encoder *encoder,
+			struct intel_crtc_config *pipe_config)
 {
-	struct drm_device *dev = encoder->dev;
-	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->requested_mode;
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	int lane_count, clock;
 	int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
@@ -702,6 +703,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
 	int bpp, mode_rate;
 	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
+	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && !is_cpu_edp(intel_dp))
+		pipe_config->has_pch_encoder = true;
+
 	if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) {
 		intel_fixed_panel_mode(intel_connector->panel.fixed_mode,
 				       adjusted_mode);
@@ -2517,7 +2521,6 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
-	.mode_fixup = intel_dp_mode_fixup,
 	.mode_set = intel_dp_mode_set,
 };
 
@@ -2937,6 +2940,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_dp_helper_funcs);
 
+	intel_encoder->compute_config = intel_dp_compute_config;
 	intel_encoder->enable = intel_enable_dp;
 	intel_encoder->pre_enable = intel_pre_enable_dp;
 	intel_encoder->disable = intel_disable_dp;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ef5111b..6aecbccf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -189,6 +189,9 @@ struct intel_crtc_config {
 	 * changes the crtc timings in the mode to prevent the crtc fixup from
 	 * overwriting them.  Currently only lvds needs that. */
 	bool timings_set;
+	/* Whether to set up the PCH/FDI. Note that we never allow sharing
+	 * between pch encoders and cpu encoders. */
+	bool has_pch_encoder;
 	/* Used by SDVO (and if we ever fix it, HDMI). */
 	unsigned pixel_multiplier;
 };
@@ -444,9 +447,8 @@ extern void intel_hdmi_init(struct drm_device *dev,
 extern void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 				      struct intel_connector *intel_connector);
 extern struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
-extern bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-				  const struct drm_display_mode *mode,
-				  struct drm_display_mode *adjusted_mode);
+extern bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+				      struct intel_crtc_config *pipe_config);
 extern void intel_dip_infoframe_csum(struct dip_infoframe *avi_if);
 extern bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg,
 			    bool is_sdvob);
@@ -470,9 +472,8 @@ extern void intel_dp_complete_link_train(struct intel_dp *intel_dp);
 extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
 extern void intel_dp_encoder_destroy(struct drm_encoder *encoder);
 extern void intel_dp_check_link_status(struct intel_dp *intel_dp);
-extern bool intel_dp_mode_fixup(struct drm_encoder *encoder,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode);
+extern bool intel_dp_compute_config(struct intel_encoder *encoder,
+				    struct intel_crtc_config *pipe_config);
 extern bool intel_dpd_is_edp(struct drm_device *dev);
 extern void ironlake_edp_backlight_on(struct intel_dp *intel_dp);
 extern void ironlake_edp_backlight_off(struct intel_dp *intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 92aba3c..1c5bd47 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -772,11 +772,12 @@ static int intel_hdmi_mode_valid(struct drm_connector *connector,
 	return MODE_OK;
 }
 
-bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
-			   const struct drm_display_mode *mode,
-			   struct drm_display_mode *adjusted_mode)
+bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+			       struct intel_crtc_config *pipe_config)
 {
-	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_device *dev = encoder->base.dev;
+	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 
 	if (intel_hdmi->color_range_auto) {
 		/* See CEA-861-E - 5.1 Default Encoding Parameters */
@@ -790,6 +791,9 @@ bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 	if (intel_hdmi->color_range)
 		adjusted_mode->private_flags |= INTEL_MODE_LIMITED_COLOR_RANGE;
 
+	if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev))
+		pipe_config->has_pch_encoder = true;
+
 	return true;
 }
 
@@ -941,7 +945,6 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
-	.mode_fixup = intel_hdmi_mode_fixup,
 	.mode_set = intel_hdmi_mode_set,
 };
 
@@ -1069,6 +1072,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
 			 DRM_MODE_ENCODER_TMDS);
 	drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
 
+	intel_encoder->compute_config = intel_hdmi_compute_config;
 	intel_encoder->enable = intel_enable_hdmi;
 	intel_encoder->disable = intel_disable_hdmi;
 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 1616f53..1f2efac 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -331,6 +331,8 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 			       adjusted_mode);
 
 	if (HAS_PCH_SPLIT(dev)) {
+		pipe_config->has_pch_encoder = true;
+
 		intel_pch_panel_fitting(dev,
 					intel_connector->panel.fitting_mode,
 					mode, adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 3a45be0..7100196 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1045,6 +1045,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
 	struct drm_display_mode *mode = &pipe_config->requested_mode;
 
+	if (HAS_PCH_SPLIT(encoder->base.dev))
+		pipe_config->has_pch_encoder = true;
+
 	/* We need to construct preferred input timings based on our
 	 * output timings.  To do that, we have to set the output
 	 * timings, even though this isn't really the right place in
-- 
1.7.11.4

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

* Re: [PATCH 09/10] drm/i915: clean up plane bpp confusion
  2013-02-21 23:56 ` [PATCH 09/10] drm/i915: clean up plane bpp confusion Daniel Vetter
@ 2013-03-26 21:04   ` Jesse Barnes
  0 siblings, 0 replies; 31+ messages in thread
From: Jesse Barnes @ 2013-03-26 21:04 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

On Fri, 22 Feb 2013 00:56:53 +0100
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> - There is no 16bpc linear color format in our hw. gen4+ has a 16 bpc
>   float layout, but we don't really support it.
> - 10bpc is a gen4+ feature, fix up the support for it.
> - Update_plane should never see a wrong fb bpp value, BUG in the
>   corresponding cases.
> 
> v2: Rebase on top of Ville's plane pixel layout changes.
> 
> v3: Actually drop the old gen4 check for 10bpc planes, spotted
> by Ville Syrjälä.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 20 ++++++++------------
>  1 file changed, 8 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 04ae8ae..1258883 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2083,8 +2083,7 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
>  		dspcntr |= DISPPLANE_RGBX101010;
>  		break;
>  	default:
> -		DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
> -		return -EINVAL;
> +		BUG();
>  	}
>  
>  	if (INTEL_INFO(dev)->gen >= 4) {
> @@ -2177,8 +2176,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
>  		dspcntr |= DISPPLANE_RGBX101010;
>  		break;
>  	default:
> -		DRM_ERROR("Unknown pixel format 0x%08x\n", fb->pixel_format);
> -		return -EINVAL;
> +		BUG();
>  	}
>  
>  	if (obj->tiling_mode != I915_TILING_NONE)
> @@ -7347,21 +7345,19 @@ pipe_config_set_bpp(struct drm_crtc *crtc,
>  		bpp = 8*3;
>  		break;
>  	case 30:
> +		if (INTEL_INFO(dev)->gen < 4) {
> +			DRM_DEBUG_KMS("10 bpc not supported on gen2/3\n");
> +			return -EINVAL;
> +		}
> +
>  		bpp = 10*3;
>  		break;
> -	case 48:
> -		bpp = 12*3;
> -		break;
> +	/* TODO: gen4+ supports 16 bpc floating point, too. */
>  	default:
>  		DRM_DEBUG_KMS("unsupported depth\n");
>  		return -EINVAL;
>  	}
>  
> -	if (fb->depth > 24 && !HAS_PCH_SPLIT(dev)) {
> -		DRM_DEBUG_KMS("high depth not supported on gmch platforms\n");
> -		return -EINVAL;
> -	}
> -
>  	pipe_config->pipe_bpp = bpp;
>  
>  	/* Clamp display bpp to EDID value */

Why not squash this into the last one?  The "high depth not supported"
jumped out at me and I had to check the docs that it really is
supported.

For the 64 bit float mode, we just need some tests in i-g-t; shouldn't
be a big deal to expose it from the kernel even if commodity userspace
doesn't use it.

-- 
Jesse Barnes, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/10] drm/i915: clean up pipe bpp confusion
  2013-02-21 23:56 ` [PATCH 10/10] drm/i915: clean up pipe " Daniel Vetter
@ 2013-03-26 21:06   ` Jesse Barnes
  0 siblings, 0 replies; 31+ messages in thread
From: Jesse Barnes @ 2013-03-26 21:06 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

On Fri, 22 Feb 2013 00:56:54 +0100
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> - gen4 and earlier (save for g4x) only really have a 8bpc pipe, with
>   the possibility to dither to 6bpc using the panel fitter
> - g4x has hdmi, but no 12 bpc pipe ... !? Clamp hdmi accordingly.
> - TV/SDVO out are the only connectors available on platforms with
>   a pipe bpp != 8, add code to force the pipe to 8bpc unconditionally.
> 
> <rant>
> The dither handling on gmch platforms is one giant disaster. I'm hoping
> somewhat that vlv enabling will fix this up, but given that the 6bpc
> handling for edp was simply added with another quick hack, I don't have
> high hopes ...
> </rant>
> 
> v2: Neither vlv nor g4x have 12bpc pipes. Still set pipe_bpp to 12*3,
> but let the crtc code clamp things down to 10bpc on these platforms.
> 
> v3: Fix a bpc vs. bpp mixup in the gen4 and earlier pipe_bpp limiter
> code.
> 
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/i915/intel_display.c |  8 ++++++++
>  drivers/gpu/drm/i915/intel_hdmi.c    |  4 +++-
>  drivers/gpu/drm/i915/intel_sdvo.c    |  3 +++
>  drivers/gpu/drm/i915/intel_tv.c      | 14 ++++++++------
>  4 files changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 1258883..f1d47dd 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3914,6 +3914,14 @@ static bool intel_crtc_compute_config(struct drm_crtc *crtc,
>  		adjusted_mode->hsync_start == adjusted_mode->hdisplay)
>  		return false;
>  
> +	if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && pipe_config->pipe_bpp > 10) {
> +		pipe_config->pipe_bpp = 10*3; /* 12bpc is gen5+ */
> +	} else if (INTEL_INFO(dev)->gen <= 4 && pipe_config->pipe_bpp > 8) {
> +		/* only a 8bpc pipe, with 6bpc dither through the panel fitter
> +		 * for lvds. */
> +		pipe_config->pipe_bpp = 8*3;
> +	}
> +
>  	return true;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 47d3a21..0e51b2b 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -797,7 +797,9 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
>  
>  	/*
>  	 * HDMI is either 12 or 8, so if the display lets 10bpc sneak
> -	 * through, clamp it down.
> +	 * through, clamp it down. Note that only pch_split platforms have 12bpc
> +	 * pipes, g4x and vlv only has a 10bpc pipe, all earlier platforms have
> +	 * only 8bpc.
>  	 */
>  	if (pipe_config->pipe_bpp > 8*3) {
>  		DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n");
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 59a6781..a443086 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -1046,6 +1046,9 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
>  	struct drm_display_mode *mode = &pipe_config->requested_mode;
>  
> +	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
> +	pipe_config->pipe_bpp = 8*3;
> +
>  	if (HAS_PCH_SPLIT(encoder->base.dev))
>  		pipe_config->has_pch_encoder = true;
>  
> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> index d808421..6673726 100644
> --- a/drivers/gpu/drm/i915/intel_tv.c
> +++ b/drivers/gpu/drm/i915/intel_tv.c
> @@ -905,11 +905,10 @@ intel_tv_mode_valid(struct drm_connector *connector,
>  
>  
>  static bool
> -intel_tv_mode_fixup(struct drm_encoder *encoder,
> -		    const struct drm_display_mode *mode,
> -		    struct drm_display_mode *adjusted_mode)
> +intel_tv_compute_config(struct intel_encoder *encoder,
> +			struct intel_crtc_config *pipe_config)
>  {
> -	struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
> +	struct intel_tv *intel_tv = enc_to_intel_tv(&encoder->base);
>  	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
>  
>  	if (!tv_mode)
> @@ -918,7 +917,10 @@ intel_tv_mode_fixup(struct drm_encoder *encoder,
>  	if (intel_encoder_check_is_cloned(&intel_tv->base))
>  		return false;
>  
> -	adjusted_mode->clock = tv_mode->clock;
> +	pipe_config->adjusted_mode.clock = tv_mode->clock;
> +	DRM_DEBUG_KMS("forcing bpc to 8 for TV\n");
> +	pipe_config->pipe_bpp = 8*3;
> +
>  	return true;
>  }
>  
> @@ -1485,7 +1487,6 @@ out:
>  }
>  
>  static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
> -	.mode_fixup = intel_tv_mode_fixup,
>  	.mode_set = intel_tv_mode_set,
>  };
>  
> @@ -1620,6 +1621,7 @@ intel_tv_init(struct drm_device *dev)
>  	drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
>  			 DRM_MODE_ENCODER_TVDAC);
>  
> +	intel_encoder->compute_config = intel_tv_compute_config;
>  	intel_encoder->enable = intel_enable_tv;
>  	intel_encoder->disable = intel_disable_tv;
>  	intel_encoder->get_hw_state = intel_tv_get_hw_state;

Yeah looks good.

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config
  2013-02-21 23:56 ` [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config Daniel Vetter
@ 2013-03-26 21:12   ` Jesse Barnes
  2013-03-26 21:32     ` Daniel Vetter
  0 siblings, 1 reply; 31+ messages in thread
From: Jesse Barnes @ 2013-03-26 21:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel Graphics Development

On Fri, 22 Feb 2013 00:56:52 +0100
Daniel Vetter <daniel.vetter@ffwll.ch> wrote:

> The procedure has now 3 steps:
> 
> 1. Compute the bpp that the plane will output, this is done in
>    pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
>    this function clamps the pipe_bpp to whatever limit the EDID of any
>    connected output specifies.
> 2. Adjust the pipe_bpp in the encoder and crtc functions, according to
>    whatever constraints there are.
> 3. Decide whether to use dither by comparing the stored plane bpp with
>    computed pipe_bpp.
> 
> There are a few slight functional changes in this patch:
> - LVDS connector are now also going through the EDID clamping. But in
>   a 2nd change we now unconditionally force the lvds bpc value - this
>   shouldn't matter in reality when the panel setup is consistent, but
>   better safe than sorry.
> - HDMI now forces the pipe_bpp to the selected value - I think that's
>   what we actually want, since otherwise at least the pixelclock
>   computations are wrong (I'm not sure whether the port would accept
>   e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
>   the next higher bpc value, since otherwise there's no way to make
>   use of the 12 bpc mode (since the next patch will remove the 12bpc
>   plane format, it doesn't exist).
> 

This is a big patch; maybe there's a reasonable way to split it up?
Maybe by leaving the _FORCE_6BPC flag in then removing in a second
patch?  May as well squash in 9/10 while you're at it, since it mainly
affects the new function.

I wonder if we want a pipe_dither and a connector_dither flag too?
On Cantiga, we can dither either at LVDS or in the pipe for example.
Not sure which is better...

And as usual, we need better tests for this stuff.  The color ramps in
testdisplay should show artifacts if we get the dithering wrong, but we
could probably improve it.

Otherwise this mostly looks good.  I definitely like the direction.

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config
  2013-03-26 21:12   ` Jesse Barnes
@ 2013-03-26 21:32     ` Daniel Vetter
  0 siblings, 0 replies; 31+ messages in thread
From: Daniel Vetter @ 2013-03-26 21:32 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Daniel Vetter, Intel Graphics Development

On Tue, Mar 26, 2013 at 02:12:39PM -0700, Jesse Barnes wrote:
> On Fri, 22 Feb 2013 00:56:52 +0100
> Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> 
> > The procedure has now 3 steps:
> > 
> > 1. Compute the bpp that the plane will output, this is done in
> >    pipe_config_set_bpp and stored into pipe_config->pipe_bpp. Also,
> >    this function clamps the pipe_bpp to whatever limit the EDID of any
> >    connected output specifies.
> > 2. Adjust the pipe_bpp in the encoder and crtc functions, according to
> >    whatever constraints there are.
> > 3. Decide whether to use dither by comparing the stored plane bpp with
> >    computed pipe_bpp.
> > 
> > There are a few slight functional changes in this patch:
> > - LVDS connector are now also going through the EDID clamping. But in
> >   a 2nd change we now unconditionally force the lvds bpc value - this
> >   shouldn't matter in reality when the panel setup is consistent, but
> >   better safe than sorry.
> > - HDMI now forces the pipe_bpp to the selected value - I think that's
> >   what we actually want, since otherwise at least the pixelclock
> >   computations are wrong (I'm not sure whether the port would accept
> >   e.g. 10 bpc when in 12bpc mode). Contrary to the old code, we pick
> >   the next higher bpc value, since otherwise there's no way to make
> >   use of the 12 bpc mode (since the next patch will remove the 12bpc
> >   plane format, it doesn't exist).
> > 
> 
> This is a big patch; maybe there's a reasonable way to split it up?
> Maybe by leaving the _FORCE_6BPC flag in then removing in a second
> patch?  May as well squash in 9/10 while you're at it, since it mainly
> affects the new function.

FORCE_6BPC is just the DP encoder's way to communicate bpp requirements,
so I've figured I might as well include it. Looking at the patch again I
admit it's pretty big, so I'll try to smash it into pieces. Should be
doable from a quick look.

> I wonder if we want a pipe_dither and a connector_dither flag too?
> On Cantiga, we can dither either at LVDS or in the pipe for example.
> Not sure which is better...

I've thought that the lvds dither flag in the port disappeared with the
appearance of the pipe dither modes. Might be wrong though, but I think
I've completely check all docs covering that range (i.e. gen3-cantiga).

The only place where we have 2 dither bits is on pch ports (one on the cpu
transcoder, one in the pch transcoder). But imo it doesn't make much sense
to dither down/up in two steps, so we should be fine with just one flag.

The only case I've come up with is a 8bpc panel which _requires_ 8bpc (the
apple retina are like that iirc), and we try to feed it a 16bpp plane.
Then it would make sense to shovel 6bpc over the fdi link and up-dither to
8bpc on the pch.

But since that'll only happen with a desktop/all-in-one eDP config, who
cares. And if your driving your expensive 8bpc edp panel at 6bpc, you're
doing it wrong anyway.

> And as usual, we need better tests for this stuff.  The color ramps in
> testdisplay should show artifacts if we get the dithering wrong, but we
> could probably improve it.

My self-imposed merge criterion for the bpp fixes (an entire pile of
follow-up patches) is that I want to improve testdisplay to also test the
different pixel depths. And it needs testing (10bpc screen is on order).

But that part of the pipe_config rework is pretty orthogonal (imo the dp
unconfusion part is more important to get things going), so can wait.

> Otherwise this mostly looks good.  I definitely like the direction.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

end of thread, other threads:[~2013-03-26 21:30 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-21 23:56 [PATCH 00/10] basic infrastructure for pipe_config Daniel Vetter
2013-02-21 23:56 ` [PATCH 01/10] drm/i915: introduce struct intel_crtc_config Daniel Vetter
2013-02-22 10:23   ` Ville Syrjälä
2013-02-22 11:05   ` [PATCH] " Daniel Vetter
2013-02-26 17:09     ` Paulo Zanoni
2013-02-21 23:56 ` [PATCH 02/10] drm/i915: compute pipe_config earlier Daniel Vetter
2013-02-26 17:11   ` Paulo Zanoni
2013-02-21 23:56 ` [PATCH 03/10] drm/i915: add pipe_config->timings_set Daniel Vetter
2013-02-22 13:51   ` Ville Syrjälä
2013-03-03 18:01     ` Daniel Vetter
2013-03-04 14:18       ` Ville Syrjälä
2013-02-26 17:23   ` Paulo Zanoni
2013-03-03 17:58     ` Daniel Vetter
2013-02-21 23:56 ` [PATCH 04/10] drm/i915: add pipe_config->pixel_multiplier Daniel Vetter
2013-02-26 17:27   ` Paulo Zanoni
2013-03-03 18:05     ` Daniel Vetter
2013-02-21 23:56 ` [PATCH 05/10] drm/i915: drop helper vtable for sdvo encoder Daniel Vetter
2013-02-21 23:56 ` [PATCH 06/10] drm/i915: add pipe_config->has_pch_encoder Daniel Vetter
2013-02-26 17:39   ` Paulo Zanoni
2013-03-03 18:13     ` Daniel Vetter
2013-03-03 18:16       ` [PATCH] " Daniel Vetter
2013-03-04 22:24       ` Daniel Vetter
2013-02-21 23:56 ` [PATCH 07/10] drm/i915: add pipe_config->limited_color_range Daniel Vetter
2013-02-26 17:46   ` Paulo Zanoni
2013-02-21 23:56 ` [PATCH 08/10] drm/i915: move pipe bpp computation to pipe_config Daniel Vetter
2013-03-26 21:12   ` Jesse Barnes
2013-03-26 21:32     ` Daniel Vetter
2013-02-21 23:56 ` [PATCH 09/10] drm/i915: clean up plane bpp confusion Daniel Vetter
2013-03-26 21:04   ` Jesse Barnes
2013-02-21 23:56 ` [PATCH 10/10] drm/i915: clean up pipe " Daniel Vetter
2013-03-26 21:06   ` Jesse Barnes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).