All of lore.kernel.org
 help / color / mirror / Atom feed
* Fastboot in 6 patches
@ 2013-05-15  0:08 Jesse Barnes
  2013-05-15  0:08 ` [PATCH 1/6] drm/i915: add encoder get_config function v5 Jesse Barnes
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

It grew a little...  but there's only one real hack left, and that's the
PFIT bits.  To fix that properly, I think either we need to pull the
compute_config calls out of set_mode and into its callers so we can
compare pfit state, or something more ambitious where we collect all the
new configs up front and then let set_mode figure out how to apply it
minimally to hw.

Hopefully the other patches are pretty close to being ready though...

Thanks,
Jesse

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

* [PATCH 1/6] drm/i915: add encoder get_config function v5
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-15 21:45   ` Paulo Zanoni
  2013-05-15  0:08 ` [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5 Jesse Barnes
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

We can use this for fetching encoder specific pipe_config state, like
mode flags, adjusted clock, etc.

Just used for mode flags atm, so we can check the pipe config state at
mode set time.

v2: get_config when checking hw state too
v3: fix DVO and LVDS mode flags (Ville)
    get SDVO DTD for flag fetch (Ville)
v4: use input timings (Ville)
    correct command used (Ville)
    remove gen4 check (Ville)
v5: get DDI flag config too

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_crt.c     |   23 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_ddi.c     |   23 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |   20 +++++++++++++---
 drivers/gpu/drm/i915/intel_dp.c      |   23 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h     |    4 ++++
 drivers/gpu/drm/i915/intel_dvo.c     |   21 +++++++++++++++++
 drivers/gpu/drm/i915/intel_hdmi.c    |   23 +++++++++++++++++++
 drivers/gpu/drm/i915/intel_lvds.c    |   26 +++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sdvo.c    |   42 ++++++++++++++++++++++++++++++++++
 9 files changed, 202 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index cc414f1..789c4ef 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_crt_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crt *crt = intel_encoder_to_crt(encoder);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(crt->adpa_reg);
+
+	if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_crt(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev)
 	crt->base.compute_config = intel_crt_compute_config;
 	crt->base.disable = intel_disable_crt;
 	crt->base.enable = intel_enable_crt;
+	crt->base.get_config = intel_crt_get_config;
 	if (I915_HAS_HOTPLUG(dev))
 		crt->base.hpd_pin = HPD_CRT;
 	if (HAS_DDI(dev))
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index cddcf4a..27a74a9 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
 		intel_dp_check_link_status(intel_dp);
 }
 
+static void intel_ddi_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+	u32 temp, flags = 0;
+
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (temp & TRANS_DDI_PHSYNC)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (temp & TRANS_DDI_PVSYNC)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
+}
+
 static void intel_ddi_destroy(struct drm_encoder *encoder)
 {
 	/* HDMI has nothing special to destroy, so we can go with this. */
@@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
 	intel_encoder->disable = intel_disable_ddi;
 	intel_encoder->post_disable = intel_ddi_post_disable;
 	intel_encoder->get_hw_state = intel_ddi_get_hw_state;
+	intel_encoder->get_config = intel_ddi_get_config;
 
 	intel_dig_port->port = port;
 	intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7358e4e..163b97e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev,
 	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
 			      DRM_MODE_FLAG_INTERLACE);
 
+	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+			      DRM_MODE_FLAG_PHSYNC);
+	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+			      DRM_MODE_FLAG_NHSYNC);
+	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+			      DRM_MODE_FLAG_PVSYNC);
+	PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
+			      DRM_MODE_FLAG_NVSYNC);
+
 	PIPE_CONF_CHECK_I(requested_mode.hdisplay);
 	PIPE_CONF_CHECK_I(requested_mode.vdisplay);
 
@@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev)
 		bool enabled = false;
 		bool active = false;
 
+		memset(&pipe_config, 0, sizeof(pipe_config));
+
 		DRM_DEBUG_KMS("[CRTC:%d]\n",
 			      crtc->base.base.id);
 
@@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev)
 			enabled = true;
 			if (encoder->connectors_active)
 				active = true;
+			if (encoder->get_config)
+				encoder->get_config(encoder, &pipe_config);
 		}
 		WARN(active != crtc->active,
 		     "crtc's computed active state doesn't match tracked active state "
@@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev)
 		     "crtc's computed enabled state doesn't match tracked enabled state "
 		     "(expected %i, found %i)\n", enabled, crtc->base.enabled);
 
-		memset(&pipe_config, 0, sizeof(pipe_config));
 		pipe_config.cpu_transcoder = crtc->config.cpu_transcoder;
 		active = dev_priv->display.get_pipe_config(crtc,
 							   &pipe_config);
@@ -9579,8 +9591,10 @@ setup_pipes:
 		pipe = 0;
 
 		if (encoder->get_hw_state(encoder, &pipe)) {
-			encoder->base.crtc =
-				dev_priv->pipe_to_crtc_mapping[pipe];
+			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+			encoder->base.crtc = &crtc->base;
+			if (encoder->get_config)
+				encoder->get_config(encoder, &crtc->config);
 		} else {
 			encoder->base.crtc = NULL;
 		}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2bb4009..a423256 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_dp_get_config(struct intel_encoder *encoder,
+				struct intel_crtc_config *pipe_config)
+{
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_dp->output_reg);
+
+	if (tmp & DP_SYNC_HS_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & DP_SYNC_VS_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_dp(struct intel_encoder *encoder)
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
@@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
 	intel_encoder->disable = intel_disable_dp;
 	intel_encoder->post_disable = intel_post_disable_dp;
 	intel_encoder->get_hw_state = intel_dp_get_hw_state;
+	intel_encoder->get_config = intel_dp_get_config;
 	if (IS_VALLEYVIEW(dev))
 		intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0f35545..4802483 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -139,6 +139,10 @@ struct intel_encoder {
 	 * the encoder is active. If the encoder is enabled it also set the pipe
 	 * it is connected to in the pipe parameter. */
 	bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
+	/* Reconstructs the equivalent mode flags for the current hardware
+	 * state. */
+	void (*get_config)(struct intel_encoder *,
+			   struct intel_crtc_config *pipe_config);
 	int crtc_mask;
 	enum hpd_pin hpd_pin;
 };
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 00e70db..91e9905 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_dvo_get_config(struct intel_encoder *encoder,
+				 struct intel_crtc_config *pipe_config)
+{
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_dvo->dev.dvo_reg);
+	if (tmp & DVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	if (tmp & DVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_dvo(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev)
 	intel_encoder->disable = intel_disable_dvo;
 	intel_encoder->enable = intel_enable_dvo;
 	intel_encoder->get_hw_state = intel_dvo_get_hw_state;
+	intel_encoder->get_config = intel_dvo_get_config;
 	intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
 
 	/* Now, try to find a controller */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 93de5ff..9091655 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_hdmi_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_config *pipe_config)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+	u32 tmp, flags = 0;
+
+	tmp = I915_READ(intel_hdmi->hdmi_reg);
+
+	if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_enable_hdmi(struct intel_encoder *encoder)
 {
 	struct drm_device *dev = encoder->base.dev;
@@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
 	intel_encoder->enable = intel_enable_hdmi;
 	intel_encoder->disable = intel_disable_hdmi;
 	intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
+	intel_encoder->get_config = intel_hdmi_get_config;
 	if (IS_VALLEYVIEW(dev)) {
 		intel_encoder->pre_enable = intel_hdmi_pre_enable;
 		intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 36fe291..6554860 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_lvds_get_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;
+	u32 lvds_reg, tmp, flags = 0;
+
+	if (HAS_PCH_SPLIT(dev))
+		lvds_reg = PCH_LVDS;
+	else
+		lvds_reg = LVDS;
+
+	tmp = I915_READ(lvds_reg);
+	if (tmp & LVDS_HSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	if (tmp & LVDS_VSYNC_POLARITY)
+		flags |= DRM_MODE_FLAG_NVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_PVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
  * This is an exception to the general rule that mode_set doesn't turn
  * things on.
@@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev)
 	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_encoder->get_config = intel_lvds_get_config;
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 	intel_connector_attach_encoder(intel_connector, intel_encoder);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 2f54dc3..416d23c 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
 		intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
 }
 
+static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
+				  struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
+		intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+}
+
 static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
 					 struct intel_sdvo_dtd *dtd)
 {
@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
 				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
+static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
+					struct intel_sdvo_dtd *dtd)
+{
+	return intel_sdvo_get_timing(intel_sdvo,
+				     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
+}
+
 static bool
 intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
 					 uint16_t clock,
@@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
 	return true;
 }
 
+static void intel_sdvo_get_config(struct intel_encoder *encoder,
+				  struct intel_crtc_config *pipe_config)
+{
+	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
+	struct intel_sdvo_dtd dtd;
+	u32 flags = 0;
+	bool ret;
+
+	ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
+	if (!ret) {
+		DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
+		return;
+	}
+
+	if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	pipe_config->adjusted_mode.flags |= flags;
+}
+
 static void intel_disable_sdvo(struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
 	intel_encoder->mode_set = intel_sdvo_mode_set;
 	intel_encoder->enable = intel_enable_sdvo;
 	intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
+	intel_encoder->get_config = intel_sdvo_get_config;
 
 	/* In default case sdvo lvds is false */
 	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
-- 
1.7.9.5

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

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

* [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
  2013-05-15  0:08 ` [PATCH 1/6] drm/i915: add encoder get_config function v5 Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-23 15:30   ` Daniel Vetter
  2013-05-15  0:08 ` [PATCH 3/6] drm/i915: copy fetched mode state into crtc at setup_hw time v2 Jesse Barnes
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

We need this for comparing modes between configuration changes.

v2: try harder to calulate non-simple pixel clocks (Daniel)
    call get_clock after getting the encoder config, needed for pixel multiply
    (Jesse)
v3: drop get_clock now that the pixel_multiply has been moved into
    get_pipe_config
v4: re-add get_clock; we need to get the pixel multiplier in the
    encoder, so need to calculate the clock value after the encoder's
    get_config is called
v5: drop hsw clock_get, still needs to be written

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_crt.c     |    1 +
 drivers/gpu/drm/i915/intel_display.c |   78 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_dp.c      |    8 ++++
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++
 drivers/gpu/drm/i915/intel_dvo.c     |    1 +
 drivers/gpu/drm/i915/intel_hdmi.c    |    1 +
 drivers/gpu/drm/i915/intel_lvds.c    |    1 +
 drivers/gpu/drm/i915/intel_sdvo.c    |   24 +++++++++++
 9 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 14817de..2e284bb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -323,6 +323,7 @@ struct drm_i915_display_funcs {
 	 * fills out the pipe-config with the hw state. */
 	bool (*get_pipe_config)(struct intel_crtc *,
 				struct intel_crtc_config *);
+	void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *);
 	int (*crtc_mode_set)(struct drm_crtc *crtc,
 			     int x, int y,
 			     struct drm_framebuffer *old_fb);
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 789c4ef..bd91e72 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -101,6 +101,7 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
 }
 
 static void intel_disable_crt(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 163b97e..356404c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -45,6 +45,11 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
 static void intel_increase_pllclock(struct drm_crtc *crtc);
 static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
 
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
+				struct intel_crtc_config *pipe_config);
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
+				    struct intel_crtc_config *pipe_config);
+
 typedef struct {
 	int	min, max;
 } intel_range_t;
@@ -6906,11 +6911,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
 }
 
 /* Returns the clock of the currently programmed mode of the given pipe. */
-static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
+				struct intel_crtc_config *pipe_config)
 {
+	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	int pipe = intel_crtc->pipe;
+	int pipe = pipe_config->cpu_transcoder;
 	u32 dpll = I915_READ(DPLL(pipe));
 	u32 fp;
 	intel_clock_t clock;
@@ -6949,7 +6955,8 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
 		default:
 			DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
 				  "mode\n", (int)(dpll & DPLL_MODE_MASK));
-			return 0;
+			pipe_config->adjusted_mode.clock = 0;
+			return;
 		}
 
 		/* XXX: Handle the 100Mhz refclk */
@@ -6988,8 +6995,54 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
 	 * i830PllIsValid() because it relies on the xf86_config connector
 	 * configuration being accurate, which it isn't necessarily.
 	 */
+	pipe_config->adjusted_mode.clock = clock.dot;
+}
+
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
+				    struct intel_crtc_config *pipe_config)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+	int link_freq, repeat;
+	u64 clock;
+	u32 link_m, link_n;
 
-	return clock.dot;
+	repeat = pipe_config->pixel_multiplier;
+
+	/*
+	 * The calculation for the data clock is:
+	 * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp
+	 * But we want to avoid losing precison if possible, so:
+	 * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp))
+	 *
+	 * and the link clock is simpler:
+	 * link_clock = (m * link_clock * repeat) / n
+	 */
+
+	/*
+	 * We need to get the FDI or DP link clock here to derive
+	 * the M/N dividers.
+	 *
+	 * For FDI, we read it from the BIOS or use a fixed 2.7GHz.
+	 * For DP, it's either 1.62GHz or 2.7GHz.
+	 * We do our calculations in 10*MHz since we don't need much precison.
+	 */
+	if (pipe_config->has_pch_encoder)
+		link_freq = intel_fdi_link_freq(dev) * 10000;
+	else
+		link_freq = pipe_config->cpu_edp_link_rate;
+
+	link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder));
+	link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder));
+
+	if (!link_m || !link_n)
+		return;
+
+	clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
+	do_div(clock, link_n);
+
+	pipe_config->adjusted_mode.clock = clock;
 }
 
 /** Returns the currently programmed mode of the given pipe. */
@@ -7000,6 +7053,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
 	struct drm_display_mode *mode;
+	struct intel_crtc_config pipe_config;
 	int htot = I915_READ(HTOTAL(cpu_transcoder));
 	int hsync = I915_READ(HSYNC(cpu_transcoder));
 	int vtot = I915_READ(VTOTAL(cpu_transcoder));
@@ -7009,7 +7063,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 	if (!mode)
 		return NULL;
 
-	mode->clock = intel_crtc_clock_get(dev, crtc);
+	pipe_config.cpu_transcoder = intel_crtc->pipe;
+	i9xx_crtc_clock_get(intel_crtc, &pipe_config);
+
+	mode->clock = pipe_config.adjusted_mode.clock;
 	mode->hdisplay = (htot & 0xffff) + 1;
 	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
 	mode->hsync_start = (hsync & 0xffff) + 1;
@@ -9011,6 +9068,7 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = ironlake_update_plane;
 	} else if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
+		dev_priv->display.get_clock = ironlake_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
 		dev_priv->display.crtc_enable = ironlake_crtc_enable;
 		dev_priv->display.crtc_disable = ironlake_crtc_disable;
@@ -9018,6 +9076,7 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = ironlake_update_plane;
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_clock = i9xx_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
 		dev_priv->display.crtc_enable = valleyview_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -9025,6 +9084,7 @@ static void intel_init_display(struct drm_device *dev)
 		dev_priv->display.update_plane = i9xx_update_plane;
 	} else {
 		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
+		dev_priv->display.get_clock = i9xx_crtc_clock_get;
 		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
 		dev_priv->display.crtc_enable = i9xx_crtc_enable;
 		dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@ -9593,8 +9653,12 @@ setup_pipes:
 		if (encoder->get_hw_state(encoder, &pipe)) {
 			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
 			encoder->base.crtc = &crtc->base;
-			if (encoder->get_config)
+			if (encoder->get_config &&
+			    dev_priv->display.get_clock) {
 				encoder->get_config(encoder, &crtc->config);
+				dev_priv->display.get_clock(crtc,
+							    &crtc->config);
+			}
 		} else {
 			encoder->base.crtc = NULL;
 		}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a423256..c32429d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1376,6 +1376,14 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
+
+	if (is_cpu_edp(intel_dp)) {
+		if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
+			pipe_config->cpu_edp_link_rate = 162000;
+		else
+			pipe_config->cpu_edp_link_rate = 270000;
+	}
 }
 
 static void intel_disable_dp(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4802483..a7c9293 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -268,6 +268,9 @@ struct intel_crtc_config {
 	/* FDI configuration, only valid if has_pch_encoder is set. */
 	int fdi_lanes;
 	struct intel_link_m_n fdi_m_n;
+
+	/* CPU eDP config */
+	int cpu_edp_link_rate;
 };
 
 struct intel_crtc {
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 91e9905..d020a9c 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -147,6 +147,7 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
 }
 
 static void intel_disable_dvo(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 9091655..7b55a8a 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -678,6 +678,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
 }
 
 static void intel_enable_hdmi(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6554860..f0cbb02 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -109,6 +109,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_PVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+	pipe_config->pixel_multiplier = 1;
 }
 
 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 416d23c..ee7f0ab 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -780,6 +780,11 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val
 	return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
 }
 
+static bool intel_sdvo_get_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 *val)
+{
+	return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1);
+}
+
 static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
 					 const struct drm_display_mode *mode)
 {
@@ -1315,6 +1320,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
 	struct intel_sdvo_dtd dtd;
 	u32 flags = 0;
+	u8 val;
 	bool ret;
 
 	ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
@@ -1334,6 +1340,24 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
 	pipe_config->adjusted_mode.flags |= flags;
+
+	ret = intel_sdvo_get_clock_rate_mult(intel_sdvo, &val);
+	if (!ret) {
+		DRM_DEBUG_DRIVER("failed to retrieve clock rate multiplier\n");
+		return;
+	}
+
+	switch (val) {
+	case SDVO_CLOCK_RATE_MULT_1X:
+		pipe_config->pixel_multiplier = 1;
+		break;
+	case SDVO_CLOCK_RATE_MULT_2X:
+		pipe_config->pixel_multiplier = 2;
+		break;
+	case SDVO_CLOCK_RATE_MULT_4X:
+		pipe_config->pixel_multiplier = 4;
+		break;
+	}
 }
 
 static void intel_disable_sdvo(struct intel_encoder *encoder)
-- 
1.7.9.5

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

* [PATCH 3/6] drm/i915: copy fetched mode state into crtc at setup_hw time v2
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
  2013-05-15  0:08 ` [PATCH 1/6] drm/i915: add encoder get_config function v5 Jesse Barnes
  2013-05-15  0:08 ` [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5 Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-15  0:08 ` [PATCH 4/6] drm/i915: fetch PCH PLL state at init time v3 Jesse Barnes
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

We already fetch and track other state into the main CRTC and encoder
structs, and for fastboot we need to do the same with the mode and clock
data we read out.

v2: fix debug print

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 356404c..604f538 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4788,6 +4788,24 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
 	pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
 }
 
+static void intel_pipe_config_to_crtc(struct intel_crtc *intel_crtc,
+				      struct intel_crtc_config *pipe_config)
+{
+	struct drm_crtc *crtc = &intel_crtc->base;
+
+	crtc->mode.hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
+	crtc->mode.htotal = pipe_config->adjusted_mode.crtc_htotal;
+	crtc->mode.hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
+	crtc->mode.hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
+
+	crtc->mode.vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
+	crtc->mode.vtotal = pipe_config->adjusted_mode.crtc_vtotal;
+	crtc->mode.vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
+	crtc->mode.vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
+
+	crtc->mode.flags = pipe_config->adjusted_mode.flags;
+}
+
 static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
@@ -9638,6 +9656,14 @@ setup_pipes:
 
 		crtc->base.enabled = crtc->active;
 
+		if (crtc->active) {
+			intel_pipe_config_to_crtc(crtc, &crtc->config);
+
+			DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
+				      crtc->base.base.id);
+			drm_mode_debug_printmodeline(&crtc->base.mode);
+		}
+
 		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
 			      crtc->base.base.id,
 			      crtc->active ? "enabled" : "disabled");
@@ -9658,6 +9684,10 @@ setup_pipes:
 				encoder->get_config(encoder, &crtc->config);
 				dev_priv->display.get_clock(crtc,
 							    &crtc->config);
+				crtc->base.mode.clock =
+					crtc->config.adjusted_mode.clock;
+				crtc->base.mode.flags |=
+					crtc->config.adjusted_mode.flags;
 			}
 		} else {
 			encoder->base.crtc = NULL;
-- 
1.7.9.5

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

* [PATCH 4/6] drm/i915: fetch PCH PLL state at init time v3
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
                   ` (2 preceding siblings ...)
  2013-05-15  0:08 ` [PATCH 3/6] drm/i915: copy fetched mode state into crtc at setup_hw time v2 Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-15  0:08 ` [PATCH 5/6] HACK: drm/i915: turn off panel fitting at flip time if needed Jesse Barnes
  2013-05-15  0:08 ` [PATCH 6/6] drm/i915: flip on a no fb -> fb transition if crtc is active v2 Jesse Barnes
  5 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

We need to properly track PCH PLL sharing configs, and generally set up
PCH PLL state at init time as part of the state readout process.

v2: update to new code, use intel_crtc instead (Jesse)
v3: move pll_get call to setup_hw_state (Daniel)

I-told-you-so-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   45 ++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 604f538..d03b6b0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7016,6 +7016,49 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 	pipe_config->adjusted_mode.clock = clock.dot;
 }
 
+static void ironlake_crtc_pll_get(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dpll_sel;
+
+	if (HAS_PCH_IBX(dev_priv->dev))
+		crtc->pch_pll = &dev_priv->pch_plls[crtc->pipe];
+
+	if (HAS_PCH_CPT(dev_priv->dev)) {
+		dpll_sel = I915_READ(PCH_DPLL_SEL);
+
+		switch (crtc->pipe) {
+		case PIPE_A:
+			if ((dpll_sel & TRANSA_DPLL_ENABLE) &&
+			    (dpll_sel & TRANSA_DPLLB_SEL))
+				crtc->pch_pll = &dev_priv->pch_plls[1];
+			else if (dpll_sel & TRANSA_DPLL_ENABLE)
+				crtc->pch_pll = &dev_priv->pch_plls[0];
+			break;
+		case PIPE_B:
+			if ((dpll_sel & TRANSB_DPLL_ENABLE) &&
+			    (dpll_sel & TRANSB_DPLLB_SEL))
+				crtc->pch_pll = &dev_priv->pch_plls[1];
+			else if (dpll_sel & TRANSB_DPLL_ENABLE)
+				crtc->pch_pll = &dev_priv->pch_plls[0];
+			break;
+		case PIPE_C:
+			if ((dpll_sel & TRANSC_DPLL_ENABLE) &&
+			    (dpll_sel & TRANSC_DPLLB_SEL))
+				crtc->pch_pll = &dev_priv->pch_plls[1];
+			else if (dpll_sel & TRANSC_DPLL_ENABLE)
+				crtc->pch_pll = &dev_priv->pch_plls[0];
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	crtc->pch_pll->refcount++;
+	crtc->pch_pll->active = 1;
+}
+
 static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
 				    struct intel_crtc_config *pipe_config)
 {
@@ -9684,6 +9727,8 @@ setup_pipes:
 				encoder->get_config(encoder, &crtc->config);
 				dev_priv->display.get_clock(crtc,
 							    &crtc->config);
+				if (HAS_PCH_SPLIT(dev))
+					ironlake_crtc_pll_get(crtc);
 				crtc->base.mode.clock =
 					crtc->config.adjusted_mode.clock;
 				crtc->base.mode.flags |=
-- 
1.7.9.5

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

* [PATCH 5/6] HACK: drm/i915: turn off panel fitting at flip time if needed
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
                   ` (3 preceding siblings ...)
  2013-05-15  0:08 ` [PATCH 4/6] drm/i915: fetch PCH PLL state at init time v3 Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-15  0:08 ` [PATCH 6/6] drm/i915: flip on a no fb -> fb transition if crtc is active v2 Jesse Barnes
  5 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

Need better pfit tracking to do this right.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d03b6b0..150ace6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2301,6 +2301,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		return ret;
 	}
 
+	/* Update pipe size and adjust fitter if needed */
+	I915_WRITE(PIPESRC(intel_crtc->pipe),
+		   ((crtc->mode.hdisplay - 1) << 16) |
+		   (crtc->mode.vdisplay - 1));
+	if (!intel_crtc->config.pch_pfit.size &&
+	    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
+	     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
+		I915_WRITE(PF_CTL(intel_crtc->pipe), 0);
+		I915_WRITE(PF_WIN_POS(intel_crtc->pipe), 0);
+		I915_WRITE(PF_WIN_SZ(intel_crtc->pipe), 0);
+	}
+
 	ret = dev_priv->display.update_plane(crtc, fb, x, y);
 	if (ret) {
 		intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
-- 
1.7.9.5

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

* [PATCH 6/6] drm/i915: flip on a no fb -> fb transition if crtc is active v2
  2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
                   ` (4 preceding siblings ...)
  2013-05-15  0:08 ` [PATCH 5/6] HACK: drm/i915: turn off panel fitting at flip time if needed Jesse Barnes
@ 2013-05-15  0:08 ` Jesse Barnes
  2013-05-23 21:23   ` [PATCH] drm/i915: flip on a no fb -> fb transition if crtc is active v3 Jesse Barnes
  5 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2013-05-15  0:08 UTC (permalink / raw)
  To: intel-gfx

If the crtc is active, we can simply flip a new fb onto it, provided the
other mode setting reqs are met.  Otherwise, we'll need to do a full
mode set to re-enable the crtc.

v2: check for crtc active and set mode_changed accordingly

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 150ace6..0701848 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8526,8 +8526,16 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 	if (set->crtc->fb != set->fb) {
 		/* If we have no fb then treat it as a full mode set */
 		if (set->crtc->fb == NULL) {
-			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
-			config->mode_changed = true;
+			struct intel_crtc *intel_crtc =
+				to_intel_crtc(set->crtc);
+
+			if (intel_crtc->active) {
+				DRM_DEBUG_KMS("crtc has no fb, will flip\n");
+				config->fb_changed = true;
+			} else {
+				DRM_DEBUG_KMS("inactive crtc, full mode set\n");
+				config->mode_changed = true;
+			}
 		} else if (set->fb == NULL) {
 			config->mode_changed = true;
 		} else if (set->fb->pixel_format !=
-- 
1.7.9.5

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

* Re: [PATCH 1/6] drm/i915: add encoder get_config function v5
  2013-05-15  0:08 ` [PATCH 1/6] drm/i915: add encoder get_config function v5 Jesse Barnes
@ 2013-05-15 21:45   ` Paulo Zanoni
  2013-05-21  7:51     ` Daniel Vetter
  2013-05-21  7:55     ` Daniel Vetter
  0 siblings, 2 replies; 14+ messages in thread
From: Paulo Zanoni @ 2013-05-15 21:45 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx

2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>:
> We can use this for fetching encoder specific pipe_config state, like
> mode flags, adjusted clock, etc.
>
> Just used for mode flags atm, so we can check the pipe config state at
> mode set time.
>
> v2: get_config when checking hw state too
> v3: fix DVO and LVDS mode flags (Ville)
>     get SDVO DTD for flag fetch (Ville)
> v4: use input timings (Ville)
>     correct command used (Ville)
>     remove gen4 check (Ville)
> v5: get DDI flag config too
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

I applied this on my Haswell machine and booted it with both eDP-only
and eDP+DP and now I don't see those error messages anymore.


> ---
>  drivers/gpu/drm/i915/intel_crt.c     |   23 +++++++++++++++++++
>  drivers/gpu/drm/i915/intel_ddi.c     |   23 +++++++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |   20 +++++++++++++---
>  drivers/gpu/drm/i915/intel_dp.c      |   23 +++++++++++++++++++
>  drivers/gpu/drm/i915/intel_drv.h     |    4 ++++
>  drivers/gpu/drm/i915/intel_dvo.c     |   21 +++++++++++++++++
>  drivers/gpu/drm/i915/intel_hdmi.c    |   23 +++++++++++++++++++
>  drivers/gpu/drm/i915/intel_lvds.c    |   26 +++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_sdvo.c    |   42 ++++++++++++++++++++++++++++++++++
>  9 files changed, 202 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index cc414f1..789c4ef 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_crt_get_config(struct intel_encoder *encoder,
> +                                struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       struct intel_crt *crt = intel_encoder_to_crt(encoder);
> +       u32 tmp, flags = 0;
> +
> +       tmp = I915_READ(crt->adpa_reg);
> +
> +       if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +
> +       if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  static void intel_disable_crt(struct intel_encoder *encoder)
>  {
>         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> @@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev)
>         crt->base.compute_config = intel_crt_compute_config;
>         crt->base.disable = intel_disable_crt;
>         crt->base.enable = intel_enable_crt;
> +       crt->base.get_config = intel_crt_get_config;
>         if (I915_HAS_HOTPLUG(dev))
>                 crt->base.hpd_pin = HPD_CRT;
>         if (HAS_DDI(dev))
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index cddcf4a..27a74a9 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
>                 intel_dp_check_link_status(intel_dp);
>  }
>
> +static void intel_ddi_get_config(struct intel_encoder *encoder,
> +                                struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> +       enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
> +       u32 temp, flags = 0;
> +
> +       temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> +       if (temp & TRANS_DDI_PHSYNC)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +       if (temp & TRANS_DDI_PVSYNC)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +       pipe_config->pixel_multiplier = 1;
> +}
> +
>  static void intel_ddi_destroy(struct drm_encoder *encoder)
>  {
>         /* HDMI has nothing special to destroy, so we can go with this. */
> @@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
>         intel_encoder->disable = intel_disable_ddi;
>         intel_encoder->post_disable = intel_ddi_post_disable;
>         intel_encoder->get_hw_state = intel_ddi_get_hw_state;
> +       intel_encoder->get_config = intel_ddi_get_config;
>
>         intel_dig_port->port = port;
>         intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 7358e4e..163b97e 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev,
>         PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
>                               DRM_MODE_FLAG_INTERLACE);
>
> +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> +                             DRM_MODE_FLAG_PHSYNC);
> +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> +                             DRM_MODE_FLAG_NHSYNC);
> +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> +                             DRM_MODE_FLAG_PVSYNC);
> +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> +                             DRM_MODE_FLAG_NVSYNC);
> +
>         PIPE_CONF_CHECK_I(requested_mode.hdisplay);
>         PIPE_CONF_CHECK_I(requested_mode.vdisplay);
>
> @@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev)
>                 bool enabled = false;
>                 bool active = false;
>
> +               memset(&pipe_config, 0, sizeof(pipe_config));
> +
>                 DRM_DEBUG_KMS("[CRTC:%d]\n",
>                               crtc->base.base.id);
>
> @@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev)
>                         enabled = true;
>                         if (encoder->connectors_active)
>                                 active = true;
> +                       if (encoder->get_config)
> +                               encoder->get_config(encoder, &pipe_config);
>                 }
>                 WARN(active != crtc->active,
>                      "crtc's computed active state doesn't match tracked active state "
> @@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev)
>                      "crtc's computed enabled state doesn't match tracked enabled state "
>                      "(expected %i, found %i)\n", enabled, crtc->base.enabled);
>
> -               memset(&pipe_config, 0, sizeof(pipe_config));
>                 pipe_config.cpu_transcoder = crtc->config.cpu_transcoder;
>                 active = dev_priv->display.get_pipe_config(crtc,
>                                                            &pipe_config);
> @@ -9579,8 +9591,10 @@ setup_pipes:
>                 pipe = 0;
>
>                 if (encoder->get_hw_state(encoder, &pipe)) {
> -                       encoder->base.crtc =
> -                               dev_priv->pipe_to_crtc_mapping[pipe];
> +                       crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
> +                       encoder->base.crtc = &crtc->base;
> +                       if (encoder->get_config)
> +                               encoder->get_config(encoder, &crtc->config);
>                 } else {
>                         encoder->base.crtc = NULL;
>                 }
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 2bb4009..a423256 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_dp_get_config(struct intel_encoder *encoder,
> +                               struct intel_crtc_config *pipe_config)
> +{
> +       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       u32 tmp, flags = 0;
> +
> +       tmp = I915_READ(intel_dp->output_reg);
> +
> +       if (tmp & DP_SYNC_HS_HIGH)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +
> +       if (tmp & DP_SYNC_VS_HIGH)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  static void intel_disable_dp(struct intel_encoder *encoder)
>  {
>         struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> @@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
>         intel_encoder->disable = intel_disable_dp;
>         intel_encoder->post_disable = intel_post_disable_dp;
>         intel_encoder->get_hw_state = intel_dp_get_hw_state;
> +       intel_encoder->get_config = intel_dp_get_config;
>         if (IS_VALLEYVIEW(dev))
>                 intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
>
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 0f35545..4802483 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -139,6 +139,10 @@ struct intel_encoder {
>          * the encoder is active. If the encoder is enabled it also set the pipe
>          * it is connected to in the pipe parameter. */
>         bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
> +       /* Reconstructs the equivalent mode flags for the current hardware
> +        * state. */
> +       void (*get_config)(struct intel_encoder *,
> +                          struct intel_crtc_config *pipe_config);
>         int crtc_mask;
>         enum hpd_pin hpd_pin;
>  };
> diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
> index 00e70db..91e9905 100644
> --- a/drivers/gpu/drm/i915/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/intel_dvo.c
> @@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_dvo_get_config(struct intel_encoder *encoder,
> +                                struct intel_crtc_config *pipe_config)
> +{
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
> +       u32 tmp, flags = 0;
> +
> +       tmp = I915_READ(intel_dvo->dev.dvo_reg);
> +       if (tmp & DVO_HSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +       if (tmp & DVO_VSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  static void intel_disable_dvo(struct intel_encoder *encoder)
>  {
>         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> @@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev)
>         intel_encoder->disable = intel_disable_dvo;
>         intel_encoder->enable = intel_enable_dvo;
>         intel_encoder->get_hw_state = intel_dvo_get_hw_state;
> +       intel_encoder->get_config = intel_dvo_get_config;
>         intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
>
>         /* Now, try to find a controller */
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 93de5ff..9091655 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_hdmi_get_config(struct intel_encoder *encoder,
> +                                 struct intel_crtc_config *pipe_config)
> +{
> +       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> +       u32 tmp, flags = 0;
> +
> +       tmp = I915_READ(intel_hdmi->hdmi_reg);
> +
> +       if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +
> +       if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  static void intel_enable_hdmi(struct intel_encoder *encoder)
>  {
>         struct drm_device *dev = encoder->base.dev;
> @@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
>         intel_encoder->enable = intel_enable_hdmi;
>         intel_encoder->disable = intel_disable_hdmi;
>         intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
> +       intel_encoder->get_config = intel_hdmi_get_config;
>         if (IS_VALLEYVIEW(dev)) {
>                 intel_encoder->pre_enable = intel_hdmi_pre_enable;
>                 intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 36fe291..6554860 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_lvds_get_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;
> +       u32 lvds_reg, tmp, flags = 0;
> +
> +       if (HAS_PCH_SPLIT(dev))
> +               lvds_reg = PCH_LVDS;
> +       else
> +               lvds_reg = LVDS;
> +
> +       tmp = I915_READ(lvds_reg);
> +       if (tmp & LVDS_HSYNC_POLARITY)
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       if (tmp & LVDS_VSYNC_POLARITY)
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  /* The LVDS pin pair needs to be on before the DPLLs are enabled.
>   * This is an exception to the general rule that mode_set doesn't turn
>   * things on.
> @@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev)
>         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_encoder->get_config = intel_lvds_get_config;
>         intel_connector->get_hw_state = intel_connector_get_hw_state;
>
>         intel_connector_attach_encoder(intel_connector, intel_encoder);
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 2f54dc3..416d23c 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
>                 intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
>  }
>
> +static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
> +                                 struct intel_sdvo_dtd *dtd)
> +{
> +       return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
> +               intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
> +}
> +
>  static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
>                                          struct intel_sdvo_dtd *dtd)
>  {
> @@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
>                                      SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
>  }
>
> +static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
> +                                       struct intel_sdvo_dtd *dtd)
> +{
> +       return intel_sdvo_get_timing(intel_sdvo,
> +                                    SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
> +}
> +
>  static bool
>  intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
>                                          uint16_t clock,
> @@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
>         return true;
>  }
>
> +static void intel_sdvo_get_config(struct intel_encoder *encoder,
> +                                 struct intel_crtc_config *pipe_config)
> +{
> +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
> +       struct intel_sdvo_dtd dtd;
> +       u32 flags = 0;
> +       bool ret;
> +
> +       ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
> +       if (!ret) {
> +               DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
> +               return;
> +       }
> +
> +       if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
> +               flags |= DRM_MODE_FLAG_PHSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NHSYNC;
> +
> +       if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
> +               flags |= DRM_MODE_FLAG_PVSYNC;
> +       else
> +               flags |= DRM_MODE_FLAG_NVSYNC;
> +
> +       pipe_config->adjusted_mode.flags |= flags;
> +}
> +
>  static void intel_disable_sdvo(struct intel_encoder *encoder)
>  {
>         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> @@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
>         intel_encoder->mode_set = intel_sdvo_mode_set;
>         intel_encoder->enable = intel_enable_sdvo;
>         intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
> +       intel_encoder->get_config = intel_sdvo_get_config;
>
>         /* In default case sdvo lvds is false */
>         if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
> --
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Paulo Zanoni

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

* Re: [PATCH 1/6] drm/i915: add encoder get_config function v5
  2013-05-15 21:45   ` Paulo Zanoni
@ 2013-05-21  7:51     ` Daniel Vetter
  2013-05-21  7:55     ` Daniel Vetter
  1 sibling, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2013-05-21  7:51 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Wed, May 15, 2013 at 06:45:35PM -0300, Paulo Zanoni wrote:
> 2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > We can use this for fetching encoder specific pipe_config state, like
> > mode flags, adjusted clock, etc.
> >
> > Just used for mode flags atm, so we can check the pipe config state at
> > mode set time.
> >
> > v2: get_config when checking hw state too
> > v3: fix DVO and LVDS mode flags (Ville)
> >     get SDVO DTD for flag fetch (Ville)
> > v4: use input timings (Ville)
> >     correct command used (Ville)
> >     remove gen4 check (Ville)
> > v5: get DDI flag config too
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> I applied this on my Haswell machine and booted it with both eDP-only
> and eDP+DP and now I don't see those error messages anymore.

Queued for -next, thanks for the patch.
-Daniel
> 
> 
> > ---
> >  drivers/gpu/drm/i915/intel_crt.c     |   23 +++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_ddi.c     |   23 +++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_display.c |   20 +++++++++++++---
> >  drivers/gpu/drm/i915/intel_dp.c      |   23 +++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_drv.h     |    4 ++++
> >  drivers/gpu/drm/i915/intel_dvo.c     |   21 +++++++++++++++++
> >  drivers/gpu/drm/i915/intel_hdmi.c    |   23 +++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_lvds.c    |   26 +++++++++++++++++++++
> >  drivers/gpu/drm/i915/intel_sdvo.c    |   42 ++++++++++++++++++++++++++++++++++
> >  9 files changed, 202 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> > index cc414f1..789c4ef 100644
> > --- a/drivers/gpu/drm/i915/intel_crt.c
> > +++ b/drivers/gpu/drm/i915/intel_crt.c
> > @@ -81,6 +81,28 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_crt_get_config(struct intel_encoder *encoder,
> > +                                struct intel_crtc_config *pipe_config)
> > +{
> > +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > +       struct intel_crt *crt = intel_encoder_to_crt(encoder);
> > +       u32 tmp, flags = 0;
> > +
> > +       tmp = I915_READ(crt->adpa_reg);
> > +
> > +       if (tmp & ADPA_HSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +
> > +       if (tmp & ADPA_VSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  static void intel_disable_crt(struct intel_encoder *encoder)
> >  {
> >         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > @@ -784,6 +806,7 @@ void intel_crt_init(struct drm_device *dev)
> >         crt->base.compute_config = intel_crt_compute_config;
> >         crt->base.disable = intel_disable_crt;
> >         crt->base.enable = intel_enable_crt;
> > +       crt->base.get_config = intel_crt_get_config;
> >         if (I915_HAS_HOTPLUG(dev))
> >                 crt->base.hpd_pin = HPD_CRT;
> >         if (HAS_DDI(dev))
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index cddcf4a..27a74a9 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -1254,6 +1254,28 @@ static void intel_ddi_hot_plug(struct intel_encoder *intel_encoder)
> >                 intel_dp_check_link_status(intel_dp);
> >  }
> >
> > +static void intel_ddi_get_config(struct intel_encoder *encoder,
> > +                                struct intel_crtc_config *pipe_config)
> > +{
> > +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > +       struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
> > +       enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
> > +       u32 temp, flags = 0;
> > +
> > +       temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> > +       if (temp & TRANS_DDI_PHSYNC)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +       if (temp & TRANS_DDI_PVSYNC)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +       pipe_config->pixel_multiplier = 1;
> > +}
> > +
> >  static void intel_ddi_destroy(struct drm_encoder *encoder)
> >  {
> >         /* HDMI has nothing special to destroy, so we can go with this. */
> > @@ -1313,6 +1335,7 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
> >         intel_encoder->disable = intel_disable_ddi;
> >         intel_encoder->post_disable = intel_ddi_post_disable;
> >         intel_encoder->get_hw_state = intel_ddi_get_hw_state;
> > +       intel_encoder->get_config = intel_ddi_get_config;
> >
> >         intel_dig_port->port = port;
> >         intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) &
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 7358e4e..163b97e 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -8057,6 +8057,15 @@ intel_pipe_config_compare(struct drm_device *dev,
> >         PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> >                               DRM_MODE_FLAG_INTERLACE);
> >
> > +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> > +                             DRM_MODE_FLAG_PHSYNC);
> > +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> > +                             DRM_MODE_FLAG_NHSYNC);
> > +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> > +                             DRM_MODE_FLAG_PVSYNC);
> > +       PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
> > +                             DRM_MODE_FLAG_NVSYNC);
> > +
> >         PIPE_CONF_CHECK_I(requested_mode.hdisplay);
> >         PIPE_CONF_CHECK_I(requested_mode.vdisplay);
> >
> > @@ -8149,6 +8158,8 @@ intel_modeset_check_state(struct drm_device *dev)
> >                 bool enabled = false;
> >                 bool active = false;
> >
> > +               memset(&pipe_config, 0, sizeof(pipe_config));
> > +
> >                 DRM_DEBUG_KMS("[CRTC:%d]\n",
> >                               crtc->base.base.id);
> >
> > @@ -8162,6 +8173,8 @@ intel_modeset_check_state(struct drm_device *dev)
> >                         enabled = true;
> >                         if (encoder->connectors_active)
> >                                 active = true;
> > +                       if (encoder->get_config)
> > +                               encoder->get_config(encoder, &pipe_config);
> >                 }
> >                 WARN(active != crtc->active,
> >                      "crtc's computed active state doesn't match tracked active state "
> > @@ -8170,7 +8183,6 @@ intel_modeset_check_state(struct drm_device *dev)
> >                      "crtc's computed enabled state doesn't match tracked enabled state "
> >                      "(expected %i, found %i)\n", enabled, crtc->base.enabled);
> >
> > -               memset(&pipe_config, 0, sizeof(pipe_config));
> >                 pipe_config.cpu_transcoder = crtc->config.cpu_transcoder;
> >                 active = dev_priv->display.get_pipe_config(crtc,
> >                                                            &pipe_config);
> > @@ -9579,8 +9591,10 @@ setup_pipes:
> >                 pipe = 0;
> >
> >                 if (encoder->get_hw_state(encoder, &pipe)) {
> > -                       encoder->base.crtc =
> > -                               dev_priv->pipe_to_crtc_mapping[pipe];
> > +                       crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
> > +                       encoder->base.crtc = &crtc->base;
> > +                       if (encoder->get_config)
> > +                               encoder->get_config(encoder, &crtc->config);
> >                 } else {
> >                         encoder->base.crtc = NULL;
> >                 }
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 2bb4009..a423256 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1356,6 +1356,28 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_dp_get_config(struct intel_encoder *encoder,
> > +                               struct intel_crtc_config *pipe_config)
> > +{
> > +       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> > +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > +       u32 tmp, flags = 0;
> > +
> > +       tmp = I915_READ(intel_dp->output_reg);
> > +
> > +       if (tmp & DP_SYNC_HS_HIGH)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +
> > +       if (tmp & DP_SYNC_VS_HIGH)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  static void intel_disable_dp(struct intel_encoder *encoder)
> >  {
> >         struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> > @@ -3154,6 +3176,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
> >         intel_encoder->disable = intel_disable_dp;
> >         intel_encoder->post_disable = intel_post_disable_dp;
> >         intel_encoder->get_hw_state = intel_dp_get_hw_state;
> > +       intel_encoder->get_config = intel_dp_get_config;
> >         if (IS_VALLEYVIEW(dev))
> >                 intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
> >
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index 0f35545..4802483 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -139,6 +139,10 @@ struct intel_encoder {
> >          * the encoder is active. If the encoder is enabled it also set the pipe
> >          * it is connected to in the pipe parameter. */
> >         bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe);
> > +       /* Reconstructs the equivalent mode flags for the current hardware
> > +        * state. */
> > +       void (*get_config)(struct intel_encoder *,
> > +                          struct intel_crtc_config *pipe_config);
> >         int crtc_mask;
> >         enum hpd_pin hpd_pin;
> >  };
> > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
> > index 00e70db..91e9905 100644
> > --- a/drivers/gpu/drm/i915/intel_dvo.c
> > +++ b/drivers/gpu/drm/i915/intel_dvo.c
> > @@ -129,6 +129,26 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_dvo_get_config(struct intel_encoder *encoder,
> > +                                struct intel_crtc_config *pipe_config)
> > +{
> > +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > +       struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
> > +       u32 tmp, flags = 0;
> > +
> > +       tmp = I915_READ(intel_dvo->dev.dvo_reg);
> > +       if (tmp & DVO_HSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +       if (tmp & DVO_VSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  static void intel_disable_dvo(struct intel_encoder *encoder)
> >  {
> >         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > @@ -440,6 +460,7 @@ void intel_dvo_init(struct drm_device *dev)
> >         intel_encoder->disable = intel_disable_dvo;
> >         intel_encoder->enable = intel_enable_dvo;
> >         intel_encoder->get_hw_state = intel_dvo_get_hw_state;
> > +       intel_encoder->get_config = intel_dvo_get_config;
> >         intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
> >
> >         /* Now, try to find a controller */
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 93de5ff..9091655 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -658,6 +658,28 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_hdmi_get_config(struct intel_encoder *encoder,
> > +                                 struct intel_crtc_config *pipe_config)
> > +{
> > +       struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> > +       struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > +       u32 tmp, flags = 0;
> > +
> > +       tmp = I915_READ(intel_hdmi->hdmi_reg);
> > +
> > +       if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +
> > +       if (tmp & SDVO_VSYNC_ACTIVE_HIGH)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  static void intel_enable_hdmi(struct intel_encoder *encoder)
> >  {
> >         struct drm_device *dev = encoder->base.dev;
> > @@ -1208,6 +1230,7 @@ void intel_hdmi_init(struct drm_device *dev, int hdmi_reg, enum port port)
> >         intel_encoder->enable = intel_enable_hdmi;
> >         intel_encoder->disable = intel_disable_hdmi;
> >         intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
> > +       intel_encoder->get_config = intel_hdmi_get_config;
> >         if (IS_VALLEYVIEW(dev)) {
> >                 intel_encoder->pre_enable = intel_hdmi_pre_enable;
> >                 intel_encoder->pre_pll_enable = intel_hdmi_pre_pll_enable;
> > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> > index 36fe291..6554860 100644
> > --- a/drivers/gpu/drm/i915/intel_lvds.c
> > +++ b/drivers/gpu/drm/i915/intel_lvds.c
> > @@ -86,6 +86,31 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_lvds_get_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;
> > +       u32 lvds_reg, tmp, flags = 0;
> > +
> > +       if (HAS_PCH_SPLIT(dev))
> > +               lvds_reg = PCH_LVDS;
> > +       else
> > +               lvds_reg = LVDS;
> > +
> > +       tmp = I915_READ(lvds_reg);
> > +       if (tmp & LVDS_HSYNC_POLARITY)
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       if (tmp & LVDS_VSYNC_POLARITY)
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  /* The LVDS pin pair needs to be on before the DPLLs are enabled.
> >   * This is an exception to the general rule that mode_set doesn't turn
> >   * things on.
> > @@ -921,6 +946,7 @@ bool intel_lvds_init(struct drm_device *dev)
> >         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_encoder->get_config = intel_lvds_get_config;
> >         intel_connector->get_hw_state = intel_connector_get_hw_state;
> >
> >         intel_connector_attach_encoder(intel_connector, intel_encoder);
> > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> > index 2f54dc3..416d23c 100644
> > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > @@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
> >                 intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
> >  }
> >
> > +static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
> > +                                 struct intel_sdvo_dtd *dtd)
> > +{
> > +       return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
> > +               intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
> > +}
> > +
> >  static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
> >                                          struct intel_sdvo_dtd *dtd)
> >  {
> > @@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
> >                                      SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
> >  }
> >
> > +static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
> > +                                       struct intel_sdvo_dtd *dtd)
> > +{
> > +       return intel_sdvo_get_timing(intel_sdvo,
> > +                                    SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
> > +}
> > +
> >  static bool
> >  intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
> >                                          uint16_t clock,
> > @@ -1295,6 +1309,33 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
> >         return true;
> >  }
> >
> > +static void intel_sdvo_get_config(struct intel_encoder *encoder,
> > +                                 struct intel_crtc_config *pipe_config)
> > +{
> > +       struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
> > +       struct intel_sdvo_dtd dtd;
> > +       u32 flags = 0;
> > +       bool ret;
> > +
> > +       ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
> > +       if (!ret) {
> > +               DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
> > +               return;
> > +       }
> > +
> > +       if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
> > +               flags |= DRM_MODE_FLAG_PHSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NHSYNC;
> > +
> > +       if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
> > +               flags |= DRM_MODE_FLAG_PVSYNC;
> > +       else
> > +               flags |= DRM_MODE_FLAG_NVSYNC;
> > +
> > +       pipe_config->adjusted_mode.flags |= flags;
> > +}
> > +
> >  static void intel_disable_sdvo(struct intel_encoder *encoder)
> >  {
> >         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
> > @@ -2819,6 +2860,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
> >         intel_encoder->mode_set = intel_sdvo_mode_set;
> >         intel_encoder->enable = intel_enable_sdvo;
> >         intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
> > +       intel_encoder->get_config = intel_sdvo_get_config;
> >
> >         /* In default case sdvo lvds is false */
> >         if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
> 
> -- 
> Paulo Zanoni
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 1/6] drm/i915: add encoder get_config function v5
  2013-05-15 21:45   ` Paulo Zanoni
  2013-05-21  7:51     ` Daniel Vetter
@ 2013-05-21  7:55     ` Daniel Vetter
  1 sibling, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2013-05-21  7:55 UTC (permalink / raw)
  To: Paulo Zanoni; +Cc: intel-gfx

On Wed, May 15, 2013 at 06:45:35PM -0300, Paulo Zanoni wrote:
> 2013/5/14 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > We can use this for fetching encoder specific pipe_config state, like
> > mode flags, adjusted clock, etc.
> >
> > Just used for mode flags atm, so we can check the pipe config state at
> > mode set time.
> >
> > v2: get_config when checking hw state too
> > v3: fix DVO and LVDS mode flags (Ville)
> >     get SDVO DTD for flag fetch (Ville)
> > v4: use input timings (Ville)
> >     correct command used (Ville)
> >     remove gen4 check (Ville)
> > v5: get DDI flag config too
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> > Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> 
> I applied this on my Haswell machine and booted it with both eDP-only
> and eDP+DP and now I don't see those error messages anymore.

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

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

* Re: [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5
  2013-05-15  0:08 ` [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5 Jesse Barnes
@ 2013-05-23 15:30   ` Daniel Vetter
  2013-05-23 16:10     ` Jesse Barnes
  0 siblings, 1 reply; 14+ messages in thread
From: Daniel Vetter @ 2013-05-23 15:30 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx

On Tue, May 14, 2013 at 05:08:27PM -0700, Jesse Barnes wrote:
> We need this for comparing modes between configuration changes.
> 
> v2: try harder to calulate non-simple pixel clocks (Daniel)
>     call get_clock after getting the encoder config, needed for pixel multiply
>     (Jesse)
> v3: drop get_clock now that the pixel_multiply has been moved into
>     get_pipe_config
> v4: re-add get_clock; we need to get the pixel multiplier in the
>     encoder, so need to calculate the clock value after the encoder's
>     get_config is called
> v5: drop hsw clock_get, still needs to be written
> 
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

Two things:
- the pixel_multiplier should be a separate patch, and I think we should
  add pipe_config check support for it. Maybe if we pick a default value
  of 1 (both for the get_config hw state readout and the compute config
  stuff in the modeset code) that should also simplify a bit since only
  SDVO uses it atm. We still need to implement pixel multiplier stuff for
  native hdmi ports ...
- For the clock readout code I think we should be able to have pipe config
  compare support (with adjusted_mode->clock), with a bit of fuzz at
  least. Not on current dinq, but with my cleanup to give
  adjusted_mode->clock saner semantics:

  http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/21750
- There's no reason imo for the new ->get_clock vfunc, it splits exactly
  the same as the existing ->get_pipe_config. So could simply be included
  there.

With those three adjustements I think this is ready to go. For the
follow-up patches though I think we should guard them with a fastboot
module option.
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h      |    1 +
>  drivers/gpu/drm/i915/intel_crt.c     |    1 +
>  drivers/gpu/drm/i915/intel_display.c |   78 +++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_dp.c      |    8 ++++
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>  drivers/gpu/drm/i915/intel_dvo.c     |    1 +
>  drivers/gpu/drm/i915/intel_hdmi.c    |    1 +
>  drivers/gpu/drm/i915/intel_lvds.c    |    1 +
>  drivers/gpu/drm/i915/intel_sdvo.c    |   24 +++++++++++
>  9 files changed, 111 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 14817de..2e284bb 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -323,6 +323,7 @@ struct drm_i915_display_funcs {
>  	 * fills out the pipe-config with the hw state. */
>  	bool (*get_pipe_config)(struct intel_crtc *,
>  				struct intel_crtc_config *);
> +	void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *);
>  	int (*crtc_mode_set)(struct drm_crtc *crtc,
>  			     int x, int y,
>  			     struct drm_framebuffer *old_fb);
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index 789c4ef..bd91e72 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -101,6 +101,7 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +	pipe_config->pixel_multiplier = 1;
>  }
>  
>  static void intel_disable_crt(struct intel_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 163b97e..356404c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -45,6 +45,11 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
>  static void intel_increase_pllclock(struct drm_crtc *crtc);
>  static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
>  
> +static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
> +				struct intel_crtc_config *pipe_config);
> +static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
> +				    struct intel_crtc_config *pipe_config);
> +
>  typedef struct {
>  	int	min, max;
>  } intel_range_t;
> @@ -6906,11 +6911,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
>  }
>  
>  /* Returns the clock of the currently programmed mode of the given pipe. */
> -static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
> +static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
> +				struct intel_crtc_config *pipe_config)
>  {
> +	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -	int pipe = intel_crtc->pipe;
> +	int pipe = pipe_config->cpu_transcoder;
>  	u32 dpll = I915_READ(DPLL(pipe));
>  	u32 fp;
>  	intel_clock_t clock;
> @@ -6949,7 +6955,8 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
>  		default:
>  			DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
>  				  "mode\n", (int)(dpll & DPLL_MODE_MASK));
> -			return 0;
> +			pipe_config->adjusted_mode.clock = 0;
> +			return;
>  		}
>  
>  		/* XXX: Handle the 100Mhz refclk */
> @@ -6988,8 +6995,54 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
>  	 * i830PllIsValid() because it relies on the xf86_config connector
>  	 * configuration being accurate, which it isn't necessarily.
>  	 */
> +	pipe_config->adjusted_mode.clock = clock.dot;
> +}
> +
> +static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
> +				    struct intel_crtc_config *pipe_config)
> +{
> +	struct drm_device *dev = crtc->base.dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +	int link_freq, repeat;
> +	u64 clock;
> +	u32 link_m, link_n;
>  
> -	return clock.dot;
> +	repeat = pipe_config->pixel_multiplier;
> +
> +	/*
> +	 * The calculation for the data clock is:
> +	 * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp
> +	 * But we want to avoid losing precison if possible, so:
> +	 * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp))
> +	 *
> +	 * and the link clock is simpler:
> +	 * link_clock = (m * link_clock * repeat) / n
> +	 */
> +
> +	/*
> +	 * We need to get the FDI or DP link clock here to derive
> +	 * the M/N dividers.
> +	 *
> +	 * For FDI, we read it from the BIOS or use a fixed 2.7GHz.
> +	 * For DP, it's either 1.62GHz or 2.7GHz.
> +	 * We do our calculations in 10*MHz since we don't need much precison.
> +	 */
> +	if (pipe_config->has_pch_encoder)
> +		link_freq = intel_fdi_link_freq(dev) * 10000;
> +	else
> +		link_freq = pipe_config->cpu_edp_link_rate;
> +
> +	link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder));
> +	link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder));
> +
> +	if (!link_m || !link_n)
> +		return;
> +
> +	clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
> +	do_div(clock, link_n);
> +
> +	pipe_config->adjusted_mode.clock = clock;
>  }
>  
>  /** Returns the currently programmed mode of the given pipe. */
> @@ -7000,6 +7053,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
>  	struct drm_display_mode *mode;
> +	struct intel_crtc_config pipe_config;
>  	int htot = I915_READ(HTOTAL(cpu_transcoder));
>  	int hsync = I915_READ(HSYNC(cpu_transcoder));
>  	int vtot = I915_READ(VTOTAL(cpu_transcoder));
> @@ -7009,7 +7063,10 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
>  	if (!mode)
>  		return NULL;
>  
> -	mode->clock = intel_crtc_clock_get(dev, crtc);
> +	pipe_config.cpu_transcoder = intel_crtc->pipe;
> +	i9xx_crtc_clock_get(intel_crtc, &pipe_config);
> +
> +	mode->clock = pipe_config.adjusted_mode.clock;
>  	mode->hdisplay = (htot & 0xffff) + 1;
>  	mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
>  	mode->hsync_start = (hsync & 0xffff) + 1;
> @@ -9011,6 +9068,7 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.update_plane = ironlake_update_plane;
>  	} else if (HAS_PCH_SPLIT(dev)) {
>  		dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
> +		dev_priv->display.get_clock = ironlake_crtc_clock_get;
>  		dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
>  		dev_priv->display.crtc_enable = ironlake_crtc_enable;
>  		dev_priv->display.crtc_disable = ironlake_crtc_disable;
> @@ -9018,6 +9076,7 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.update_plane = ironlake_update_plane;
>  	} else if (IS_VALLEYVIEW(dev)) {
>  		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> +		dev_priv->display.get_clock = i9xx_crtc_clock_get;
>  		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
>  		dev_priv->display.crtc_enable = valleyview_crtc_enable;
>  		dev_priv->display.crtc_disable = i9xx_crtc_disable;
> @@ -9025,6 +9084,7 @@ static void intel_init_display(struct drm_device *dev)
>  		dev_priv->display.update_plane = i9xx_update_plane;
>  	} else {
>  		dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
> +		dev_priv->display.get_clock = i9xx_crtc_clock_get;
>  		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
>  		dev_priv->display.crtc_enable = i9xx_crtc_enable;
>  		dev_priv->display.crtc_disable = i9xx_crtc_disable;
> @@ -9593,8 +9653,12 @@ setup_pipes:
>  		if (encoder->get_hw_state(encoder, &pipe)) {
>  			crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
>  			encoder->base.crtc = &crtc->base;
> -			if (encoder->get_config)
> +			if (encoder->get_config &&
> +			    dev_priv->display.get_clock) {
>  				encoder->get_config(encoder, &crtc->config);
> +				dev_priv->display.get_clock(crtc,
> +							    &crtc->config);
> +			}
>  		} else {
>  			encoder->base.crtc = NULL;
>  		}
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index a423256..c32429d 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1376,6 +1376,14 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +	pipe_config->pixel_multiplier = 1;
> +
> +	if (is_cpu_edp(intel_dp)) {
> +		if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
> +			pipe_config->cpu_edp_link_rate = 162000;
> +		else
> +			pipe_config->cpu_edp_link_rate = 270000;
> +	}
>  }
>  
>  static void intel_disable_dp(struct intel_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 4802483..a7c9293 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -268,6 +268,9 @@ struct intel_crtc_config {
>  	/* FDI configuration, only valid if has_pch_encoder is set. */
>  	int fdi_lanes;
>  	struct intel_link_m_n fdi_m_n;
> +
> +	/* CPU eDP config */
> +	int cpu_edp_link_rate;
>  };
>  
>  struct intel_crtc {
> diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
> index 91e9905..d020a9c 100644
> --- a/drivers/gpu/drm/i915/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/intel_dvo.c
> @@ -147,6 +147,7 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +	pipe_config->pixel_multiplier = 1;
>  }
>  
>  static void intel_disable_dvo(struct intel_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 9091655..7b55a8a 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -678,6 +678,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +	pipe_config->pixel_multiplier = 1;
>  }
>  
>  static void intel_enable_hdmi(struct intel_encoder *encoder)
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 6554860..f0cbb02 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -109,6 +109,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_PVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +	pipe_config->pixel_multiplier = 1;
>  }
>  
>  /* The LVDS pin pair needs to be on before the DPLLs are enabled.
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 416d23c..ee7f0ab 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -780,6 +780,11 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val
>  	return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
>  }
>  
> +static bool intel_sdvo_get_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 *val)
> +{
> +	return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1);
> +}
> +
>  static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
>  					 const struct drm_display_mode *mode)
>  {
> @@ -1315,6 +1320,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>  	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
>  	struct intel_sdvo_dtd dtd;
>  	u32 flags = 0;
> +	u8 val;
>  	bool ret;
>  
>  	ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
> @@ -1334,6 +1340,24 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	pipe_config->adjusted_mode.flags |= flags;
> +
> +	ret = intel_sdvo_get_clock_rate_mult(intel_sdvo, &val);
> +	if (!ret) {
> +		DRM_DEBUG_DRIVER("failed to retrieve clock rate multiplier\n");
> +		return;
> +	}
> +
> +	switch (val) {
> +	case SDVO_CLOCK_RATE_MULT_1X:
> +		pipe_config->pixel_multiplier = 1;
> +		break;
> +	case SDVO_CLOCK_RATE_MULT_2X:
> +		pipe_config->pixel_multiplier = 2;
> +		break;
> +	case SDVO_CLOCK_RATE_MULT_4X:
> +		pipe_config->pixel_multiplier = 4;
> +		break;
> +	}
>  }
>  
>  static void intel_disable_sdvo(struct intel_encoder *encoder)
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5
  2013-05-23 15:30   ` Daniel Vetter
@ 2013-05-23 16:10     ` Jesse Barnes
  2013-05-23 18:53       ` Daniel Vetter
  0 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2013-05-23 16:10 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Thu, 23 May 2013 17:30:06 +0200
Daniel Vetter <daniel@ffwll.ch> wrote:

> On Tue, May 14, 2013 at 05:08:27PM -0700, Jesse Barnes wrote:
> > We need this for comparing modes between configuration changes.
> > 
> > v2: try harder to calulate non-simple pixel clocks (Daniel)
> >     call get_clock after getting the encoder config, needed for pixel multiply
> >     (Jesse)
> > v3: drop get_clock now that the pixel_multiply has been moved into
> >     get_pipe_config
> > v4: re-add get_clock; we need to get the pixel multiplier in the
> >     encoder, so need to calculate the clock value after the encoder's
> >     get_config is called
> > v5: drop hsw clock_get, still needs to be written
> > 
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> 
> Two things:
> - the pixel_multiplier should be a separate patch, and I think we should
>   add pipe_config check support for it. Maybe if we pick a default value
>   of 1 (both for the get_config hw state readout and the compute config
>   stuff in the modeset code) that should also simplify a bit since only
>   SDVO uses it atm. We still need to implement pixel multiplier stuff for
>   native hdmi ports ...

Yeah, I'm ambivalent about it.  I like it called out in the encoder
funcs just because the setting belongs there, but since only SDVO uses
it, it does seem wasteful.  Maybe I'm just being hopeful about the HDMI
side of things landing soon. :)

> - For the clock readout code I think we should be able to have pipe config
>   compare support (with adjusted_mode->clock), with a bit of fuzz at
>   least. Not on current dinq, but with my cleanup to give
>   adjusted_mode->clock saner semantics:
> 
>   http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/21750

So far I haven't needed the fuzz, but I'm not opposed to adding it as
needed.

> - There's no reason imo for the new ->get_clock vfunc, it splits exactly
>   the same as the existing ->get_pipe_config. So could simply be included
>   there.

Except that it depends on the results of the encoder->get_config
callback... that's the only reason I split it.  If you have ideas about
how to merge it back that's ok with me.

> With those three adjustements I think this is ready to go. For the
> follow-up patches though I think we should guard them with a fastboot
> module option.

Yeah, the main one there is the compute_config.  We can hide that
behind "boot_me_faster" or some such.

-- 
Jesse Barnes, Intel Open Source Technology Center

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

* Re: [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5
  2013-05-23 16:10     ` Jesse Barnes
@ 2013-05-23 18:53       ` Daniel Vetter
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel Vetter @ 2013-05-23 18:53 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx

On Thu, May 23, 2013 at 6:10 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>> - For the clock readout code I think we should be able to have pipe config
>>   compare support (with adjusted_mode->clock), with a bit of fuzz at
>>   least. Not on current dinq, but with my cleanup to give
>>   adjusted_mode->clock saner semantics:
>>
>>   http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/21750
>
> So far I haven't needed the fuzz, but I'm not opposed to adding it as
> needed.

I mean for the pipe_config comparison/checking in general, which seems
to still be lacking.

>> - There's no reason imo for the new ->get_clock vfunc, it splits exactly
>>   the same as the existing ->get_pipe_config. So could simply be included
>>   there.
>
> Except that it depends on the results of the encoder->get_config
> callback... that's the only reason I split it.  If you have ideas about
> how to merge it back that's ok with me.

Yeah, I always forget about that. I still think we should shovel
everything into the platform get_config (including the encoder loop)
like we do for the crtc enable/disable functions. But the current
approach still works, so meh ;-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

* [PATCH] drm/i915: flip on a no fb -> fb transition if crtc is active v3
  2013-05-15  0:08 ` [PATCH 6/6] drm/i915: flip on a no fb -> fb transition if crtc is active v2 Jesse Barnes
@ 2013-05-23 21:23   ` Jesse Barnes
  0 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2013-05-23 21:23 UTC (permalink / raw)
  To: intel-gfx

If the crtc is active, we can simply flip a new fb onto it, provided the
other mode setting reqs are met.  Otherwise, we'll need to do a full
mode set to re-enable the crtc.

v2: check for crtc active and set mode_changed accordingly
v3: add module parameter, i915.fastboot, to control no fb -> fb flip behavior

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.c      |    5 +++++
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |   12 ++++++++++--
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a1a936f..cf266dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -128,6 +128,11 @@ module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
 MODULE_PARM_DESC(disable_power_well,
 		 "Disable the power well when possible (default: false)");
 
+bool i915_fastboot __read_mostly = 0;
+module_param_named(fastboot, i915_fastboot, bool, 0600);
+MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
+		 "(default: false)");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 62f20b2..9b9b106 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1470,6 +1470,7 @@ extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
 extern unsigned int i915_preliminary_hw_support __read_mostly;
 extern int i915_disable_power_well __read_mostly;
+extern bool i915_fastboot __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 80b70dc..e90df02 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8532,8 +8532,16 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
 	if (set->crtc->fb != set->fb) {
 		/* If we have no fb then treat it as a full mode set */
 		if (set->crtc->fb == NULL) {
-			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
-			config->mode_changed = true;
+			struct intel_crtc *intel_crtc =
+				to_intel_crtc(set->crtc);
+
+			if (intel_crtc->active && i915_fastboot) {
+				DRM_DEBUG_KMS("crtc has no fb, will flip\n");
+				config->fb_changed = true;
+			} else {
+				DRM_DEBUG_KMS("inactive crtc, full mode set\n");
+				config->mode_changed = true;
+			}
 		} else if (set->fb == NULL) {
 			config->mode_changed = true;
 		} else if (set->fb->pixel_format !=
-- 
1.7.9.5

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

end of thread, other threads:[~2013-05-23 21:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-15  0:08 Fastboot in 6 patches Jesse Barnes
2013-05-15  0:08 ` [PATCH 1/6] drm/i915: add encoder get_config function v5 Jesse Barnes
2013-05-15 21:45   ` Paulo Zanoni
2013-05-21  7:51     ` Daniel Vetter
2013-05-21  7:55     ` Daniel Vetter
2013-05-15  0:08 ` [PATCH 2/6] drm/i915: get mode clock when reading the pipe config v5 Jesse Barnes
2013-05-23 15:30   ` Daniel Vetter
2013-05-23 16:10     ` Jesse Barnes
2013-05-23 18:53       ` Daniel Vetter
2013-05-15  0:08 ` [PATCH 3/6] drm/i915: copy fetched mode state into crtc at setup_hw time v2 Jesse Barnes
2013-05-15  0:08 ` [PATCH 4/6] drm/i915: fetch PCH PLL state at init time v3 Jesse Barnes
2013-05-15  0:08 ` [PATCH 5/6] HACK: drm/i915: turn off panel fitting at flip time if needed Jesse Barnes
2013-05-15  0:08 ` [PATCH 6/6] drm/i915: flip on a no fb -> fb transition if crtc is active v2 Jesse Barnes
2013-05-23 21:23   ` [PATCH] drm/i915: flip on a no fb -> fb transition if crtc is active v3 Jesse Barnes

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