All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

Decouple intel_dp_set_link_params() from struct intel_crtc_state. This
will be useful for implementing DP upfront link training.

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c    |  5 ++++-
 drivers/gpu/drm/i915/intel_dp.c     | 14 +++++++++-----
 drivers/gpu/drm/i915/intel_dp_mst.c |  6 ++++--
 drivers/gpu/drm/i915/intel_drv.h    |  3 ++-
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c2df4e4..530ee9f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1637,7 +1637,10 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 
 		intel_prepare_dp_ddi_buffers(intel_encoder);
 
-		intel_dp_set_link_params(intel_dp, crtc->config);
+		intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
+					 crtc->config->lane_count,
+					 intel_crtc_has_type(crtc->config,
+							     INTEL_OUTPUT_DP_MST));
 
 		intel_ddi_init_dp_buf_reg(intel_encoder);
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 364db90..2cfb2ae 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1640,11 +1640,12 @@ found:
 }
 
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *pipe_config)
+			      int link_rate, uint8_t lane_count,
+			      bool link_mst)
 {
-	intel_dp->link_rate = pipe_config->port_clock;
-	intel_dp->lane_count = pipe_config->lane_count;
-	intel_dp->link_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST);
+	intel_dp->link_rate = link_rate;
+	intel_dp->lane_count = lane_count;
+	intel_dp->link_mst = link_mst;
 }
 
 static void intel_dp_prepare(struct intel_encoder *encoder)
@@ -1656,7 +1657,10 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
 
-	intel_dp_set_link_params(intel_dp, crtc->config);
+	intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
+				 crtc->config->lane_count,
+				 intel_crtc_has_type(crtc->config,
+						     INTEL_OUTPUT_DP_MST));
 
 	/*
 	 * There are four kinds of DP registers:
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 629337d..e654fea 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -173,8 +173,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
 
 		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
-
-		intel_dp_set_link_params(intel_dp, intel_crtc->config);
+		intel_dp_set_link_params(intel_dp,
+					 intel_crtc->config->port_clock,
+					 intel_crtc->config->lane_count,
+					 true);
 
 		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 774aab3..990a9b9 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1367,7 +1367,8 @@ bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *pipe_config);
+			      int link_rate, uint8_t lane_count,
+			      bool link_mst);
 void intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
-- 
1.9.1

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

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

* [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
  2016-08-19 23:33 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

The value of ddi_pll_sel is derived from the selection of shared dpll,
so just calculate the final value when necessary.

v2: Actually remove it from crtc state and delete remaining usages. (CI)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 45 ++++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_display.c  | 43 +++++++--------------------------
 drivers/gpu/drm/i915/intel_dp_mst.c   |  3 ++-
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 27 ---------------------
 drivers/gpu/drm/i915/intel_drv.h      |  8 +------
 5 files changed, 45 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 530ee9f..8c87d21 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -546,6 +546,27 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
 	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
 }
 
+static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
+{
+	switch (pll->id) {
+	case DPLL_ID_WRPLL1:
+		return PORT_CLK_SEL_WRPLL1;
+	case DPLL_ID_WRPLL2:
+		return PORT_CLK_SEL_WRPLL2;
+	case DPLL_ID_SPLL:
+		return PORT_CLK_SEL_SPLL;
+	case DPLL_ID_LCPLL_810:
+		return PORT_CLK_SEL_LCPLL_810;
+	case DPLL_ID_LCPLL_1350:
+		return PORT_CLK_SEL_LCPLL_1350;
+	case DPLL_ID_LCPLL_2700:
+		return PORT_CLK_SEL_LCPLL_2700;
+	default:
+		MISSING_CASE(pll->id);
+		return PORT_CLK_SEL_NONE;
+	}
+}
+
 /* Starting with Haswell, different DDI ports can work in FDI mode for
  * connection to the PCH-located connectors. For this, it is necessary to train
  * both the DDI port and PCH receiver for the desired DDI buffer settings.
@@ -561,7 +582,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
-	u32 temp, i, rx_ctl_val;
+	u32 temp, i, rx_ctl_val, ddi_pll_sel;
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
@@ -592,8 +613,9 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
 
 	/* Configure Port Clock Select */
-	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
-	WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
+	ddi_pll_sel = hsw_pll_to_ddi_pll_sel(intel_crtc->config->shared_dpll);
+	I915_WRITE(PORT_CLK_SEL(PORT_E), ddi_pll_sel);
+	WARN_ON(ddi_pll_sel != PORT_CLK_SEL_SPLL);
 
 	/* Start the training iterating through available voltages and emphasis,
 	 * testing each value twice. */
@@ -870,7 +892,7 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder,
 	int link_clock = 0;
 	uint32_t dpll_ctl1, dpll;
 
-	dpll = pipe_config->ddi_pll_sel;
+	dpll = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
 
 	dpll_ctl1 = I915_READ(DPLL_CTRL1);
 
@@ -918,7 +940,7 @@ static void hsw_ddi_clock_get(struct intel_encoder *encoder,
 	int link_clock = 0;
 	u32 val, pll;
 
-	val = pipe_config->ddi_pll_sel;
+	val = hsw_pll_to_ddi_pll_sel(pipe_config->shared_dpll);
 	switch (val & PORT_CLK_SEL_MASK) {
 	case PORT_CLK_SEL_LCPLL_810:
 		link_clock = 81000;
@@ -1586,13 +1608,15 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 }
 
 void intel_ddi_clk_select(struct intel_encoder *encoder,
-			  const struct intel_crtc_state *pipe_config)
+			  struct intel_shared_dpll *pll)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = intel_ddi_get_encoder_port(encoder);
 
+	if (WARN_ON(!pll))
+		return;
+
 	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-		uint32_t dpll = pipe_config->ddi_pll_sel;
 		uint32_t val;
 
 		/* DDI -> PLL mapping  */
@@ -1600,14 +1624,13 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 
 		val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
 			DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
-		val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
+		val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->id, port) |
 			DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
 
 		I915_WRITE(DPLL_CTRL2, val);
 
 	} else if (INTEL_INFO(dev_priv)->gen < 9) {
-		WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
-		I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
+		I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll));
 	}
 }
 
@@ -1630,7 +1653,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		intel_edp_panel_on(intel_dp);
 	}
 
-	intel_ddi_clk_select(intel_encoder, crtc->config);
+	intel_ddi_clk_select(intel_encoder, crtc->config->shared_dpll);
 
 	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d224f64..23b05c3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10318,15 +10318,12 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
 
 	switch (port) {
 	case PORT_A:
-		pipe_config->ddi_pll_sel = SKL_DPLL0;
 		id = DPLL_ID_SKL_DPLL0;
 		break;
 	case PORT_B:
-		pipe_config->ddi_pll_sel = SKL_DPLL1;
 		id = DPLL_ID_SKL_DPLL1;
 		break;
 	case PORT_C:
-		pipe_config->ddi_pll_sel = SKL_DPLL2;
 		id = DPLL_ID_SKL_DPLL2;
 		break;
 	default:
@@ -10345,25 +10342,10 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
 	u32 temp;
 
 	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
-	pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
+	id = temp >> (port * 3 + 1);
 
-	switch (pipe_config->ddi_pll_sel) {
-	case SKL_DPLL0:
-		id = DPLL_ID_SKL_DPLL0;
-		break;
-	case SKL_DPLL1:
-		id = DPLL_ID_SKL_DPLL1;
-		break;
-	case SKL_DPLL2:
-		id = DPLL_ID_SKL_DPLL2;
-		break;
-	case SKL_DPLL3:
-		id = DPLL_ID_SKL_DPLL3;
-		break;
-	default:
-		MISSING_CASE(pipe_config->ddi_pll_sel);
+	if (WARN_ON(id < SKL_DPLL0 || id > SKL_DPLL3))
 		return;
-	}
 
 	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
 }
@@ -10373,10 +10355,9 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 				struct intel_crtc_state *pipe_config)
 {
 	enum intel_dpll_id id;
+	uint32_t ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
 
-	pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
-
-	switch (pipe_config->ddi_pll_sel) {
+	switch (ddi_pll_sel) {
 	case PORT_CLK_SEL_WRPLL1:
 		id = DPLL_ID_WRPLL1;
 		break;
@@ -10396,7 +10377,7 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 		id = DPLL_ID_LCPLL_2700;
 		break;
 	default:
-		MISSING_CASE(pipe_config->ddi_pll_sel);
+		MISSING_CASE(ddi_pll_sel);
 		/* fall through */
 	case PORT_CLK_SEL_NONE:
 		return;
@@ -12668,10 +12649,9 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 	DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
 
 	if (IS_BROXTON(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
+		DRM_DEBUG_KMS("dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
 			      "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
 			      "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
 			      pipe_config->dpll_hw_state.ebb0,
 			      pipe_config->dpll_hw_state.ebb4,
 			      pipe_config->dpll_hw_state.pll0,
@@ -12684,15 +12664,13 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			      pipe_config->dpll_hw_state.pll10,
 			      pipe_config->dpll_hw_state.pcsdw12);
 	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
+		DRM_DEBUG_KMS("dpll_hw_state: "
 			      "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
 			      pipe_config->dpll_hw_state.ctrl1,
 			      pipe_config->dpll_hw_state.cfgcr1,
 			      pipe_config->dpll_hw_state.cfgcr2);
 	} else if (HAS_DDI(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
+		DRM_DEBUG_KMS("dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
 			      pipe_config->dpll_hw_state.wrpll,
 			      pipe_config->dpll_hw_state.spll);
 	} else {
@@ -12805,7 +12783,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	struct intel_crtc_scaler_state scaler_state;
 	struct intel_dpll_hw_state dpll_hw_state;
 	struct intel_shared_dpll *shared_dpll;
-	uint32_t ddi_pll_sel;
 	bool force_thru;
 
 	/* FIXME: before the switch to atomic started, a new pipe_config was
@@ -12817,7 +12794,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	scaler_state = crtc_state->scaler_state;
 	shared_dpll = crtc_state->shared_dpll;
 	dpll_hw_state = crtc_state->dpll_hw_state;
-	ddi_pll_sel = crtc_state->ddi_pll_sel;
 	force_thru = crtc_state->pch_pfit.force_thru;
 
 	memset(crtc_state, 0, sizeof *crtc_state);
@@ -12826,7 +12802,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	crtc_state->scaler_state = scaler_state;
 	crtc_state->shared_dpll = shared_dpll;
 	crtc_state->dpll_hw_state = dpll_hw_state;
-	crtc_state->ddi_pll_sel = ddi_pll_sel;
 	crtc_state->pch_pfit.force_thru = force_thru;
 }
 
@@ -13255,8 +13230,6 @@ intel_pipe_config_compare(struct drm_device *dev,
 
 	PIPE_CONF_CHECK_I(double_wide);
 
-	PIPE_CONF_CHECK_X(ddi_pll_sel);
-
 	PIPE_CONF_CHECK_P(shared_dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index e654fea..131881d 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -170,7 +170,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	intel_mst->connector = found;
 
 	if (intel_dp->active_mst_links == 0) {
-		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
+		intel_ddi_clk_select(&intel_dig_port->base,
+				     intel_crtc->config->shared_dpll);
 
 		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
 		intel_dp_set_link_params(intel_dp,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 5c1f2d2..0e1af4d 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -452,26 +452,6 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
 	return val & SPLL_PLL_ENABLE;
 }
 
-static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
-{
-	switch (pll->id) {
-	case DPLL_ID_WRPLL1:
-		return PORT_CLK_SEL_WRPLL1;
-	case DPLL_ID_WRPLL2:
-		return PORT_CLK_SEL_WRPLL2;
-	case DPLL_ID_SPLL:
-		return PORT_CLK_SEL_SPLL;
-	case DPLL_ID_LCPLL_810:
-		return PORT_CLK_SEL_LCPLL_810;
-	case DPLL_ID_LCPLL_1350:
-		return PORT_CLK_SEL_LCPLL_1350;
-	case DPLL_ID_LCPLL_2700:
-		return PORT_CLK_SEL_LCPLL_2700;
-	default:
-		return PORT_CLK_SEL_NONE;
-	}
-}
-
 #define LC_FREQ 2700
 #define LC_FREQ_2K U64_C(LC_FREQ * 2000)
 
@@ -751,8 +731,6 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	if (!pll)
 		return NULL;
 
-	crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
-
 	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
@@ -1274,8 +1252,6 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	if (!pll)
 		return NULL;
 
-	crtc_state->ddi_pll_sel = pll->id;
-
 	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
@@ -1622,9 +1598,6 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 
 	intel_reference_shared_dpll(pll, crtc_state);
 
-	/* shared DPLL id 0 is DPLL A */
-	crtc_state->ddi_pll_sel = pll->id;
-
 	return pll;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 990a9b9..9963e5f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -578,12 +578,6 @@ struct intel_crtc_state {
 	/* Selected dpll when shared or NULL. */
 	struct intel_shared_dpll *shared_dpll;
 
-	/*
-	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
-	 * - enum skl_dpll on SKL
-	 */
-	uint32_t ddi_pll_sel;
-
 	/* Actual register state of the dpll, for shared dpll cross-checking. */
 	struct intel_dpll_hw_state dpll_hw_state;
 
@@ -1124,7 +1118,7 @@ void intel_crt_reset(struct drm_encoder *encoder);
 
 /* intel_ddi.c */
 void intel_ddi_clk_select(struct intel_encoder *encoder,
-			  const struct intel_crtc_state *pipe_config);
+			  struct intel_shared_dpll *pll);
 void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder);
 void hsw_fdi_link_train(struct drm_crtc *crtc);
 void intel_ddi_init(struct drm_device *dev, enum port port);
-- 
1.9.1

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

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

* [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
  2016-08-19 23:33 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
  2016-08-19 23:33 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

Split intel_ddi_pre_enable() into encoder type specific versions that
don't depend on crtc_state. The necessary parameters are passed as
function arguments. This split will be necessary for implementing DP
upfront link training.

v2:
* Rebased onto kernel v4.7 (Jim)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 96 +++++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8c87d21..dfb3fb6 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1634,59 +1634,73 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 	}
 }
 
-static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
+				    int link_rate, uint32_t lane_count,
+				    struct intel_shared_dpll *pll,
+				    bool link_mst)
 {
-	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
-	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
-	enum port port = intel_ddi_get_encoder_port(intel_encoder);
-	int type = intel_encoder->type;
-
-	if (type == INTEL_OUTPUT_HDMI) {
-		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = intel_ddi_get_encoder_port(encoder);
 
-		intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
-	}
+	intel_dp_set_link_params(intel_dp, link_rate, lane_count,
+				 link_mst);
 
-	if (type == INTEL_OUTPUT_EDP) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	if (encoder->type == INTEL_OUTPUT_EDP)
 		intel_edp_panel_on(intel_dp);
-	}
-
-	intel_ddi_clk_select(intel_encoder, crtc->config->shared_dpll);
 
-	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	intel_ddi_clk_select(encoder, pll);
+	intel_prepare_dp_ddi_buffers(encoder);
+	intel_ddi_init_dp_buf_reg(encoder);
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_start_link_train(intel_dp);
+	if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
+		intel_dp_stop_link_train(intel_dp);
+}
 
-		intel_prepare_dp_ddi_buffers(intel_encoder);
+static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
+				      bool has_hdmi_sink,
+				      struct drm_display_mode *adjusted_mode,
+				      struct intel_shared_dpll *pll)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct drm_encoder *drm_encoder = &encoder->base;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	int level = intel_ddi_hdmi_level(dev_priv, port);
 
-		intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
-					 crtc->config->lane_count,
-					 intel_crtc_has_type(crtc->config,
-							     INTEL_OUTPUT_DP_MST));
+	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_ddi_clk_select(encoder, pll);
+	intel_prepare_hdmi_ddi_buffers(encoder);
 
-		intel_ddi_init_dp_buf_reg(intel_encoder);
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		skl_ddi_set_iboost(encoder, level);
+	else if (IS_BROXTON(dev_priv))
+		bxt_ddi_vswing_sequence(dev_priv, level, port,
+					INTEL_OUTPUT_HDMI);
 
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-		intel_dp_start_link_train(intel_dp);
-		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
-			intel_dp_stop_link_train(intel_dp);
-	} else if (type == INTEL_OUTPUT_HDMI) {
-		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-		int level = intel_ddi_hdmi_level(dev_priv, port);
+	intel_hdmi->set_infoframes(drm_encoder, has_hdmi_sink, adjusted_mode);
+}
 
-		intel_prepare_hdmi_ddi_buffers(intel_encoder);
+static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	int type = intel_encoder->type;
 
-		if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
-			skl_ddi_set_iboost(intel_encoder, level);
-		else if (IS_BROXTON(dev_priv))
-			bxt_ddi_vswing_sequence(dev_priv, level, port,
-						INTEL_OUTPUT_HDMI);
+	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP)
+		intel_ddi_pre_enable_dp(intel_encoder,
+					crtc->config->port_clock,
+					crtc->config->lane_count,
+					crtc->config->shared_dpll,
+					intel_crtc_has_type(crtc->config,
+							    INTEL_OUTPUT_DP_MST));
 
-		intel_hdmi->set_infoframes(encoder,
-					   crtc->config->has_hdmi_sink,
-					   &crtc->config->base.adjusted_mode);
-	}
+	if (type == INTEL_OUTPUT_HDMI)
+		intel_ddi_pre_enable_hdmi(intel_encoder,
+					crtc->config->has_hdmi_sink,
+					&crtc->config->base.adjusted_mode,
+					crtc->config->shared_dpll);
 }
 
 static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
-- 
1.9.1

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

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

* [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (2 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Durgadoss R <durgadoss.r@intel.com>

Split out of bxt_ddi_pll_select() the logic that calculates the pll
dividers and dpll_hw_state into a new function that doesn't depend on
crtc state. This will be used for enabling the port pll when doing
upfront link training.

v2:
* Refactored code so that bxt_clk_div need not be exported (Durga)
v1:
* Rebased on top of intel_dpll_mgr.c (Durga)
* Initial version from Ander on top of intel_ddi.c

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 165 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   3 +
 2 files changed, 104 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 0e1af4d..61d2311 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1460,6 +1460,8 @@ struct bxt_clk_div {
 	uint32_t m2_frac;
 	bool m2_frac_en;
 	uint32_t n;
+
+	int vco;
 };
 
 /* pre-calculated values for DP linkrates */
@@ -1473,57 +1475,60 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = {
 	{432000, 3, 1, 32, 1677722, 1, 1}
 };
 
-static struct intel_shared_dpll *
-bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
-	     struct intel_encoder *encoder)
+static bool
+bxt_ddi_hdmi_pll_dividers(struct intel_crtc *intel_crtc,
+			  struct intel_crtc_state *crtc_state, int clock,
+			  struct bxt_clk_div *clk_div)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-	struct intel_digital_port *intel_dig_port;
-	struct bxt_clk_div clk_div = {0};
-	int vco = 0;
-	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
-	uint32_t lanestagger;
-	int clock = crtc_state->port_clock;
+	struct dpll best_clock;
 
-	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		struct dpll best_clock;
+	/* Calculate HDMI div */
+	/*
+	 * FIXME: tie the following calculation into
+	 * i9xx_crtc_compute_clock
+	 */
+	if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
+		DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
+				 clock, pipe_name(intel_crtc->pipe));
+		return false;
+	}
 
-		/* Calculate HDMI div */
-		/*
-		 * FIXME: tie the following calculation into
-		 * i9xx_crtc_compute_clock
-		 */
-		if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
-			DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
-					 clock, pipe_name(crtc->pipe));
-			return NULL;
-		}
+	clk_div->p1 = best_clock.p1;
+	clk_div->p2 = best_clock.p2;
+	WARN_ON(best_clock.m1 != 2);
+	clk_div->n = best_clock.n;
+	clk_div->m2_int = best_clock.m2 >> 22;
+	clk_div->m2_frac = best_clock.m2 & ((1 << 22) - 1);
+	clk_div->m2_frac_en = clk_div->m2_frac != 0;
 
-		clk_div.p1 = best_clock.p1;
-		clk_div.p2 = best_clock.p2;
-		WARN_ON(best_clock.m1 != 2);
-		clk_div.n = best_clock.n;
-		clk_div.m2_int = best_clock.m2 >> 22;
-		clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
-		clk_div.m2_frac_en = clk_div.m2_frac != 0;
+	clk_div->vco = best_clock.vco;
 
-		vco = best_clock.vco;
-	} else if (encoder->type == INTEL_OUTPUT_DP ||
-		   encoder->type == INTEL_OUTPUT_EDP) {
-		int i;
+	return true;
+}
 
-		clk_div = bxt_dp_clk_val[0];
-		for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
-			if (bxt_dp_clk_val[i].clock == clock) {
-				clk_div = bxt_dp_clk_val[i];
-				break;
-			}
+static void bxt_ddi_dp_pll_dividers(int clock, struct bxt_clk_div *clk_div)
+{
+	int i;
+
+	*clk_div = bxt_dp_clk_val[0];
+	for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
+		if (bxt_dp_clk_val[i].clock == clock) {
+			*clk_div = bxt_dp_clk_val[i];
+			break;
 		}
-		vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
 	}
 
+	clk_div->vco = clock * 10 / 2 * clk_div->p1 * clk_div->p2;
+}
+
+static bool bxt_ddi_set_dpll_hw_state(int clock,
+			  struct bxt_clk_div *clk_div,
+			  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	int vco = clk_div->vco;
+	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
+	uint32_t lanestagger;
+
 	if (vco >= 6200000 && vco <= 6700000) {
 		prop_coef = 4;
 		int_coef = 9;
@@ -1542,12 +1547,9 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 		targ_cnt = 9;
 	} else {
 		DRM_ERROR("Invalid VCO\n");
-		return NULL;
+		return false;
 	}
 
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
 	if (clock > 270000)
 		lanestagger = 0x18;
 	else if (clock > 135000)
@@ -1559,33 +1561,68 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	else
 		lanestagger = 0x02;
 
-	crtc_state->dpll_hw_state.ebb0 =
-		PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
-	crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
-	crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
-	crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
+	dpll_hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
+	dpll_hw_state->pll0 = clk_div->m2_int;
+	dpll_hw_state->pll1 = PORT_PLL_N(clk_div->n);
+	dpll_hw_state->pll2 = clk_div->m2_frac;
 
-	if (clk_div.m2_frac_en)
-		crtc_state->dpll_hw_state.pll3 =
-			PORT_PLL_M2_FRAC_ENABLE;
+	if (clk_div->m2_frac_en)
+		dpll_hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
 
-	crtc_state->dpll_hw_state.pll6 =
-		prop_coef | PORT_PLL_INT_COEFF(int_coef);
-	crtc_state->dpll_hw_state.pll6 |=
-		PORT_PLL_GAIN_CTL(gain_ctl);
+	dpll_hw_state->pll6 = prop_coef | PORT_PLL_INT_COEFF(int_coef);
+	dpll_hw_state->pll6 |= PORT_PLL_GAIN_CTL(gain_ctl);
 
-	crtc_state->dpll_hw_state.pll8 = targ_cnt;
+	dpll_hw_state->pll8 = targ_cnt;
 
-	crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
+	dpll_hw_state->pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
 
-	crtc_state->dpll_hw_state.pll10 =
+	dpll_hw_state->pll10 =
 		PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
 		| PORT_PLL_DCO_AMP_OVR_EN_H;
 
-	crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+	dpll_hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+
+	dpll_hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
+
+	return true;
+}
+
+bool bxt_ddi_dp_set_dpll_hw_state(int clock,
+			  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	struct bxt_clk_div clk_div = {0};
+
+	bxt_ddi_dp_pll_dividers(clock, &clk_div);
+
+	return bxt_ddi_set_dpll_hw_state(clock, &clk_div, dpll_hw_state);
+}
+
+static struct intel_shared_dpll *
+bxt_get_dpll(struct intel_crtc *crtc,
+		struct intel_crtc_state *crtc_state,
+		struct intel_encoder *encoder)
+{
+	struct bxt_clk_div clk_div = {0};
+	struct intel_dpll_hw_state dpll_hw_state = {0};
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_digital_port *intel_dig_port;
+	struct intel_shared_dpll *pll;
+	int i, clock = crtc_state->port_clock;
+
+	if (encoder->type == INTEL_OUTPUT_HDMI
+	    && !bxt_ddi_hdmi_pll_dividers(crtc, crtc_state,
+					  clock, &clk_div))
+			return false;
+
+	if ((encoder->type == INTEL_OUTPUT_DP ||
+		encoder->type == INTEL_OUTPUT_EDP) &&
+		!bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
+			return false;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
 
-	crtc_state->dpll_hw_state.pcsdw12 =
-		LANESTAGGER_STRAP_OVRD | lanestagger;
+	crtc_state->dpll_hw_state = dpll_hw_state;
 
 	intel_dig_port = enc_to_dig_port(&encoder->base);
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 89c5ada..11a85a5 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -160,5 +160,8 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc);
 void intel_shared_dpll_commit(struct drm_atomic_state *state);
 void intel_shared_dpll_init(struct drm_device *dev);
 
+/* BXT dpll related functions */
+bool bxt_ddi_dp_set_dpll_hw_state(int clock,
+			  struct intel_dpll_hw_state *dpll_hw_state);
 
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (3 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-20  9:51   ` David Weinehall
  2016-08-19 23:33 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx

From: Durgadoss R <durgadoss.r@intel.com>

To support USB type C alternate DP mode, the display driver needs to
know the number of lanes required by the DP panel as well as number
of lanes that can be supported by the type-C cable. Sometimes, the
type-C cable may limit the bandwidth even if Panel can support
more lanes. To address these scenarios, the display driver will
start link training with max lanes, and if that fails, the driver
falls back to x2 lanes; and repeats this procedure for all
bandwidth/lane configurations.

* Since link training is done before modeset only the port
  (and not pipe/planes) and its associated PLLs are enabled.
* On DP hotplug: Directly start link training on the DP encoder.
* On Connected boot scenarios: When booted with an LFP and a DP,
  sometimes BIOS brings up DP. In these cases, we disable the
  crtc and then do upfront link training; and bring it back up.
* All local changes made for upfront link training are reset
  to their previous values once it is done; so that the
  subsequent modeset is not aware of these changes.

Changes since v8:
* Reset upfront lane count and link rate values on HPD
for DP connector physical disconnect (Manasi)
Changes since v7:
* Move the upfront link training to intel_dp_mode_valid()
  to avoid a race condition with DP MST sideband comms. (Ville)
Changes since v6:
* Fix some initialization bugs on link_rate (Jim Bride)
* Use link_rate (and not link_bw) for upfront (Ville)
* Make intel_dp_upfront*() as a vfunc (Ander)
* The train_set_valid variable in intel_dp was removed due to
  issues in fast link training. So, to indicate the link train
  status, move the channel_eq inside intel_dp.
Changes since v5:
* Moved retry logic in upfront to intel_dp.c so that it
  can be used for all platforms.
Changes since v4:
* Removed usage of crtc_state in upfront link training;
  Hence no need to find free crtc to do upfront now.
* Re-enable crtc if it was disabled for upfront.
* Use separate variables to track max lane count
  and link rate found by upfront, without modifying
  the original DPCD read from panel.
Changes since v3:
* Fixed a return value on BXT check
* Reworked on top of bxt_ddi_pll_select split from Ander
* Renamed from ddi_upfront to bxt_upfront since the
  upfront logic includes BXT specific functions for now.
Changes since v2:
* Rebased on top of latest dpll_mgr.c code and
  latest HPD related clean ups.
* Corrected return values from upfront (Ander)
* Corrected atomic locking for upfront in intel_dp.c (Ville)
Changes since v1:
*  all pll related functions inside ddi.c

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c              |  47 ++++
 drivers/gpu/drm/i915/intel_dp.c               | 372 +++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_dp_link_training.c |   7 +-
 drivers/gpu/drm/i915/intel_drv.h              |  16 ++
 4 files changed, 339 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index dfb3fb6..3921230 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2378,6 +2378,53 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
 	return connector;
 }
 
+
+bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+				  int clock, uint8_t lane_count,
+				  bool link_mst)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = connector->encoder;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config tmp_pll_config;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
+
+	/*
+	 * FIXME: Works only for BXT.
+	 * Select the required PLL. This works for platforms where
+	 * there is no shared DPLL.
+	 */
+	pll = &dev_priv->shared_dplls[dpll_id];
+	if (WARN_ON(pll->active_mask)) {
+		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
+		return false;
+	}
+
+	tmp_pll_config = pll->config;
+
+	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
+		DRM_ERROR("Could not setup DPLL\n");
+		pll->config = tmp_pll_config;
+		return false;
+	}
+
+	/* Enable PLL followed by port */
+	pll->funcs.enable(dev_priv, pll);
+	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
+
+	DRM_DEBUG_KMS("Upfront link train %s: link_clock:%d lanes:%d\n",
+	intel_dp->channel_eq_status ? "Passed" : "Failed", clock, lane_count);
+
+	/* Disable port followed by PLL for next retry/clean up */
+	intel_ddi_post_disable(encoder);
+	pll->funcs.disable(dev_priv, pll);
+
+	pll->config = tmp_pll_config;
+	return intel_dp->channel_eq_status;
+}
+
 void intel_ddi_init(struct drm_device *dev, enum port port)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2cfb2ae..5e362eb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -153,12 +153,21 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
 static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	u8 source_max, sink_max;
+	u8 temp, source_max, sink_max;
 
 	source_max = intel_dig_port->max_lanes;
 	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
 
-	return min(source_max, sink_max);
+	temp = min(source_max, sink_max);
+
+	/*
+	 * Limit max lanes w.r.t to the max value found
+	 * using Upfront link training also.
+	 */
+	if (intel_dp->max_lanes_upfront)
+		return min(temp, intel_dp->max_lanes_upfront);
+	else
+		return temp;
 }
 
 /*
@@ -190,6 +199,224 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static int intel_dp_upfront_crtc_disable(struct intel_crtc *crtc,
+				struct drm_modeset_acquire_ctx *ctx,
+				bool enable)
+{
+	int ret;
+	struct drm_atomic_state *state;
+	struct intel_crtc_state *crtc_state;
+	struct drm_device *dev = crtc->base.dev;
+	enum pipe pipe = crtc->pipe;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return -ENOMEM;
+
+	state->acquire_ctx = ctx;
+
+	crtc_state = intel_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		drm_atomic_state_free(state);
+		return ret;
+	}
+
+	DRM_DEBUG_KMS("%sabling crtc %c %s upfront link train\n",
+			enable ? "En" : "Dis",
+			pipe_name(pipe),
+			enable ? "after" : "before");
+
+	crtc_state->base.active = enable;
+	ret = drm_atomic_commit(state);
+	if (ret)
+		drm_atomic_state_free(state);
+
+	return ret;
+}
+
+static int
+intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
+{
+	if (intel_dp->num_sink_rates) {
+		*sink_rates = intel_dp->sink_rates;
+		return intel_dp->num_sink_rates;
+	}
+
+	*sink_rates = default_rates;
+
+	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+}
+
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+
+	/* WaDisableHBR2:skl */
+	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
+		return false;
+
+	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
+	    (INTEL_INFO(dev)->gen >= 9))
+		return true;
+	else
+		return false;
+}
+
+static int
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_device *dev = dig_port->base.base.dev;
+	int size;
+
+	if (IS_BROXTON(dev)) {
+		*source_rates = bxt_rates;
+		size = ARRAY_SIZE(bxt_rates);
+	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		*source_rates = skl_rates;
+		size = ARRAY_SIZE(skl_rates);
+	} else {
+		*source_rates = default_rates;
+		size = ARRAY_SIZE(default_rates);
+	}
+
+	/* This depends on the fact that 5.4 is last value in the array */
+	if (!intel_dp_source_supports_hbr2(intel_dp))
+		size--;
+
+	return size;
+}
+
+static int intersect_rates(const int *source_rates, int source_len,
+			   const int *sink_rates, int sink_len,
+			   int *common_rates)
+{
+	int i = 0, j = 0, k = 0;
+
+	while (i < source_len && j < sink_len) {
+		if (source_rates[i] == sink_rates[j]) {
+			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
+				return k;
+			common_rates[k] = source_rates[i];
+			++k;
+			++i;
+			++j;
+		} else if (source_rates[i] < sink_rates[j]) {
+			++i;
+		} else {
+			++j;
+		}
+	}
+	return k;
+}
+
+static int intel_dp_common_rates(struct intel_dp *intel_dp,
+				 int *common_rates)
+{
+	const int *source_rates, *sink_rates;
+	int source_len, sink_len;
+
+	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+
+	/* Cap sink rates w.r.t upfront values */
+	if (intel_dp->max_link_rate_upfront) {
+		int len = sink_len - 1;
+		while (len > 0 && sink_rates[len] > intel_dp->max_link_rate_upfront)
+			len--;
+		sink_len = len + 1;
+	}
+
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
+
+	return intersect_rates(source_rates, source_len,
+			       sink_rates, sink_len,
+			       common_rates);
+}
+
+static bool intel_dp_upfront_link_train(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_modeset_acquire_ctx ctx;
+	struct intel_crtc *intel_crtc;
+	struct drm_crtc *crtc = NULL;
+	int ret;
+	bool done = false, has_mst = false;
+	uint8_t lane_count, max_lanes = 4;
+	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
+	int clock, common_len;
+	enum intel_display_power_domain power_domain;
+
+	power_domain = intel_display_port_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+	if (WARN_ON(common_len <= 0))
+		return true;
+
+	drm_modeset_acquire_init(&ctx, 0);
+retry:
+	ret = drm_modeset_lock(&config->connection_mutex, &ctx);
+	if (ret)
+		goto exit_fail;
+
+	if (intel_encoder->base.crtc) {
+		crtc = intel_encoder->base.crtc;
+
+		ret = drm_modeset_lock(&crtc->mutex, &ctx);
+		if (ret)
+			goto exit_fail;
+
+		ret = drm_modeset_lock(&crtc->primary->mutex, &ctx);
+		if (ret)
+			goto exit_fail;
+
+		intel_crtc = to_intel_crtc(crtc);
+		has_mst = intel_crtc_has_type(intel_crtc->config,
+					      INTEL_OUTPUT_DP_MST);
+		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, false);
+		if (ret)
+			goto exit_fail;
+	}
+
+	mutex_lock(&dev_priv->dpll_lock);
+
+	for (lane_count = max_lanes; lane_count >= 1 && !done;
+	     lane_count >>= 1) {
+		for (clock = common_len - 1; clock >= 0 && !done; clock--) {
+			done = intel_dp->upfront_link_train(intel_dp,
+							    common_rates[clock],
+							    lane_count,
+							    has_mst);
+			if (done) {
+				intel_dp->max_lanes_upfront = lane_count;
+				intel_dp->max_link_rate_upfront = common_rates[clock];
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&dev_priv->dpll_lock);
+
+	if (crtc)
+		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, true);
+
+exit_fail:
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+	intel_display_power_put(dev_priv, power_domain);
+	return done;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -211,6 +438,19 @@ intel_dp_mode_valid(struct drm_connector *connector,
 		target_clock = fixed_mode->clock;
 	}
 
+	if (intel_dp->upfront_link_train && !intel_dp->upfront_done) {
+		bool do_upfront_link_train;
+		/* Do not do upfront link train, if it is a compliance
+		 * request
+		 */
+		do_upfront_link_train = !intel_dp->upfront_done &&
+			(intel_dp->compliance_test_type !=
+			 DP_TEST_LINK_TRAINING);
+
+		if (do_upfront_link_train)
+			intel_dp->upfront_done = intel_dp_upfront_link_train(intel_dp);
+	}
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -1256,60 +1496,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
 }
 
-static int
-intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
-{
-	if (intel_dp->num_sink_rates) {
-		*sink_rates = intel_dp->sink_rates;
-		return intel_dp->num_sink_rates;
-	}
-
-	*sink_rates = default_rates;
-
-	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
-}
-
-bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-
-	/* WaDisableHBR2:skl */
-	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
-		return false;
-
-	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
-	    (INTEL_INFO(dev)->gen >= 9))
-		return true;
-	else
-		return false;
-}
-
-static int
-intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-	int size;
-
-	if (IS_BROXTON(dev)) {
-		*source_rates = bxt_rates;
-		size = ARRAY_SIZE(bxt_rates);
-	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-		*source_rates = skl_rates;
-		size = ARRAY_SIZE(skl_rates);
-	} else {
-		*source_rates = default_rates;
-		size = ARRAY_SIZE(default_rates);
-	}
-
-	/* This depends on the fact that 5.4 is last value in the array */
-	if (!intel_dp_source_supports_hbr2(intel_dp))
-		size--;
-
-	return size;
-}
-
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
 		   struct intel_crtc_state *pipe_config)
@@ -1343,42 +1529,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
 	}
 }
 
-static int intersect_rates(const int *source_rates, int source_len,
-			   const int *sink_rates, int sink_len,
-			   int *common_rates)
-{
-	int i = 0, j = 0, k = 0;
-
-	while (i < source_len && j < sink_len) {
-		if (source_rates[i] == sink_rates[j]) {
-			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
-				return k;
-			common_rates[k] = source_rates[i];
-			++k;
-			++i;
-			++j;
-		} else if (source_rates[i] < sink_rates[j]) {
-			++i;
-		} else {
-			++j;
-		}
-	}
-	return k;
-}
-
-static int intel_dp_common_rates(struct intel_dp *intel_dp,
-				 int *common_rates)
-{
-	const int *source_rates, *sink_rates;
-	int source_len, sink_len;
-
-	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
-	source_len = intel_dp_source_rates(intel_dp, &source_rates);
-
-	return intersect_rates(source_rates, source_len,
-			       sink_rates, sink_len,
-			       common_rates);
-}
 
 static void snprintf_int_array(char *str, size_t len,
 			       const int *array, int nelem)
@@ -1436,6 +1586,9 @@ intel_dp_max_link_rate(struct intel_dp *intel_dp)
 	int rates[DP_MAX_SUPPORTED_RATES] = {};
 	int len;
 
+	if (intel_dp->max_link_rate_upfront)
+		return intel_dp->max_link_rate_upfront;
+
 	len = intel_dp_common_rates(intel_dp, rates);
 	if (WARN_ON(len <= 0))
 		return 162000;
@@ -1472,7 +1625,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	enum port port = dp_to_dig_port(intel_dp)->port;
 	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int lane_count, clock;
+	int lane_count, clock = 0;
 	int min_lane_count = 1;
 	int max_lane_count = intel_dp_max_lane_count(intel_dp);
 	/* Conveniently, the link BW constants become indices with a shift...*/
@@ -1551,11 +1704,23 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	for (; bpp >= 6*3; bpp -= 2*3) {
 		mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
 						   bpp);
+		if (!is_edp(intel_dp) && intel_dp->upfront_done) {
+			clock = max_clock;
+			lane_count = intel_dp->max_lanes_upfront;
+			link_clock = intel_dp->max_link_rate_upfront;
+			link_avail = intel_dp_max_data_rate(link_clock, lane_count);
+			mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
+							   bpp);
+			if (mode_rate <= link_avail)
+				goto found;
+			else
+				continue;
+		}
 
 		for (clock = min_clock; clock <= max_clock; clock++) {
 			for (lane_count = min_lane_count;
-				lane_count <= max_lane_count;
-				lane_count <<= 1) {
+			     lane_count <= max_lane_count;
+			     lane_count <<= 1) {
 
 				link_clock = common_rates[clock];
 				link_avail = intel_dp_max_data_rate(link_clock,
@@ -1565,6 +1730,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 					goto found;
 				}
 			}
+
 		}
 	}
 
@@ -1585,7 +1751,6 @@ found:
 	}
 
 	pipe_config->lane_count = lane_count;
-
 	pipe_config->pipe_bpp = bpp;
 	pipe_config->port_clock = common_rates[clock];
 
@@ -4244,7 +4409,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status;
 	enum intel_display_power_domain power_domain;
-	u8 sink_irq_vector = 0;
+	u8 sink_irq_vector;
 
 	power_domain = intel_display_port_aux_power_domain(intel_encoder);
 	intel_display_power_get(to_i915(dev), power_domain);
@@ -4337,9 +4502,12 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 	}
 
 out:
-	if ((status != connector_status_connected) &&
-	    (intel_dp->is_mst == false))
+	if (status != connector_status_connected) {
 		intel_dp_unset_edid(intel_dp);
+		intel_dp->upfront_done = false;
+		intel_dp->max_lanes_upfront = 0;
+		intel_dp->max_link_rate_upfront = 0;
+	}
 
 	intel_display_power_put(to_i915(dev), power_domain);
 	return;
@@ -5587,6 +5755,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	if (type == DRM_MODE_CONNECTOR_eDP)
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 
+	/* Initialize upfront link training vfunc for DP */
+	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
+		if (IS_BROXTON(dev))
+			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
+	}
+
 	/* eDP only on port B and/or C on vlv/chv */
 	if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
 		    is_edp(intel_dp) && port != PORT_B && port != PORT_C))
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 60fb39c..e58442a 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -232,7 +232,6 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 static void
 intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 {
-	bool channel_eq = false;
 	int tries, cr_tries;
 	u32 training_pattern;
 
@@ -248,7 +247,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	tries = 0;
 	cr_tries = 0;
-	channel_eq = false;
+	intel_dp->channel_eq_status = false;
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
 
@@ -276,7 +275,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 		if (drm_dp_channel_eq_ok(link_status,
 					 intel_dp->lane_count)) {
-			channel_eq = true;
+			intel_dp->channel_eq_status = true;
 			break;
 		}
 
@@ -302,7 +301,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	intel_dp_set_idle_link_train(intel_dp);
 
-	if (channel_eq)
+	if (intel_dp->channel_eq_status)
 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 9963e5f..8b3d062 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -869,6 +869,15 @@ struct intel_dp {
 	enum hdmi_force_audio force_audio;
 	bool limited_color_range;
 	bool color_range_auto;
+
+	/* Whether Channel Equalization was achieved during Link training */
+	bool channel_eq_status;
+
+	/* Upfront link train parameters */
+	int max_link_rate_upfront;
+	uint8_t max_lanes_upfront;
+	bool upfront_done;
+
 	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
 	uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
 	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
@@ -926,6 +935,10 @@ struct intel_dp {
 	/* This is called before a link training is starterd */
 	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
 
+	/* For Upfront link training */
+	bool (*upfront_link_train)(struct intel_dp *intel_dp, int clock,
+				   uint8_t lane_count, bool link_mst);
+
 	/* Displayport compliance testing */
 	unsigned long compliance_test_type;
 	unsigned long compliance_test_data;
@@ -1145,6 +1158,9 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
+bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+				  int clock, uint8_t lane_count,
+				  bool link_mst);
 
 unsigned int intel_fb_align_height(struct drm_device *dev,
 				   unsigned int height,
-- 
1.9.1

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

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

* [PATCH 6/9] drm/i915: Split skl_get_dpll()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (4 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx

From: Jim Bride <jim.bride@linux.intel.com>

Split out the DisplayPort and HDMI pll setup code into separate
functions and refactor the DP code does not directly depend on
crtc state, so that the code can be used for upfront link training.

Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   4 ++
 2 files changed, 87 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 61d2311..8ce220e 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1172,75 +1172,110 @@ skip_remaining_dividers:
 	return true;
 }
 
-static struct intel_shared_dpll *
-skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
-	     struct intel_encoder *encoder)
+static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc,
+				      struct intel_crtc_state *crtc_state,
+				      int clock)
 {
-	struct intel_shared_dpll *pll;
 	uint32_t ctrl1, cfgcr1, cfgcr2;
-	int clock = crtc_state->port_clock;
+	struct skl_wrpll_params wrpll_params = { 0, };
 
 	/*
 	 * See comment in intel_dpll_hw_state to understand why we always use 0
 	 * as the DPLL id in this function.
 	 */
-
 	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
 
-	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		struct skl_wrpll_params wrpll_params = { 0, };
+	ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
 
-		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+	if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
+		return false;
 
-		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
-			return NULL;
+	cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+		DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+		wrpll_params.dco_integer;
+
+	cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+		DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+		DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+		DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+		wrpll_params.central_freq;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
+	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
+	return true;
+}
+
+
+bool skl_ddi_dp_set_dpll_hw_state(int clock,
+				  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	uint32_t ctrl1;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+	switch (clock / 2) {
+	case 81000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
+		break;
+	case 135000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
+		break;
+	case 270000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
+		break;
+		/* eDP 1.4 rates */
+	case 162000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
+		break;
+	case 108000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
+		break;
+	case 216000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
+		break;
+	}
 
-		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
-			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
-			 wrpll_params.dco_integer;
+	dpll_hw_state->ctrl1 = ctrl1;
+	return true;
+}
 
-		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
-			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
-			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
-			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
-			 wrpll_params.central_freq;
+static struct intel_shared_dpll *
+skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct intel_shared_dpll *pll;
+	int clock = crtc_state->port_clock;
+	bool bret;
+	struct intel_dpll_hw_state dpll_hw_state;
+
+	memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock);
+		if (!bret) {
+			DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
+			return NULL;
+		}
 	} else if (encoder->type == INTEL_OUTPUT_DP ||
 		   encoder->type == INTEL_OUTPUT_DP_MST ||
 		   encoder->type == INTEL_OUTPUT_EDP) {
-		switch (crtc_state->port_clock / 2) {
-		case 81000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
-			break;
-		case 135000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
-			break;
-		case 270000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
-			break;
-		/* eDP 1.4 rates */
-		case 162000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
-			break;
-		case 108000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
-			break;
-		case 216000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
-			break;
+		bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state);
+		if (!bret) {
+			DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
+			return NULL;
 		}
-
-		cfgcr1 = cfgcr2 = 0;
+		crtc_state->dpll_hw_state = dpll_hw_state;
 	} else {
 		return NULL;
 	}
 
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
-	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
-	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
-	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
-
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		pll = intel_find_shared_dpll(crtc, crtc_state,
 					     DPLL_ID_SKL_DPLL0,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 11a85a5..cb28f8d 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -164,4 +164,8 @@ void intel_shared_dpll_init(struct drm_device *dev);
 bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 			  struct intel_dpll_hw_state *dpll_hw_state);
 
+/* SKL dpll related functions */
+bool skl_ddi_dp_set_dpll_hw_state(int clock,
+				  struct intel_dpll_hw_state *dpll_hw_state);
+
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (5 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-20  9:52   ` David Weinehall
  2016-08-19 23:33 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx

From: Jim Bride <jim.bride@linux.intel.com>

Split the PLL selection code out of the BXT upfront link training
implementation and into a stand-alone function in order to allow
for the implementation of a platform neutral upfront link training
function, and then enable upfront link training for Skylake.

Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 56 ++++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_dp.c       |  4 +--
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 38 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  2 ++
 drivers/gpu/drm/i915/intel_drv.h      |  4 ++-
 5 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 3921230..ef63b4b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2378,8 +2378,43 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
 	return connector;
 }
 
+struct intel_shared_dpll *
+intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = connector->encoder;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_shared_dpll *pll = NULL;
+	struct intel_shared_dpll_config tmp_pll_config;
+	enum intel_dpll_id dpll_id;
+
+	if (IS_BROXTON(dev_priv)) {
+		dpll_id =  (enum intel_dpll_id)dig_port->port;
+		/*
+		 * Select the required PLL. This works for platforms where
+		 * there is no shared DPLL.
+		 */
+		pll = &dev_priv->shared_dplls[dpll_id];
+		if (WARN_ON(pll->active_mask)) {
+
+			DRM_ERROR("Shared DPLL in use. active_mask:%x\n",
+				  pll->active_mask);
+			pll = NULL;
+		}
+		tmp_pll_config = pll->config;
+		if (!bxt_ddi_dp_set_dpll_hw_state(clock,
+						  &pll->config.hw_state)) {
+			DRM_ERROR("Could not setup DPLL\n");
+			pll->config = tmp_pll_config;
+		}
+	} else if (IS_SKYLAKE(dev_priv)) {
+		pll = skl_find_link_pll(dev_priv, clock);
+	}
+	return pll;
+}
 
-bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
 				  int clock, uint8_t lane_count,
 				  bool link_mst)
 {
@@ -2388,28 +2423,15 @@ bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_shared_dpll *pll;
 	struct intel_shared_dpll_config tmp_pll_config;
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
 
-	/*
-	 * FIXME: Works only for BXT.
-	 * Select the required PLL. This works for platforms where
-	 * there is no shared DPLL.
-	 */
-	pll = &dev_priv->shared_dplls[dpll_id];
-	if (WARN_ON(pll->active_mask)) {
-		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
+	pll = intel_ddi_get_link_dpll(intel_dp, clock);
+	if (pll == NULL) {
+		DRM_ERROR("Could not find DPLL for link training.\n");
 		return false;
 	}
 
 	tmp_pll_config = pll->config;
 
-	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
-		DRM_ERROR("Could not setup DPLL\n");
-		pll->config = tmp_pll_config;
-		return false;
-	}
-
 	/* Enable PLL followed by port */
 	pll->funcs.enable(dev_priv, pll);
 	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5e362eb..fe156fb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5757,8 +5757,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev))
-			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
+		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
+			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
 	}
 
 	/* eDP only on port B and/or C on vlv/chv */
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 8ce220e..e5c025e 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -24,6 +24,44 @@
 #include "intel_drv.h"
 
 struct intel_shared_dpll *
+skl_find_link_pll(struct drm_i915_private *dev_priv, int clock)
+{
+	struct intel_shared_dpll *pll = NULL;
+	struct intel_dpll_hw_state dpll_hw_state;
+	enum intel_dpll_id i;
+	bool found = false;
+
+	if (!skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
+		return pll;
+
+	for (i = DPLL_ID_SKL_DPLL1; i <= DPLL_ID_SKL_DPLL3; i++) {
+		pll = &dev_priv->shared_dplls[i];
+
+		/* Only want to check enabled timings first */
+		if (pll->config.crtc_mask == 0)
+			continue;
+
+		if (memcmp(&dpll_hw_state, &pll->config.hw_state,
+			   sizeof(pll->config.hw_state)) == 0) {
+			found = true;
+			break;
+		}
+	}
+
+	/* Ok no matching timings, maybe there's a free one? */
+	for (i = DPLL_ID_SKL_DPLL1;
+	     ((found == false) && (i <= DPLL_ID_SKL_DPLL3)); i++) {
+		pll = &dev_priv->shared_dplls[i];
+		if (pll->config.crtc_mask == 0) {
+			pll->config.hw_state = dpll_hw_state;
+			break;
+		}
+	}
+
+	return pll;
+}
+
+struct intel_shared_dpll *
 intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
 			    enum intel_dpll_id id)
 {
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index cb28f8d..ec0fe66 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -167,5 +167,7 @@ bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 /* SKL dpll related functions */
 bool skl_ddi_dp_set_dpll_hw_state(int clock,
 				  struct intel_dpll_hw_state *dpll_hw_state);
+struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv,
+					    int clock);
 
 #endif /* _INTEL_DPLL_MGR_H_ */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8b3d062..374cbbd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1158,9 +1158,11 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
-bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
 				  int clock, uint8_t lane_count,
 				  bool link_mst);
+struct intel_shared_dpll *intel_ddi_get_link_dpll(struct intel_dp *intel_dp,
+						  int clock);
 
 unsigned int intel_fb_align_height(struct drm_device *dev,
 				   unsigned int height,
-- 
1.9.1

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

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

* [PATCH 8/9] drm/i915: Split hsw_get_dpll()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (6 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-19 23:33 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx

Split out the DisplayPort and HDMI pll setup code into separate
functions and refactor the DP code that calculates the pll
so that it doesn't depend on crtc state.
This will be used for acquiring port pll when doing
upfront link training.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 90 ++++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  6 +++
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index e5c025e..93f7aae 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -705,11 +705,65 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 	*r2_out = best.r2;
 }
 
+static struct intel_shared_dpll *hsw_ddi_hdmi_get_dpll(int clock,
+						       struct intel_crtc *crtc,
+						       struct intel_crtc_state *crtc_state)
+{
+	struct intel_shared_dpll *pll;
+	uint32_t val;
+	unsigned p, n2, r2;
+
+	hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+
+	val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
+	      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
+	      WRPLL_DIVIDER_POST(p);
+
+	crtc_state->dpll_hw_state.wrpll = val;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state,
+				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+
+	if (!pll)
+		return NULL;
+
+	return pll;
+}
+
+struct intel_shared_dpll *hsw_ddi_dp_get_dpll(struct intel_encoder *encoder,
+					      int clock)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id pll_id;
+
+	switch (clock / 2) {
+	case 81000:
+		pll_id = DPLL_ID_LCPLL_810;
+		break;
+	case 135000:
+		pll_id = DPLL_ID_LCPLL_1350;
+		break;
+	case 270000:
+		pll_id = DPLL_ID_LCPLL_2700;
+		break;
+	default:
+		DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
+		return NULL;
+	}
+
+	pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+
+	if (!pll)
+		return NULL;
+
+	return pll;
+}
+
 static struct intel_shared_dpll *
 hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	     struct intel_encoder *encoder)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll;
 	int clock = crtc_state->port_clock;
 
@@ -717,41 +771,12 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	       sizeof(crtc_state->dpll_hw_state));
 
 	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		uint32_t val;
-		unsigned p, n2, r2;
-
-		hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-
-		val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
-		      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
-		      WRPLL_DIVIDER_POST(p);
-
-		crtc_state->dpll_hw_state.wrpll = val;
-
-		pll = intel_find_shared_dpll(crtc, crtc_state,
-					     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+		pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state);
 
 	} else if (encoder->type == INTEL_OUTPUT_DP ||
 		   encoder->type == INTEL_OUTPUT_DP_MST ||
 		   encoder->type == INTEL_OUTPUT_EDP) {
-		enum intel_dpll_id pll_id;
-
-		switch (clock / 2) {
-		case 81000:
-			pll_id = DPLL_ID_LCPLL_810;
-			break;
-		case 135000:
-			pll_id = DPLL_ID_LCPLL_1350;
-			break;
-		case 270000:
-			pll_id = DPLL_ID_LCPLL_2700;
-			break;
-		default:
-			DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
-			return NULL;
-		}
-
-		pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 
 	} else if (encoder->type == INTEL_OUTPUT_ANALOG) {
 		if (WARN_ON(crtc_state->port_clock / 2 != 135000))
@@ -774,7 +799,6 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	return pll;
 }
 
-
 static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
 	.enable = hsw_ddi_wrpll_enable,
 	.disable = hsw_ddi_wrpll_disable,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index ec0fe66..f438535 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -164,10 +164,16 @@ void intel_shared_dpll_init(struct drm_device *dev);
 bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 			  struct intel_dpll_hw_state *dpll_hw_state);
 
+
 /* SKL dpll related functions */
 bool skl_ddi_dp_set_dpll_hw_state(int clock,
 				  struct intel_dpll_hw_state *dpll_hw_state);
 struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv,
 					    int clock);
 
+
+/* HSW dpll related functions */
+struct intel_shared_dpll *hsw_ddi_dp_get_dpll(struct intel_encoder *encoder,
+					      int clock);
+
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (7 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
@ 2016-08-19 23:33 ` Manasi Navare
  2016-08-20  9:46   ` David Weinehall
  2016-08-23  1:41 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-08-19 23:33 UTC (permalink / raw)
  To: intel-gfx

Get the PLLs for HSW/BDW using the platform specific function
and add hooks for enabling upfront link training on HSW and BDW.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ef63b4b..1d3ab8a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
 		}
 	} else if (IS_SKYLAKE(dev_priv)) {
 		pll = skl_find_link_pll(dev_priv, clock);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 	}
 	return pll;
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index fe156fb..a1cea4d 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5757,8 +5757,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
+		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
+		    IS_BROADWELL(dev) || IS_HASWELL(dev))
 			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
+
 	}
 
 	/* eDP only on port B and/or C on vlv/chv */
-- 
1.9.1

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

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

* Re: [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-19 23:33 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
@ 2016-08-20  9:46   ` David Weinehall
  2016-08-22 18:11     ` Manasi Navare
  2016-08-22 18:17     ` Manasi Navare
  0 siblings, 2 replies; 27+ messages in thread
From: David Weinehall @ 2016-08-20  9:46 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Fri, Aug 19, 2016 at 04:33:49PM -0700, Manasi Navare wrote:
> Get the PLLs for HSW/BDW using the platform specific function
> and add hooks for enabling upfront link training on HSW and BDW.
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
>  drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index ef63b4b..1d3ab8a 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
>  		}
>  	} else if (IS_SKYLAKE(dev_priv)) {
>  		pll = skl_find_link_pll(dev_priv, clock);
> +	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> +		pll = hsw_ddi_dp_get_dpll(encoder, clock);
>  	}
>  	return pll;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index fe156fb..a1cea4d 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5757,8 +5757,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  
>  	/* Initialize upfront link training vfunc for DP */
>  	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> -		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
> +		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
> +		    IS_BROADWELL(dev) || IS_HASWELL(dev))
>  			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
> +
>  	}
>  
>  	/* eDP only on port B and/or C on vlv/chv */

s/dev/dev_priv/ in feature macros.  To keep the diff down to a minimum
you can ignore the rest of them, but I certainly wouldn't mind if
you cleanup them all (and change INTEL_INFO()->gen to INTEL_GEN()).


Regards: David Weinehall
-- 
 /) David Weinehall <tao@acc.umu.se> /) Northern lights wander      (\
//  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
\)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT
  2016-08-19 23:33 ` [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
@ 2016-08-20  9:51   ` David Weinehall
  0 siblings, 0 replies; 27+ messages in thread
From: David Weinehall @ 2016-08-20  9:51 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Fri, Aug 19, 2016 at 04:33:45PM -0700, Manasi Navare wrote:
> From: Durgadoss R <durgadoss.r@intel.com>
> 
> To support USB type C alternate DP mode, the display driver needs to
> know the number of lanes required by the DP panel as well as number
> of lanes that can be supported by the type-C cable. Sometimes, the
> type-C cable may limit the bandwidth even if Panel can support
> more lanes. To address these scenarios, the display driver will
> start link training with max lanes, and if that fails, the driver
> falls back to x2 lanes; and repeats this procedure for all
> bandwidth/lane configurations.
> 
> * Since link training is done before modeset only the port
>   (and not pipe/planes) and its associated PLLs are enabled.
> * On DP hotplug: Directly start link training on the DP encoder.
> * On Connected boot scenarios: When booted with an LFP and a DP,
>   sometimes BIOS brings up DP. In these cases, we disable the
>   crtc and then do upfront link training; and bring it back up.
> * All local changes made for upfront link training are reset
>   to their previous values once it is done; so that the
>   subsequent modeset is not aware of these changes.
> 
> Changes since v8:
> * Reset upfront lane count and link rate values on HPD
> for DP connector physical disconnect (Manasi)
> Changes since v7:
> * Move the upfront link training to intel_dp_mode_valid()
>   to avoid a race condition with DP MST sideband comms. (Ville)
> Changes since v6:
> * Fix some initialization bugs on link_rate (Jim Bride)
> * Use link_rate (and not link_bw) for upfront (Ville)
> * Make intel_dp_upfront*() as a vfunc (Ander)
> * The train_set_valid variable in intel_dp was removed due to
>   issues in fast link training. So, to indicate the link train
>   status, move the channel_eq inside intel_dp.
> Changes since v5:
> * Moved retry logic in upfront to intel_dp.c so that it
>   can be used for all platforms.
> Changes since v4:
> * Removed usage of crtc_state in upfront link training;
>   Hence no need to find free crtc to do upfront now.
> * Re-enable crtc if it was disabled for upfront.
> * Use separate variables to track max lane count
>   and link rate found by upfront, without modifying
>   the original DPCD read from panel.
> Changes since v3:
> * Fixed a return value on BXT check
> * Reworked on top of bxt_ddi_pll_select split from Ander
> * Renamed from ddi_upfront to bxt_upfront since the
>   upfront logic includes BXT specific functions for now.
> Changes since v2:
> * Rebased on top of latest dpll_mgr.c code and
>   latest HPD related clean ups.
> * Corrected return values from upfront (Ander)
> * Corrected atomic locking for upfront in intel_dp.c (Ville)
> Changes since v1:
> *  all pll related functions inside ddi.c
> 
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c              |  47 ++++
>  drivers/gpu/drm/i915/intel_dp.c               | 372 +++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_dp_link_training.c |   7 +-
>  drivers/gpu/drm/i915/intel_drv.h              |  16 ++
>  4 files changed, 339 insertions(+), 103 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index dfb3fb6..3921230 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2378,6 +2378,53 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
>  	return connector;
>  }
>  
> +
> +bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
> +				  int clock, uint8_t lane_count,
> +				  bool link_mst)
> +{
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	struct intel_encoder *encoder = connector->encoder;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	struct intel_shared_dpll *pll;
> +	struct intel_shared_dpll_config tmp_pll_config;
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
> +
> +	/*
> +	 * FIXME: Works only for BXT.
> +	 * Select the required PLL. This works for platforms where
> +	 * there is no shared DPLL.
> +	 */
> +	pll = &dev_priv->shared_dplls[dpll_id];
> +	if (WARN_ON(pll->active_mask)) {
> +		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
> +		return false;
> +	}
> +
> +	tmp_pll_config = pll->config;
> +
> +	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
> +		DRM_ERROR("Could not setup DPLL\n");
> +		pll->config = tmp_pll_config;
> +		return false;
> +	}
> +
> +	/* Enable PLL followed by port */
> +	pll->funcs.enable(dev_priv, pll);
> +	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
> +
> +	DRM_DEBUG_KMS("Upfront link train %s: link_clock:%d lanes:%d\n",
> +	intel_dp->channel_eq_status ? "Passed" : "Failed", clock, lane_count);
> +
> +	/* Disable port followed by PLL for next retry/clean up */
> +	intel_ddi_post_disable(encoder);
> +	pll->funcs.disable(dev_priv, pll);
> +
> +	pll->config = tmp_pll_config;
> +	return intel_dp->channel_eq_status;
> +}
> +
>  void intel_ddi_init(struct drm_device *dev, enum port port)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 2cfb2ae..5e362eb 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -153,12 +153,21 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
>  static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> -	u8 source_max, sink_max;
> +	u8 temp, source_max, sink_max;
>  
>  	source_max = intel_dig_port->max_lanes;
>  	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
>  
> -	return min(source_max, sink_max);
> +	temp = min(source_max, sink_max);
> +
> +	/*
> +	 * Limit max lanes w.r.t to the max value found
> +	 * using Upfront link training also.
> +	 */
> +	if (intel_dp->max_lanes_upfront)
> +		return min(temp, intel_dp->max_lanes_upfront);
> +	else
> +		return temp;
>  }
>  
>  /*
> @@ -190,6 +199,224 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>  	return (max_link_clock * max_lanes * 8) / 10;
>  }
>  
> +static int intel_dp_upfront_crtc_disable(struct intel_crtc *crtc,
> +				struct drm_modeset_acquire_ctx *ctx,
> +				bool enable)
> +{
> +	int ret;
> +	struct drm_atomic_state *state;
> +	struct intel_crtc_state *crtc_state;
> +	struct drm_device *dev = crtc->base.dev;
> +	enum pipe pipe = crtc->pipe;
> +
> +	state = drm_atomic_state_alloc(dev);
> +	if (!state)
> +		return -ENOMEM;
> +
> +	state->acquire_ctx = ctx;
> +
> +	crtc_state = intel_atomic_get_crtc_state(state, crtc);
> +	if (IS_ERR(crtc_state)) {
> +		ret = PTR_ERR(crtc_state);
> +		drm_atomic_state_free(state);
> +		return ret;
> +	}
> +
> +	DRM_DEBUG_KMS("%sabling crtc %c %s upfront link train\n",
> +			enable ? "En" : "Dis",
> +			pipe_name(pipe),
> +			enable ? "after" : "before");
> +
> +	crtc_state->base.active = enable;
> +	ret = drm_atomic_commit(state);
> +	if (ret)
> +		drm_atomic_state_free(state);
> +
> +	return ret;
> +}
> +
> +static int
> +intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
> +{
> +	if (intel_dp->num_sink_rates) {
> +		*sink_rates = intel_dp->sink_rates;
> +		return intel_dp->num_sink_rates;
> +	}
> +
> +	*sink_rates = default_rates;
> +
> +	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> +}
> +
> +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_device *dev = dig_port->base.base.dev;

struct drm_i915_private *dev_priv = to_i915(dig_port->base.dev.dev);

> +
> +	/* WaDisableHBR2:skl */
> +	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
> +		return false;

dev_priv

> +
> +	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||

dev_priv, dev_priv, dev_priv

> +	    (INTEL_INFO(dev)->gen >= 9))

INTEL_GEN(dev_priv)

> +		return true;
> +	else
> +		return false;
> +}
> +
> +static int
> +intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
> +{
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct drm_device *dev = dig_port->base.base.dev;

struct drm_i915_private *dev_priv = to_i915(dig_port->base.dev.dev);

> +	int size;
> +
> +	if (IS_BROXTON(dev)) {

dev_priv

> +		*source_rates = bxt_rates;
> +		size = ARRAY_SIZE(bxt_rates);
> +	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
dev_priv, dev_priv

> +		*source_rates = skl_rates;
> +		size = ARRAY_SIZE(skl_rates);
> +	} else {
> +		*source_rates = default_rates;
> +		size = ARRAY_SIZE(default_rates);
> +	}
> +
> +	/* This depends on the fact that 5.4 is last value in the array */
> +	if (!intel_dp_source_supports_hbr2(intel_dp))
> +		size--;
> +
> +	return size;
> +}
> +
> +static int intersect_rates(const int *source_rates, int source_len,
> +			   const int *sink_rates, int sink_len,
> +			   int *common_rates)
> +{
> +	int i = 0, j = 0, k = 0;
> +
> +	while (i < source_len && j < sink_len) {
> +		if (source_rates[i] == sink_rates[j]) {
> +			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> +				return k;
> +			common_rates[k] = source_rates[i];
> +			++k;
> +			++i;
> +			++j;
> +		} else if (source_rates[i] < sink_rates[j]) {
> +			++i;
> +		} else {
> +			++j;
> +		}
> +	}
> +	return k;
> +}
> +
> +static int intel_dp_common_rates(struct intel_dp *intel_dp,
> +				 int *common_rates)
> +{
> +	const int *source_rates, *sink_rates;
> +	int source_len, sink_len;
> +
> +	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> +
> +	/* Cap sink rates w.r.t upfront values */
> +	if (intel_dp->max_link_rate_upfront) {
> +		int len = sink_len - 1;
> +		while (len > 0 && sink_rates[len] > intel_dp->max_link_rate_upfront)
> +			len--;
> +		sink_len = len + 1;
> +	}
> +
> +	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> +
> +	return intersect_rates(source_rates, source_len,
> +			       sink_rates, sink_len,
> +			       common_rates);
> +}
> +
> +static bool intel_dp_upfront_link_train(struct intel_dp *intel_dp)
> +{
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	struct intel_encoder *intel_encoder = &intel_dig_port->base;
> +	struct drm_device *dev = intel_encoder->base.dev;
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_modeset_acquire_ctx ctx;
> +	struct intel_crtc *intel_crtc;
> +	struct drm_crtc *crtc = NULL;
> +	int ret;
> +	bool done = false, has_mst = false;
> +	uint8_t lane_count, max_lanes = 4;
> +	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
> +	int clock, common_len;
> +	enum intel_display_power_domain power_domain;
> +
> +	power_domain = intel_display_port_power_domain(intel_encoder);
> +	intel_display_power_get(dev_priv, power_domain);
> +
> +	common_len = intel_dp_common_rates(intel_dp, common_rates);
> +	if (WARN_ON(common_len <= 0))
> +		return true;
> +
> +	drm_modeset_acquire_init(&ctx, 0);
> +retry:
> +	ret = drm_modeset_lock(&config->connection_mutex, &ctx);
> +	if (ret)
> +		goto exit_fail;
> +
> +	if (intel_encoder->base.crtc) {
> +		crtc = intel_encoder->base.crtc;
> +
> +		ret = drm_modeset_lock(&crtc->mutex, &ctx);
> +		if (ret)
> +			goto exit_fail;
> +
> +		ret = drm_modeset_lock(&crtc->primary->mutex, &ctx);
> +		if (ret)
> +			goto exit_fail;
> +
> +		intel_crtc = to_intel_crtc(crtc);
> +		has_mst = intel_crtc_has_type(intel_crtc->config,
> +					      INTEL_OUTPUT_DP_MST);
> +		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, false);
> +		if (ret)
> +			goto exit_fail;
> +	}
> +
> +	mutex_lock(&dev_priv->dpll_lock);
> +
> +	for (lane_count = max_lanes; lane_count >= 1 && !done;
> +	     lane_count >>= 1) {
> +		for (clock = common_len - 1; clock >= 0 && !done; clock--) {
> +			done = intel_dp->upfront_link_train(intel_dp,
> +							    common_rates[clock],
> +							    lane_count,
> +							    has_mst);
> +			if (done) {
> +				intel_dp->max_lanes_upfront = lane_count;
> +				intel_dp->max_link_rate_upfront = common_rates[clock];
> +				break;
> +			}
> +		}
> +	}
> +
> +	mutex_unlock(&dev_priv->dpll_lock);
> +
> +	if (crtc)
> +		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, true);
> +
> +exit_fail:
> +	if (ret == -EDEADLK) {
> +		drm_modeset_backoff(&ctx);
> +		goto retry;
> +	}
> +	drm_modeset_drop_locks(&ctx);
> +	drm_modeset_acquire_fini(&ctx);
> +	intel_display_power_put(dev_priv, power_domain);
> +	return done;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -211,6 +438,19 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  		target_clock = fixed_mode->clock;
>  	}
>  
> +	if (intel_dp->upfront_link_train && !intel_dp->upfront_done) {
> +		bool do_upfront_link_train;
> +		/* Do not do upfront link train, if it is a compliance
> +		 * request
> +		 */
> +		do_upfront_link_train = !intel_dp->upfront_done &&
> +			(intel_dp->compliance_test_type !=
> +			 DP_TEST_LINK_TRAINING);
> +
> +		if (do_upfront_link_train)
> +			intel_dp->upfront_done = intel_dp_upfront_link_train(intel_dp);
> +	}
> +
>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>  
> @@ -1256,60 +1496,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
>  	intel_dp->aux.transfer = intel_dp_aux_transfer;
>  }
>  
> -static int
> -intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
> -{
> -	if (intel_dp->num_sink_rates) {
> -		*sink_rates = intel_dp->sink_rates;
> -		return intel_dp->num_sink_rates;
> -	}
> -
> -	*sink_rates = default_rates;
> -
> -	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
> -}
> -
> -bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
> -{
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -
> -	/* WaDisableHBR2:skl */
> -	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
> -		return false;
> -
> -	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
> -	    (INTEL_INFO(dev)->gen >= 9))
> -		return true;
> -	else
> -		return false;
> -}
> -
> -static int
> -intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
> -{
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	struct drm_device *dev = dig_port->base.base.dev;
> -	int size;
> -
> -	if (IS_BROXTON(dev)) {
> -		*source_rates = bxt_rates;
> -		size = ARRAY_SIZE(bxt_rates);
> -	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> -		*source_rates = skl_rates;
> -		size = ARRAY_SIZE(skl_rates);
> -	} else {
> -		*source_rates = default_rates;
> -		size = ARRAY_SIZE(default_rates);
> -	}
> -
> -	/* This depends on the fact that 5.4 is last value in the array */
> -	if (!intel_dp_source_supports_hbr2(intel_dp))
> -		size--;
> -
> -	return size;
> -}
> -
>  static void
>  intel_dp_set_clock(struct intel_encoder *encoder,
>  		   struct intel_crtc_state *pipe_config)
> @@ -1343,42 +1529,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
>  	}
>  }
>  
> -static int intersect_rates(const int *source_rates, int source_len,
> -			   const int *sink_rates, int sink_len,
> -			   int *common_rates)
> -{
> -	int i = 0, j = 0, k = 0;
> -
> -	while (i < source_len && j < sink_len) {
> -		if (source_rates[i] == sink_rates[j]) {
> -			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
> -				return k;
> -			common_rates[k] = source_rates[i];
> -			++k;
> -			++i;
> -			++j;
> -		} else if (source_rates[i] < sink_rates[j]) {
> -			++i;
> -		} else {
> -			++j;
> -		}
> -	}
> -	return k;
> -}
> -
> -static int intel_dp_common_rates(struct intel_dp *intel_dp,
> -				 int *common_rates)
> -{
> -	const int *source_rates, *sink_rates;
> -	int source_len, sink_len;
> -
> -	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
> -	source_len = intel_dp_source_rates(intel_dp, &source_rates);
> -
> -	return intersect_rates(source_rates, source_len,
> -			       sink_rates, sink_len,
> -			       common_rates);
> -}
>  
>  static void snprintf_int_array(char *str, size_t len,
>  			       const int *array, int nelem)
> @@ -1436,6 +1586,9 @@ intel_dp_max_link_rate(struct intel_dp *intel_dp)
>  	int rates[DP_MAX_SUPPORTED_RATES] = {};
>  	int len;
>  
> +	if (intel_dp->max_link_rate_upfront)
> +		return intel_dp->max_link_rate_upfront;
> +
>  	len = intel_dp_common_rates(intel_dp, rates);
>  	if (WARN_ON(len <= 0))
>  		return 162000;
> @@ -1472,7 +1625,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	enum port port = dp_to_dig_port(intel_dp)->port;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
> -	int lane_count, clock;
> +	int lane_count, clock = 0;
>  	int min_lane_count = 1;
>  	int max_lane_count = intel_dp_max_lane_count(intel_dp);
>  	/* Conveniently, the link BW constants become indices with a shift...*/
> @@ -1551,11 +1704,23 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	for (; bpp >= 6*3; bpp -= 2*3) {
>  		mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
>  						   bpp);
> +		if (!is_edp(intel_dp) && intel_dp->upfront_done) {
> +			clock = max_clock;
> +			lane_count = intel_dp->max_lanes_upfront;
> +			link_clock = intel_dp->max_link_rate_upfront;
> +			link_avail = intel_dp_max_data_rate(link_clock, lane_count);
> +			mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
> +							   bpp);
> +			if (mode_rate <= link_avail)
> +				goto found;
> +			else
> +				continue;
> +		}
>  
>  		for (clock = min_clock; clock <= max_clock; clock++) {
>  			for (lane_count = min_lane_count;
> -				lane_count <= max_lane_count;
> -				lane_count <<= 1) {
> +			     lane_count <= max_lane_count;
> +			     lane_count <<= 1) {
>  
>  				link_clock = common_rates[clock];
>  				link_avail = intel_dp_max_data_rate(link_clock,
> @@ -1565,6 +1730,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					goto found;
>  				}
>  			}
> +
>  		}
>  	}
>  
> @@ -1585,7 +1751,6 @@ found:
>  	}
>  
>  	pipe_config->lane_count = lane_count;
> -
>  	pipe_config->pipe_bpp = bpp;
>  	pipe_config->port_clock = common_rates[clock];
>  
> @@ -4244,7 +4409,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
>  	struct drm_device *dev = connector->dev;
>  	enum drm_connector_status status;
>  	enum intel_display_power_domain power_domain;
> -	u8 sink_irq_vector = 0;
> +	u8 sink_irq_vector;
>  
>  	power_domain = intel_display_port_aux_power_domain(intel_encoder);
>  	intel_display_power_get(to_i915(dev), power_domain);
> @@ -4337,9 +4502,12 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
>  	}
>  
>  out:
> -	if ((status != connector_status_connected) &&
> -	    (intel_dp->is_mst == false))
> +	if (status != connector_status_connected) {
>  		intel_dp_unset_edid(intel_dp);
> +		intel_dp->upfront_done = false;
> +		intel_dp->max_lanes_upfront = 0;
> +		intel_dp->max_link_rate_upfront = 0;
> +	}
>  
>  	intel_display_power_put(to_i915(dev), power_domain);
>  	return;
> @@ -5587,6 +5755,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  	if (type == DRM_MODE_CONNECTOR_eDP)
>  		intel_encoder->type = INTEL_OUTPUT_EDP;
>  
> +	/* Initialize upfront link training vfunc for DP */
> +	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> +		if (IS_BROXTON(dev))

dev_priv

> +			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
> +	}
> +
>  	/* eDP only on port B and/or C on vlv/chv */
>  	if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
>  		    is_edp(intel_dp) && port != PORT_B && port != PORT_C))
> diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
> index 60fb39c..e58442a 100644
> --- a/drivers/gpu/drm/i915/intel_dp_link_training.c
> +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
> @@ -232,7 +232,6 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
>  static void
>  intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  {
> -	bool channel_eq = false;
>  	int tries, cr_tries;
>  	u32 training_pattern;
>  
> @@ -248,7 +247,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  
>  	tries = 0;
>  	cr_tries = 0;
> -	channel_eq = false;
> +	intel_dp->channel_eq_status = false;
>  	for (;;) {
>  		uint8_t link_status[DP_LINK_STATUS_SIZE];
>  
> @@ -276,7 +275,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  
>  		if (drm_dp_channel_eq_ok(link_status,
>  					 intel_dp->lane_count)) {
> -			channel_eq = true;
> +			intel_dp->channel_eq_status = true;
>  			break;
>  		}
>  
> @@ -302,7 +301,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
>  
>  	intel_dp_set_idle_link_train(intel_dp);
>  
> -	if (channel_eq)
> +	if (intel_dp->channel_eq_status)
>  		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 9963e5f..8b3d062 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -869,6 +869,15 @@ struct intel_dp {
>  	enum hdmi_force_audio force_audio;
>  	bool limited_color_range;
>  	bool color_range_auto;
> +
> +	/* Whether Channel Equalization was achieved during Link training */
> +	bool channel_eq_status;
> +
> +	/* Upfront link train parameters */
> +	int max_link_rate_upfront;
> +	uint8_t max_lanes_upfront;
> +	bool upfront_done;
> +
>  	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
>  	uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
>  	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
> @@ -926,6 +935,10 @@ struct intel_dp {
>  	/* This is called before a link training is starterd */
>  	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
>  
> +	/* For Upfront link training */
> +	bool (*upfront_link_train)(struct intel_dp *intel_dp, int clock,
> +				   uint8_t lane_count, bool link_mst);
> +
>  	/* Displayport compliance testing */
>  	unsigned long compliance_test_type;
>  	unsigned long compliance_test_data;
> @@ -1145,6 +1158,9 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
>  void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
>  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> +bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
> +				  int clock, uint8_t lane_count,
> +				  bool link_mst);
>  
>  unsigned int intel_fb_align_height(struct drm_device *dev,
>  				   unsigned int height,

Getting all existing calls of feature macros to pass dev_priv is tricky
enough without adding more...


Regards, David Weinehall
-- 
 /) David Weinehall <tao@acc.umu.se> /) Northern lights wander      (\
//  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
\)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL
  2016-08-19 23:33 ` [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
@ 2016-08-20  9:52   ` David Weinehall
  0 siblings, 0 replies; 27+ messages in thread
From: David Weinehall @ 2016-08-20  9:52 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Fri, Aug 19, 2016 at 04:33:47PM -0700, Manasi Navare wrote:
> From: Jim Bride <jim.bride@linux.intel.com>
> 
> Split the PLL selection code out of the BXT upfront link training
> implementation and into a stand-alone function in order to allow
> for the implementation of a platform neutral upfront link training
> function, and then enable upfront link training for Skylake.
> 
> Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c      | 56 ++++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_dp.c       |  4 +--
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 38 ++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  2 ++
>  drivers/gpu/drm/i915/intel_drv.h      |  4 ++-
>  5 files changed, 84 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 3921230..ef63b4b 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2378,8 +2378,43 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
>  	return connector;
>  }
>  
> +struct intel_shared_dpll *
> +intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
> +{
> +	struct intel_connector *connector = intel_dp->attached_connector;
> +	struct intel_encoder *encoder = connector->encoder;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> +	struct intel_shared_dpll *pll = NULL;
> +	struct intel_shared_dpll_config tmp_pll_config;
> +	enum intel_dpll_id dpll_id;
> +
> +	if (IS_BROXTON(dev_priv)) {
> +		dpll_id =  (enum intel_dpll_id)dig_port->port;
> +		/*
> +		 * Select the required PLL. This works for platforms where
> +		 * there is no shared DPLL.
> +		 */
> +		pll = &dev_priv->shared_dplls[dpll_id];
> +		if (WARN_ON(pll->active_mask)) {
> +
> +			DRM_ERROR("Shared DPLL in use. active_mask:%x\n",
> +				  pll->active_mask);
> +			pll = NULL;
> +		}
> +		tmp_pll_config = pll->config;
> +		if (!bxt_ddi_dp_set_dpll_hw_state(clock,
> +						  &pll->config.hw_state)) {
> +			DRM_ERROR("Could not setup DPLL\n");
> +			pll->config = tmp_pll_config;
> +		}
> +	} else if (IS_SKYLAKE(dev_priv)) {
> +		pll = skl_find_link_pll(dev_priv, clock);
> +	}
> +	return pll;
> +}
>  
> -bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
> +bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
>  				  int clock, uint8_t lane_count,
>  				  bool link_mst)
>  {
> @@ -2388,28 +2423,15 @@ bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_shared_dpll *pll;
>  	struct intel_shared_dpll_config tmp_pll_config;
> -	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> -	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
>  
> -	/*
> -	 * FIXME: Works only for BXT.
> -	 * Select the required PLL. This works for platforms where
> -	 * there is no shared DPLL.
> -	 */
> -	pll = &dev_priv->shared_dplls[dpll_id];
> -	if (WARN_ON(pll->active_mask)) {
> -		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
> +	pll = intel_ddi_get_link_dpll(intel_dp, clock);
> +	if (pll == NULL) {
> +		DRM_ERROR("Could not find DPLL for link training.\n");
>  		return false;
>  	}
>  
>  	tmp_pll_config = pll->config;
>  
> -	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
> -		DRM_ERROR("Could not setup DPLL\n");
> -		pll->config = tmp_pll_config;
> -		return false;
> -	}
> -
>  	/* Enable PLL followed by port */
>  	pll->funcs.enable(dev_priv, pll);
>  	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 5e362eb..fe156fb 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5757,8 +5757,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
>  
>  	/* Initialize upfront link training vfunc for DP */
>  	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> -		if (IS_BROXTON(dev))
> -			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
> +		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))

dev_priv, dev_priv

> +			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
>  	}
>  
>  	/* eDP only on port B and/or C on vlv/chv */
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 8ce220e..e5c025e 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -24,6 +24,44 @@
>  #include "intel_drv.h"
>  
>  struct intel_shared_dpll *
> +skl_find_link_pll(struct drm_i915_private *dev_priv, int clock)
> +{
> +	struct intel_shared_dpll *pll = NULL;
> +	struct intel_dpll_hw_state dpll_hw_state;
> +	enum intel_dpll_id i;
> +	bool found = false;
> +
> +	if (!skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
> +		return pll;
> +
> +	for (i = DPLL_ID_SKL_DPLL1; i <= DPLL_ID_SKL_DPLL3; i++) {
> +		pll = &dev_priv->shared_dplls[i];
> +
> +		/* Only want to check enabled timings first */
> +		if (pll->config.crtc_mask == 0)
> +			continue;
> +
> +		if (memcmp(&dpll_hw_state, &pll->config.hw_state,
> +			   sizeof(pll->config.hw_state)) == 0) {
> +			found = true;
> +			break;
> +		}
> +	}
> +
> +	/* Ok no matching timings, maybe there's a free one? */
> +	for (i = DPLL_ID_SKL_DPLL1;
> +	     ((found == false) && (i <= DPLL_ID_SKL_DPLL3)); i++) {
> +		pll = &dev_priv->shared_dplls[i];
> +		if (pll->config.crtc_mask == 0) {
> +			pll->config.hw_state = dpll_hw_state;
> +			break;
> +		}
> +	}
> +
> +	return pll;
> +}
> +
> +struct intel_shared_dpll *
>  intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
>  			    enum intel_dpll_id id)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> index cb28f8d..ec0fe66 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> @@ -167,5 +167,7 @@ bool bxt_ddi_dp_set_dpll_hw_state(int clock,
>  /* SKL dpll related functions */
>  bool skl_ddi_dp_set_dpll_hw_state(int clock,
>  				  struct intel_dpll_hw_state *dpll_hw_state);
> +struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv,
> +					    int clock);
>  
>  #endif /* _INTEL_DPLL_MGR_H_ */
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 8b3d062..374cbbd 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1158,9 +1158,11 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
>  			 struct intel_crtc_state *pipe_config);
>  void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
>  uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
> -bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
> +bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
>  				  int clock, uint8_t lane_count,
>  				  bool link_mst);
> +struct intel_shared_dpll *intel_ddi_get_link_dpll(struct intel_dp *intel_dp,
> +						  int clock);
>  
>  unsigned int intel_fb_align_height(struct drm_device *dev,
>  				   unsigned int height,


-- 
 /) David Weinehall <tao@acc.umu.se> /) Northern lights wander      (\
//  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
\)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-20  9:46   ` David Weinehall
@ 2016-08-22 18:11     ` Manasi Navare
  2016-08-22 18:17     ` Manasi Navare
  1 sibling, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-22 18:11 UTC (permalink / raw)
  To: David Weinehall; +Cc: intel-gfx

On Sat, Aug 20, 2016 at 11:46:19AM +0200, David Weinehall wrote:
> On Fri, Aug 19, 2016 at 04:33:49PM -0700, Manasi Navare wrote:
> > Get the PLLs for HSW/BDW using the platform specific function
> > and add hooks for enabling upfront link training on HSW and BDW.
> > 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
> >  drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
> >  2 files changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index ef63b4b..1d3ab8a 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
> >  		}
> >  	} else if (IS_SKYLAKE(dev_priv)) {
> >  		pll = skl_find_link_pll(dev_priv, clock);
> > +	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> > +		pll = hsw_ddi_dp_get_dpll(encoder, clock);
> >  	}
> >  	return pll;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index fe156fb..a1cea4d 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -5757,8 +5757,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  
> >  	/* Initialize upfront link training vfunc for DP */
> >  	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> > -		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
> > +		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
> > +		    IS_BROADWELL(dev) || IS_HASWELL(dev))
> >  			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
> > +
> >  	}
> >  
> >  	/* eDP only on port B and/or C on vlv/chv */
> 
> s/dev/dev_priv/ in feature macros.  To keep the diff down to a minimum
> you can ignore the rest of them, but I certainly wouldn't mind if
> you cleanup them all (and change INTEL_INFO()->gen to INTEL_GEN()).
> 
> 
> Regards: David Weinehall

Thanks for the review David. I will change the dev to dev_priv
in the usages in these patches. Cleaning them up all could be
a separate patch, not part of this patch series.

Regards Manasi
> -- 
>  /) David Weinehall <tao@acc.umu.se> /) Northern lights wander      (\
> //  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
> \)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-20  9:46   ` David Weinehall
  2016-08-22 18:11     ` Manasi Navare
@ 2016-08-22 18:17     ` Manasi Navare
  1 sibling, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-22 18:17 UTC (permalink / raw)
  To: David Weinehall; +Cc: intel-gfx

On Sat, Aug 20, 2016 at 11:46:19AM +0200, David Weinehall wrote:
> On Fri, Aug 19, 2016 at 04:33:49PM -0700, Manasi Navare wrote:
> > Get the PLLs for HSW/BDW using the platform specific function
> > and add hooks for enabling upfront link training on HSW and BDW.
> > 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
> >  drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
> >  2 files changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index ef63b4b..1d3ab8a 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
> >  		}
> >  	} else if (IS_SKYLAKE(dev_priv)) {
> >  		pll = skl_find_link_pll(dev_priv, clock);
> > +	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> > +		pll = hsw_ddi_dp_get_dpll(encoder, clock);
> >  	}
> >  	return pll;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index fe156fb..a1cea4d 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -5757,8 +5757,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
> >  
> >  	/* Initialize upfront link training vfunc for DP */
> >  	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> > -		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
> > +		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
> > +		    IS_BROADWELL(dev) || IS_HASWELL(dev))
> >  			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
> > +
> >  	}
> >  
> >  	/* eDP only on port B and/or C on vlv/chv */
> 
> s/dev/dev_priv/ in feature macros.  To keep the diff down to a minimum
> you can ignore the rest of them, but I certainly wouldn't mind if
> you cleanup them all (and change INTEL_INFO()->gen to INTEL_GEN()).
> 
> 
> Regards: David Weinehall

Thanks for reviewing this David. I will change the macros to use dev in
place of dev_priv in the usages in all these patches.
Rest of the cleanup should be a separate patch and not part fo this patch series.

Regards
Manasi


> -- 
>  /) David Weinehall <tao@acc.umu.se> /) Northern lights wander      (\
> //  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
> \)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (8 preceding siblings ...)
  2016-08-19 23:33 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

Decouple intel_dp_set_link_params() from struct intel_crtc_state. This
will be useful for implementing DP upfront link training.

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c    |  5 ++++-
 drivers/gpu/drm/i915/intel_dp.c     | 14 +++++++++-----
 drivers/gpu/drm/i915/intel_dp_mst.c |  6 ++++--
 drivers/gpu/drm/i915/intel_drv.h    |  3 ++-
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index c2df4e4..530ee9f 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1637,7 +1637,10 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 
 		intel_prepare_dp_ddi_buffers(intel_encoder);
 
-		intel_dp_set_link_params(intel_dp, crtc->config);
+		intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
+					 crtc->config->lane_count,
+					 intel_crtc_has_type(crtc->config,
+							     INTEL_OUTPUT_DP_MST));
 
 		intel_ddi_init_dp_buf_reg(intel_encoder);
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 364db90..2cfb2ae 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1640,11 +1640,12 @@ found:
 }
 
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *pipe_config)
+			      int link_rate, uint8_t lane_count,
+			      bool link_mst)
 {
-	intel_dp->link_rate = pipe_config->port_clock;
-	intel_dp->lane_count = pipe_config->lane_count;
-	intel_dp->link_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST);
+	intel_dp->link_rate = link_rate;
+	intel_dp->lane_count = lane_count;
+	intel_dp->link_mst = link_mst;
 }
 
 static void intel_dp_prepare(struct intel_encoder *encoder)
@@ -1656,7 +1657,10 @@ static void intel_dp_prepare(struct intel_encoder *encoder)
 	struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
 
-	intel_dp_set_link_params(intel_dp, crtc->config);
+	intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
+				 crtc->config->lane_count,
+				 intel_crtc_has_type(crtc->config,
+						     INTEL_OUTPUT_DP_MST));
 
 	/*
 	 * There are four kinds of DP registers:
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 629337d..e654fea 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -173,8 +173,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
 
 		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
-
-		intel_dp_set_link_params(intel_dp, intel_crtc->config);
+		intel_dp_set_link_params(intel_dp,
+					 intel_crtc->config->port_clock,
+					 intel_crtc->config->lane_count,
+					 true);
 
 		intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 92c38d4..c79ca10 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1367,7 +1367,8 @@ bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 			     struct intel_connector *intel_connector);
 void intel_dp_set_link_params(struct intel_dp *intel_dp,
-			      const struct intel_crtc_state *pipe_config);
+			      int link_rate, uint8_t lane_count,
+			      bool link_mst);
 void intel_dp_start_link_train(struct intel_dp *intel_dp);
 void intel_dp_stop_link_train(struct intel_dp *intel_dp);
 void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode);
-- 
1.9.1

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

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

* [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (9 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

The value of ddi_pll_sel is derived from the selection of shared dpll,
so just calculate the final value when necessary.

v2: Actually remove it from crtc state and delete remaining usages. (CI)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 45 ++++++++++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_display.c  | 43 +++++++--------------------------
 drivers/gpu/drm/i915/intel_dp_mst.c   |  3 ++-
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 27 ---------------------
 drivers/gpu/drm/i915/intel_drv.h      |  8 +------
 5 files changed, 45 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 530ee9f..8c87d21 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -546,6 +546,27 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
 	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
 }
 
+static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
+{
+	switch (pll->id) {
+	case DPLL_ID_WRPLL1:
+		return PORT_CLK_SEL_WRPLL1;
+	case DPLL_ID_WRPLL2:
+		return PORT_CLK_SEL_WRPLL2;
+	case DPLL_ID_SPLL:
+		return PORT_CLK_SEL_SPLL;
+	case DPLL_ID_LCPLL_810:
+		return PORT_CLK_SEL_LCPLL_810;
+	case DPLL_ID_LCPLL_1350:
+		return PORT_CLK_SEL_LCPLL_1350;
+	case DPLL_ID_LCPLL_2700:
+		return PORT_CLK_SEL_LCPLL_2700;
+	default:
+		MISSING_CASE(pll->id);
+		return PORT_CLK_SEL_NONE;
+	}
+}
+
 /* Starting with Haswell, different DDI ports can work in FDI mode for
  * connection to the PCH-located connectors. For this, it is necessary to train
  * both the DDI port and PCH receiver for the desired DDI buffer settings.
@@ -561,7 +582,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *encoder;
-	u32 temp, i, rx_ctl_val;
+	u32 temp, i, rx_ctl_val, ddi_pll_sel;
 
 	for_each_encoder_on_crtc(dev, crtc, encoder) {
 		WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
@@ -592,8 +613,9 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
 	I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
 
 	/* Configure Port Clock Select */
-	I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
-	WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
+	ddi_pll_sel = hsw_pll_to_ddi_pll_sel(intel_crtc->config->shared_dpll);
+	I915_WRITE(PORT_CLK_SEL(PORT_E), ddi_pll_sel);
+	WARN_ON(ddi_pll_sel != PORT_CLK_SEL_SPLL);
 
 	/* Start the training iterating through available voltages and emphasis,
 	 * testing each value twice. */
@@ -870,7 +892,7 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder,
 	int link_clock = 0;
 	uint32_t dpll_ctl1, dpll;
 
-	dpll = pipe_config->ddi_pll_sel;
+	dpll = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
 
 	dpll_ctl1 = I915_READ(DPLL_CTRL1);
 
@@ -918,7 +940,7 @@ static void hsw_ddi_clock_get(struct intel_encoder *encoder,
 	int link_clock = 0;
 	u32 val, pll;
 
-	val = pipe_config->ddi_pll_sel;
+	val = hsw_pll_to_ddi_pll_sel(pipe_config->shared_dpll);
 	switch (val & PORT_CLK_SEL_MASK) {
 	case PORT_CLK_SEL_LCPLL_810:
 		link_clock = 81000;
@@ -1586,13 +1608,15 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
 }
 
 void intel_ddi_clk_select(struct intel_encoder *encoder,
-			  const struct intel_crtc_state *pipe_config)
+			  struct intel_shared_dpll *pll)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = intel_ddi_get_encoder_port(encoder);
 
+	if (WARN_ON(!pll))
+		return;
+
 	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-		uint32_t dpll = pipe_config->ddi_pll_sel;
 		uint32_t val;
 
 		/* DDI -> PLL mapping  */
@@ -1600,14 +1624,13 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 
 		val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
 			DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
-		val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
+		val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->id, port) |
 			DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
 
 		I915_WRITE(DPLL_CTRL2, val);
 
 	} else if (INTEL_INFO(dev_priv)->gen < 9) {
-		WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
-		I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
+		I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll));
 	}
 }
 
@@ -1630,7 +1653,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
 		intel_edp_panel_on(intel_dp);
 	}
 
-	intel_ddi_clk_select(intel_encoder, crtc->config);
+	intel_ddi_clk_select(intel_encoder, crtc->config->shared_dpll);
 
 	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 22e6f56..c2f1620 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10326,15 +10326,12 @@ static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv,
 
 	switch (port) {
 	case PORT_A:
-		pipe_config->ddi_pll_sel = SKL_DPLL0;
 		id = DPLL_ID_SKL_DPLL0;
 		break;
 	case PORT_B:
-		pipe_config->ddi_pll_sel = SKL_DPLL1;
 		id = DPLL_ID_SKL_DPLL1;
 		break;
 	case PORT_C:
-		pipe_config->ddi_pll_sel = SKL_DPLL2;
 		id = DPLL_ID_SKL_DPLL2;
 		break;
 	default:
@@ -10353,25 +10350,10 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
 	u32 temp;
 
 	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
-	pipe_config->ddi_pll_sel = temp >> (port * 3 + 1);
+	id = temp >> (port * 3 + 1);
 
-	switch (pipe_config->ddi_pll_sel) {
-	case SKL_DPLL0:
-		id = DPLL_ID_SKL_DPLL0;
-		break;
-	case SKL_DPLL1:
-		id = DPLL_ID_SKL_DPLL1;
-		break;
-	case SKL_DPLL2:
-		id = DPLL_ID_SKL_DPLL2;
-		break;
-	case SKL_DPLL3:
-		id = DPLL_ID_SKL_DPLL3;
-		break;
-	default:
-		MISSING_CASE(pipe_config->ddi_pll_sel);
+	if (WARN_ON(id < SKL_DPLL0 || id > SKL_DPLL3))
 		return;
-	}
 
 	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
 }
@@ -10381,10 +10363,9 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 				struct intel_crtc_state *pipe_config)
 {
 	enum intel_dpll_id id;
+	uint32_t ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
 
-	pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
-
-	switch (pipe_config->ddi_pll_sel) {
+	switch (ddi_pll_sel) {
 	case PORT_CLK_SEL_WRPLL1:
 		id = DPLL_ID_WRPLL1;
 		break;
@@ -10404,7 +10385,7 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
 		id = DPLL_ID_LCPLL_2700;
 		break;
 	default:
-		MISSING_CASE(pipe_config->ddi_pll_sel);
+		MISSING_CASE(ddi_pll_sel);
 		/* fall through */
 	case PORT_CLK_SEL_NONE:
 		return;
@@ -12684,10 +12665,9 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 	DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
 
 	if (IS_BROXTON(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
+		DRM_DEBUG_KMS("dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
 			      "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
 			      "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
 			      pipe_config->dpll_hw_state.ebb0,
 			      pipe_config->dpll_hw_state.ebb4,
 			      pipe_config->dpll_hw_state.pll0,
@@ -12700,15 +12680,13 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 			      pipe_config->dpll_hw_state.pll10,
 			      pipe_config->dpll_hw_state.pcsdw12);
 	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: %u; dpll_hw_state: "
+		DRM_DEBUG_KMS("dpll_hw_state: "
 			      "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
 			      pipe_config->dpll_hw_state.ctrl1,
 			      pipe_config->dpll_hw_state.cfgcr1,
 			      pipe_config->dpll_hw_state.cfgcr2);
 	} else if (HAS_DDI(dev)) {
-		DRM_DEBUG_KMS("ddi_pll_sel: 0x%x; dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
-			      pipe_config->ddi_pll_sel,
+		DRM_DEBUG_KMS("dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
 			      pipe_config->dpll_hw_state.wrpll,
 			      pipe_config->dpll_hw_state.spll);
 	} else {
@@ -12821,7 +12799,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	struct intel_crtc_scaler_state scaler_state;
 	struct intel_dpll_hw_state dpll_hw_state;
 	struct intel_shared_dpll *shared_dpll;
-	uint32_t ddi_pll_sel;
 	bool force_thru;
 
 	/* FIXME: before the switch to atomic started, a new pipe_config was
@@ -12833,7 +12810,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	scaler_state = crtc_state->scaler_state;
 	shared_dpll = crtc_state->shared_dpll;
 	dpll_hw_state = crtc_state->dpll_hw_state;
-	ddi_pll_sel = crtc_state->ddi_pll_sel;
 	force_thru = crtc_state->pch_pfit.force_thru;
 
 	memset(crtc_state, 0, sizeof *crtc_state);
@@ -12842,7 +12818,6 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	crtc_state->scaler_state = scaler_state;
 	crtc_state->shared_dpll = shared_dpll;
 	crtc_state->dpll_hw_state = dpll_hw_state;
-	crtc_state->ddi_pll_sel = ddi_pll_sel;
 	crtc_state->pch_pfit.force_thru = force_thru;
 }
 
@@ -13271,8 +13246,6 @@ intel_pipe_config_compare(struct drm_device *dev,
 
 	PIPE_CONF_CHECK_I(double_wide);
 
-	PIPE_CONF_CHECK_X(ddi_pll_sel);
-
 	PIPE_CONF_CHECK_P(shared_dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index e654fea..131881d 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -170,7 +170,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
 	intel_mst->connector = found;
 
 	if (intel_dp->active_mst_links == 0) {
-		intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config);
+		intel_ddi_clk_select(&intel_dig_port->base,
+				     intel_crtc->config->shared_dpll);
 
 		intel_prepare_dp_ddi_buffers(&intel_dig_port->base);
 		intel_dp_set_link_params(intel_dp,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 5c1f2d2..0e1af4d 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -452,26 +452,6 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
 	return val & SPLL_PLL_ENABLE;
 }
 
-static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
-{
-	switch (pll->id) {
-	case DPLL_ID_WRPLL1:
-		return PORT_CLK_SEL_WRPLL1;
-	case DPLL_ID_WRPLL2:
-		return PORT_CLK_SEL_WRPLL2;
-	case DPLL_ID_SPLL:
-		return PORT_CLK_SEL_SPLL;
-	case DPLL_ID_LCPLL_810:
-		return PORT_CLK_SEL_LCPLL_810;
-	case DPLL_ID_LCPLL_1350:
-		return PORT_CLK_SEL_LCPLL_1350;
-	case DPLL_ID_LCPLL_2700:
-		return PORT_CLK_SEL_LCPLL_2700;
-	default:
-		return PORT_CLK_SEL_NONE;
-	}
-}
-
 #define LC_FREQ 2700
 #define LC_FREQ_2K U64_C(LC_FREQ * 2000)
 
@@ -751,8 +731,6 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	if (!pll)
 		return NULL;
 
-	crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
-
 	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
@@ -1274,8 +1252,6 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	if (!pll)
 		return NULL;
 
-	crtc_state->ddi_pll_sel = pll->id;
-
 	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
@@ -1622,9 +1598,6 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 
 	intel_reference_shared_dpll(pll, crtc_state);
 
-	/* shared DPLL id 0 is DPLL A */
-	crtc_state->ddi_pll_sel = pll->id;
-
 	return pll;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c79ca10..8c68ae8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -578,12 +578,6 @@ struct intel_crtc_state {
 	/* Selected dpll when shared or NULL. */
 	struct intel_shared_dpll *shared_dpll;
 
-	/*
-	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
-	 * - enum skl_dpll on SKL
-	 */
-	uint32_t ddi_pll_sel;
-
 	/* Actual register state of the dpll, for shared dpll cross-checking. */
 	struct intel_dpll_hw_state dpll_hw_state;
 
@@ -1124,7 +1118,7 @@ void intel_crt_reset(struct drm_encoder *encoder);
 
 /* intel_ddi.c */
 void intel_ddi_clk_select(struct intel_encoder *encoder,
-			  const struct intel_crtc_state *pipe_config);
+			  struct intel_shared_dpll *pll);
 void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder);
 void hsw_fdi_link_train(struct drm_crtc *crtc);
 void intel_ddi_init(struct drm_device *dev, enum port port);
-- 
1.9.1

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

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

* [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (10 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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

Split intel_ddi_pre_enable() into encoder type specific versions that
don't depend on crtc_state. The necessary parameters are passed as
function arguments. This split will be necessary for implementing DP
upfront link training.

v2:
* Rebased onto kernel v4.7 (Jim)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 98 +++++++++++++++++++++++-----------------
 1 file changed, 56 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8c87d21..e24dcc0 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1629,64 +1629,78 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 
 		I915_WRITE(DPLL_CTRL2, val);
 
-	} else if (INTEL_INFO(dev_priv)->gen < 9) {
+	} else if (INTEL_GEN(dev_priv) < 9) {
 		I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll));
 	}
 }
 
-static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
+				    int link_rate, uint32_t lane_count,
+				    struct intel_shared_dpll *pll,
+				    bool link_mst)
 {
-	struct drm_encoder *encoder = &intel_encoder->base;
-	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
-	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
-	enum port port = intel_ddi_get_encoder_port(intel_encoder);
-	int type = intel_encoder->type;
-
-	if (type == INTEL_OUTPUT_HDMI) {
-		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum port port = intel_ddi_get_encoder_port(encoder);
 
-		intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
-	}
+	intel_dp_set_link_params(intel_dp, link_rate, lane_count,
+				 link_mst);
 
-	if (type == INTEL_OUTPUT_EDP) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	if (encoder->type == INTEL_OUTPUT_EDP)
 		intel_edp_panel_on(intel_dp);
-	}
-
-	intel_ddi_clk_select(intel_encoder, crtc->config->shared_dpll);
 
-	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
-		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	intel_ddi_clk_select(encoder, pll);
+	intel_prepare_dp_ddi_buffers(encoder);
+	intel_ddi_init_dp_buf_reg(encoder);
+	intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+	intel_dp_start_link_train(intel_dp);
+	if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
+		intel_dp_stop_link_train(intel_dp);
+}
 
-		intel_prepare_dp_ddi_buffers(intel_encoder);
+static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
+				      bool has_hdmi_sink,
+				      struct drm_display_mode *adjusted_mode,
+				      struct intel_shared_dpll *pll)
+{
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct drm_encoder *drm_encoder = &encoder->base;
+	enum port port = intel_ddi_get_encoder_port(encoder);
+	int level = intel_ddi_hdmi_level(dev_priv, port);
 
-		intel_dp_set_link_params(intel_dp, crtc->config->port_clock,
-					 crtc->config->lane_count,
-					 intel_crtc_has_type(crtc->config,
-							     INTEL_OUTPUT_DP_MST));
+	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+	intel_ddi_clk_select(encoder, pll);
+	intel_prepare_hdmi_ddi_buffers(encoder);
 
-		intel_ddi_init_dp_buf_reg(intel_encoder);
+	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+		skl_ddi_set_iboost(encoder, level);
+	else if (IS_BROXTON(dev_priv))
+		bxt_ddi_vswing_sequence(dev_priv, level, port,
+					INTEL_OUTPUT_HDMI);
 
-		intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
-		intel_dp_start_link_train(intel_dp);
-		if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
-			intel_dp_stop_link_train(intel_dp);
-	} else if (type == INTEL_OUTPUT_HDMI) {
-		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
-		int level = intel_ddi_hdmi_level(dev_priv, port);
+	intel_hdmi->set_infoframes(drm_encoder, has_hdmi_sink, adjusted_mode);
+}
 
-		intel_prepare_hdmi_ddi_buffers(intel_encoder);
+static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+{
+	struct drm_encoder *encoder = &intel_encoder->base;
+	struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
+	int type = intel_encoder->type;
 
-		if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
-			skl_ddi_set_iboost(intel_encoder, level);
-		else if (IS_BROXTON(dev_priv))
-			bxt_ddi_vswing_sequence(dev_priv, level, port,
-						INTEL_OUTPUT_HDMI);
+	if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP)
+		intel_ddi_pre_enable_dp(intel_encoder,
+					crtc->config->port_clock,
+					crtc->config->lane_count,
+					crtc->config->shared_dpll,
+					intel_crtc_has_type(crtc->config,
+							    INTEL_OUTPUT_DP_MST));
 
-		intel_hdmi->set_infoframes(encoder,
-					   crtc->config->has_hdmi_sink,
-					   &crtc->config->base.adjusted_mode);
-	}
+	if (type == INTEL_OUTPUT_HDMI)
+		intel_ddi_pre_enable_hdmi(intel_encoder,
+					crtc->config->has_hdmi_sink,
+					&crtc->config->base.adjusted_mode,
+					crtc->config->shared_dpll);
 }
 
 static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
-- 
1.9.1

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

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

* [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (11 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v10 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

From: Durgadoss R <durgadoss.r@intel.com>

Split out of bxt_ddi_pll_select() the logic that calculates the pll
dividers and dpll_hw_state into a new function that doesn't depend on
crtc state. This will be used for enabling the port pll when doing
upfront link training.

v2:
* Refactored code so that bxt_clk_div need not be exported (Durga)
v1:
* Rebased on top of intel_dpll_mgr.c (Durga)
* Initial version from Ander on top of intel_ddi.c

Reviewed-by:  Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 165 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   3 +
 2 files changed, 104 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 0e1af4d..61d2311 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1460,6 +1460,8 @@ struct bxt_clk_div {
 	uint32_t m2_frac;
 	bool m2_frac_en;
 	uint32_t n;
+
+	int vco;
 };
 
 /* pre-calculated values for DP linkrates */
@@ -1473,57 +1475,60 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = {
 	{432000, 3, 1, 32, 1677722, 1, 1}
 };
 
-static struct intel_shared_dpll *
-bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
-	     struct intel_encoder *encoder)
+static bool
+bxt_ddi_hdmi_pll_dividers(struct intel_crtc *intel_crtc,
+			  struct intel_crtc_state *crtc_state, int clock,
+			  struct bxt_clk_div *clk_div)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-	struct intel_digital_port *intel_dig_port;
-	struct bxt_clk_div clk_div = {0};
-	int vco = 0;
-	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
-	uint32_t lanestagger;
-	int clock = crtc_state->port_clock;
+	struct dpll best_clock;
 
-	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		struct dpll best_clock;
+	/* Calculate HDMI div */
+	/*
+	 * FIXME: tie the following calculation into
+	 * i9xx_crtc_compute_clock
+	 */
+	if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
+		DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
+				 clock, pipe_name(intel_crtc->pipe));
+		return false;
+	}
 
-		/* Calculate HDMI div */
-		/*
-		 * FIXME: tie the following calculation into
-		 * i9xx_crtc_compute_clock
-		 */
-		if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
-			DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
-					 clock, pipe_name(crtc->pipe));
-			return NULL;
-		}
+	clk_div->p1 = best_clock.p1;
+	clk_div->p2 = best_clock.p2;
+	WARN_ON(best_clock.m1 != 2);
+	clk_div->n = best_clock.n;
+	clk_div->m2_int = best_clock.m2 >> 22;
+	clk_div->m2_frac = best_clock.m2 & ((1 << 22) - 1);
+	clk_div->m2_frac_en = clk_div->m2_frac != 0;
 
-		clk_div.p1 = best_clock.p1;
-		clk_div.p2 = best_clock.p2;
-		WARN_ON(best_clock.m1 != 2);
-		clk_div.n = best_clock.n;
-		clk_div.m2_int = best_clock.m2 >> 22;
-		clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
-		clk_div.m2_frac_en = clk_div.m2_frac != 0;
+	clk_div->vco = best_clock.vco;
 
-		vco = best_clock.vco;
-	} else if (encoder->type == INTEL_OUTPUT_DP ||
-		   encoder->type == INTEL_OUTPUT_EDP) {
-		int i;
+	return true;
+}
 
-		clk_div = bxt_dp_clk_val[0];
-		for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
-			if (bxt_dp_clk_val[i].clock == clock) {
-				clk_div = bxt_dp_clk_val[i];
-				break;
-			}
+static void bxt_ddi_dp_pll_dividers(int clock, struct bxt_clk_div *clk_div)
+{
+	int i;
+
+	*clk_div = bxt_dp_clk_val[0];
+	for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
+		if (bxt_dp_clk_val[i].clock == clock) {
+			*clk_div = bxt_dp_clk_val[i];
+			break;
 		}
-		vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
 	}
 
+	clk_div->vco = clock * 10 / 2 * clk_div->p1 * clk_div->p2;
+}
+
+static bool bxt_ddi_set_dpll_hw_state(int clock,
+			  struct bxt_clk_div *clk_div,
+			  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	int vco = clk_div->vco;
+	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
+	uint32_t lanestagger;
+
 	if (vco >= 6200000 && vco <= 6700000) {
 		prop_coef = 4;
 		int_coef = 9;
@@ -1542,12 +1547,9 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 		targ_cnt = 9;
 	} else {
 		DRM_ERROR("Invalid VCO\n");
-		return NULL;
+		return false;
 	}
 
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
 	if (clock > 270000)
 		lanestagger = 0x18;
 	else if (clock > 135000)
@@ -1559,33 +1561,68 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	else
 		lanestagger = 0x02;
 
-	crtc_state->dpll_hw_state.ebb0 =
-		PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
-	crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
-	crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
-	crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
+	dpll_hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
+	dpll_hw_state->pll0 = clk_div->m2_int;
+	dpll_hw_state->pll1 = PORT_PLL_N(clk_div->n);
+	dpll_hw_state->pll2 = clk_div->m2_frac;
 
-	if (clk_div.m2_frac_en)
-		crtc_state->dpll_hw_state.pll3 =
-			PORT_PLL_M2_FRAC_ENABLE;
+	if (clk_div->m2_frac_en)
+		dpll_hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
 
-	crtc_state->dpll_hw_state.pll6 =
-		prop_coef | PORT_PLL_INT_COEFF(int_coef);
-	crtc_state->dpll_hw_state.pll6 |=
-		PORT_PLL_GAIN_CTL(gain_ctl);
+	dpll_hw_state->pll6 = prop_coef | PORT_PLL_INT_COEFF(int_coef);
+	dpll_hw_state->pll6 |= PORT_PLL_GAIN_CTL(gain_ctl);
 
-	crtc_state->dpll_hw_state.pll8 = targ_cnt;
+	dpll_hw_state->pll8 = targ_cnt;
 
-	crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
+	dpll_hw_state->pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
 
-	crtc_state->dpll_hw_state.pll10 =
+	dpll_hw_state->pll10 =
 		PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
 		| PORT_PLL_DCO_AMP_OVR_EN_H;
 
-	crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+	dpll_hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+
+	dpll_hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
+
+	return true;
+}
+
+bool bxt_ddi_dp_set_dpll_hw_state(int clock,
+			  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	struct bxt_clk_div clk_div = {0};
+
+	bxt_ddi_dp_pll_dividers(clock, &clk_div);
+
+	return bxt_ddi_set_dpll_hw_state(clock, &clk_div, dpll_hw_state);
+}
+
+static struct intel_shared_dpll *
+bxt_get_dpll(struct intel_crtc *crtc,
+		struct intel_crtc_state *crtc_state,
+		struct intel_encoder *encoder)
+{
+	struct bxt_clk_div clk_div = {0};
+	struct intel_dpll_hw_state dpll_hw_state = {0};
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_digital_port *intel_dig_port;
+	struct intel_shared_dpll *pll;
+	int i, clock = crtc_state->port_clock;
+
+	if (encoder->type == INTEL_OUTPUT_HDMI
+	    && !bxt_ddi_hdmi_pll_dividers(crtc, crtc_state,
+					  clock, &clk_div))
+			return false;
+
+	if ((encoder->type == INTEL_OUTPUT_DP ||
+		encoder->type == INTEL_OUTPUT_EDP) &&
+		!bxt_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
+			return false;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
 
-	crtc_state->dpll_hw_state.pcsdw12 =
-		LANESTAGGER_STRAP_OVRD | lanestagger;
+	crtc_state->dpll_hw_state = dpll_hw_state;
 
 	intel_dig_port = enc_to_dig_port(&encoder->base);
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 89c5ada..11a85a5 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -160,5 +160,8 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc);
 void intel_shared_dpll_commit(struct drm_atomic_state *state);
 void intel_shared_dpll_init(struct drm_device *dev);
 
+/* BXT dpll related functions */
+bool bxt_ddi_dp_set_dpll_hw_state(int clock,
+			  struct intel_dpll_hw_state *dpll_hw_state);
 
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH v10 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (12 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx

From: Durgadoss R <durgadoss.r@intel.com>

To support USB type C alternate DP mode, the display driver needs to
know the number of lanes required by the DP panel as well as number
of lanes that can be supported by the type-C cable. Sometimes, the
type-C cable may limit the bandwidth even if Panel can support
more lanes. To address these scenarios, the display driver will
start link training with max lanes, and if that fails, the driver
falls back to x2 lanes; and repeats this procedure for all
bandwidth/lane configurations.

* Since link training is done before modeset only the port
  (and not pipe/planes) and its associated PLLs are enabled.
* On DP hotplug: Directly start link training on the DP encoder.
* On Connected boot scenarios: When booted with an LFP and a DP,
  sometimes BIOS brings up DP. In these cases, we disable the
  crtc and then do upfront link training; and bring it back up.
* All local changes made for upfront link training are reset
  to their previous values once it is done; so that the
  subsequent modeset is not aware of these changes.

Changes since v9:
* Change the macros to use dev_priv in place of dev (David Weinehall)
Changes since v8:
* Reset upfront lane count and link rate values on HPD
for DP connector physical disconnect (Manasi)
Changes since v7:
* Move the upfront link training to intel_dp_mode_valid()
  to avoid a race condition with DP MST sideband comms. (Ville)
Changes since v6:
* Fix some initialization bugs on link_rate (Jim Bride)
* Use link_rate (and not link_bw) for upfront (Ville)
* Make intel_dp_upfront*() as a vfunc (Ander)
* The train_set_valid variable in intel_dp was removed due to
  issues in fast link training. So, to indicate the link train
  status, move the channel_eq inside intel_dp.
Changes since v5:
* Moved retry logic in upfront to intel_dp.c so that it
  can be used for all platforms.
Changes since v4:
* Removed usage of crtc_state in upfront link training;
  Hence no need to find free crtc to do upfront now.
* Re-enable crtc if it was disabled for upfront.
* Use separate variables to track max lane count
  and link rate found by upfront, without modifying
  the original DPCD read from panel.
Changes since v3:
* Fixed a return value on BXT check
* Reworked on top of bxt_ddi_pll_select split from Ander
* Renamed from ddi_upfront to bxt_upfront since the
  upfront logic includes BXT specific functions for now.
Changes since v2:
* Rebased on top of latest dpll_mgr.c code and
  latest HPD related clean ups.
* Corrected return values from upfront (Ander)
* Corrected atomic locking for upfront in intel_dp.c (Ville)
Changes since v1:
*  all pll related functions inside ddi.c

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c              |  47 ++++
 drivers/gpu/drm/i915/intel_dp.c               | 372 +++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_dp_link_training.c |   7 +-
 drivers/gpu/drm/i915/intel_drv.h              |  16 ++
 4 files changed, 339 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index dfb3fb6..3921230 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2378,6 +2378,53 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
 	return connector;
 }
 
+
+bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+				  int clock, uint8_t lane_count,
+				  bool link_mst)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = connector->encoder;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config tmp_pll_config;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
+
+	/*
+	 * FIXME: Works only for BXT.
+	 * Select the required PLL. This works for platforms where
+	 * there is no shared DPLL.
+	 */
+	pll = &dev_priv->shared_dplls[dpll_id];
+	if (WARN_ON(pll->active_mask)) {
+		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
+		return false;
+	}
+
+	tmp_pll_config = pll->config;
+
+	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
+		DRM_ERROR("Could not setup DPLL\n");
+		pll->config = tmp_pll_config;
+		return false;
+	}
+
+	/* Enable PLL followed by port */
+	pll->funcs.enable(dev_priv, pll);
+	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
+
+	DRM_DEBUG_KMS("Upfront link train %s: link_clock:%d lanes:%d\n",
+	intel_dp->channel_eq_status ? "Passed" : "Failed", clock, lane_count);
+
+	/* Disable port followed by PLL for next retry/clean up */
+	intel_ddi_post_disable(encoder);
+	pll->funcs.disable(dev_priv, pll);
+
+	pll->config = tmp_pll_config;
+	return intel_dp->channel_eq_status;
+}
+
 void intel_ddi_init(struct drm_device *dev, enum port port)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2cfb2ae..165d029 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -153,12 +153,21 @@ intel_dp_max_link_bw(struct intel_dp  *intel_dp)
 static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-	u8 source_max, sink_max;
+	u8 temp, source_max, sink_max;
 
 	source_max = intel_dig_port->max_lanes;
 	sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
 
-	return min(source_max, sink_max);
+	temp = min(source_max, sink_max);
+
+	/*
+	 * Limit max lanes w.r.t to the max value found
+	 * using Upfront link training also.
+	 */
+	if (intel_dp->max_lanes_upfront)
+		return min(temp, intel_dp->max_lanes_upfront);
+	else
+		return temp;
 }
 
 /*
@@ -190,6 +199,224 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static int intel_dp_upfront_crtc_disable(struct intel_crtc *crtc,
+				struct drm_modeset_acquire_ctx *ctx,
+				bool enable)
+{
+	int ret;
+	struct drm_atomic_state *state;
+	struct intel_crtc_state *crtc_state;
+	struct drm_device *dev = crtc->base.dev;
+	enum pipe pipe = crtc->pipe;
+
+	state = drm_atomic_state_alloc(dev);
+	if (!state)
+		return -ENOMEM;
+
+	state->acquire_ctx = ctx;
+
+	crtc_state = intel_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state)) {
+		ret = PTR_ERR(crtc_state);
+		drm_atomic_state_free(state);
+		return ret;
+	}
+
+	DRM_DEBUG_KMS("%sabling crtc %c %s upfront link train\n",
+			enable ? "En" : "Dis",
+			pipe_name(pipe),
+			enable ? "after" : "before");
+
+	crtc_state->base.active = enable;
+	ret = drm_atomic_commit(state);
+	if (ret)
+		drm_atomic_state_free(state);
+
+	return ret;
+}
+
+static int
+intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
+{
+	if (intel_dp->num_sink_rates) {
+		*sink_rates = intel_dp->sink_rates;
+		return intel_dp->num_sink_rates;
+	}
+
+	*sink_rates = default_rates;
+
+	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+}
+
+bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+
+	/* WaDisableHBR2:skl */
+	if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_B0))
+		return false;
+
+	if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) ||
+	    IS_BROADWELL(dev_priv) || (INTEL_GEN(dev_priv) >= 9))
+		return true;
+	else
+		return false;
+}
+
+static int
+intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
+{
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+	int size;
+
+	if (IS_BROXTON(dev_priv)) {
+		*source_rates = bxt_rates;
+		size = ARRAY_SIZE(bxt_rates);
+	} else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
+		*source_rates = skl_rates;
+		size = ARRAY_SIZE(skl_rates);
+	} else {
+		*source_rates = default_rates;
+		size = ARRAY_SIZE(default_rates);
+	}
+
+	/* This depends on the fact that 5.4 is last value in the array */
+	if (!intel_dp_source_supports_hbr2(intel_dp))
+		size--;
+
+	return size;
+}
+
+static int intersect_rates(const int *source_rates, int source_len,
+			   const int *sink_rates, int sink_len,
+			   int *common_rates)
+{
+	int i = 0, j = 0, k = 0;
+
+	while (i < source_len && j < sink_len) {
+		if (source_rates[i] == sink_rates[j]) {
+			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
+				return k;
+			common_rates[k] = source_rates[i];
+			++k;
+			++i;
+			++j;
+		} else if (source_rates[i] < sink_rates[j]) {
+			++i;
+		} else {
+			++j;
+		}
+	}
+	return k;
+}
+
+static int intel_dp_common_rates(struct intel_dp *intel_dp,
+				 int *common_rates)
+{
+	const int *source_rates, *sink_rates;
+	int source_len, sink_len;
+
+	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
+
+	/* Cap sink rates w.r.t upfront values */
+	if (intel_dp->max_link_rate_upfront) {
+		int len = sink_len - 1;
+		while (len > 0 && sink_rates[len] > intel_dp->max_link_rate_upfront)
+			len--;
+		sink_len = len + 1;
+	}
+
+	source_len = intel_dp_source_rates(intel_dp, &source_rates);
+
+	return intersect_rates(source_rates, source_len,
+			       sink_rates, sink_len,
+			       common_rates);
+}
+
+static bool intel_dp_upfront_link_train(struct intel_dp *intel_dp)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+	struct drm_device *dev = intel_encoder->base.dev;
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_mode_config *config = &dev->mode_config;
+	struct drm_modeset_acquire_ctx ctx;
+	struct intel_crtc *intel_crtc;
+	struct drm_crtc *crtc = NULL;
+	int ret;
+	bool done = false, has_mst = false;
+	uint8_t lane_count, max_lanes = 4;
+	int common_rates[DP_MAX_SUPPORTED_RATES] = {};
+	int clock, common_len;
+	enum intel_display_power_domain power_domain;
+
+	power_domain = intel_display_port_power_domain(intel_encoder);
+	intel_display_power_get(dev_priv, power_domain);
+
+	common_len = intel_dp_common_rates(intel_dp, common_rates);
+	if (WARN_ON(common_len <= 0))
+		return true;
+
+	drm_modeset_acquire_init(&ctx, 0);
+retry:
+	ret = drm_modeset_lock(&config->connection_mutex, &ctx);
+	if (ret)
+		goto exit_fail;
+
+	if (intel_encoder->base.crtc) {
+		crtc = intel_encoder->base.crtc;
+
+		ret = drm_modeset_lock(&crtc->mutex, &ctx);
+		if (ret)
+			goto exit_fail;
+
+		ret = drm_modeset_lock(&crtc->primary->mutex, &ctx);
+		if (ret)
+			goto exit_fail;
+
+		intel_crtc = to_intel_crtc(crtc);
+		has_mst = intel_crtc_has_type(intel_crtc->config,
+					      INTEL_OUTPUT_DP_MST);
+		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, false);
+		if (ret)
+			goto exit_fail;
+	}
+
+	mutex_lock(&dev_priv->dpll_lock);
+
+	for (lane_count = max_lanes; lane_count >= 1 && !done;
+	     lane_count >>= 1) {
+		for (clock = common_len - 1; clock >= 0 && !done; clock--) {
+			done = intel_dp->upfront_link_train(intel_dp,
+							    common_rates[clock],
+							    lane_count,
+							    has_mst);
+			if (done) {
+				intel_dp->max_lanes_upfront = lane_count;
+				intel_dp->max_link_rate_upfront = common_rates[clock];
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&dev_priv->dpll_lock);
+
+	if (crtc)
+		ret = intel_dp_upfront_crtc_disable(intel_crtc, &ctx, true);
+
+exit_fail:
+	if (ret == -EDEADLK) {
+		drm_modeset_backoff(&ctx);
+		goto retry;
+	}
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+	intel_display_power_put(dev_priv, power_domain);
+	return done;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -211,6 +438,19 @@ intel_dp_mode_valid(struct drm_connector *connector,
 		target_clock = fixed_mode->clock;
 	}
 
+	if (intel_dp->upfront_link_train && !intel_dp->upfront_done) {
+		bool do_upfront_link_train;
+		/* Do not do upfront link train, if it is a compliance
+		 * request
+		 */
+		do_upfront_link_train = !intel_dp->upfront_done &&
+			(intel_dp->compliance_test_type !=
+			 DP_TEST_LINK_TRAINING);
+
+		if (do_upfront_link_train)
+			intel_dp->upfront_done = intel_dp_upfront_link_train(intel_dp);
+	}
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -1256,60 +1496,6 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
 }
 
-static int
-intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
-{
-	if (intel_dp->num_sink_rates) {
-		*sink_rates = intel_dp->sink_rates;
-		return intel_dp->num_sink_rates;
-	}
-
-	*sink_rates = default_rates;
-
-	return (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
-}
-
-bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-
-	/* WaDisableHBR2:skl */
-	if (IS_SKL_REVID(dev, 0, SKL_REVID_B0))
-		return false;
-
-	if ((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || IS_BROADWELL(dev) ||
-	    (INTEL_INFO(dev)->gen >= 9))
-		return true;
-	else
-		return false;
-}
-
-static int
-intel_dp_source_rates(struct intel_dp *intel_dp, const int **source_rates)
-{
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	struct drm_device *dev = dig_port->base.base.dev;
-	int size;
-
-	if (IS_BROXTON(dev)) {
-		*source_rates = bxt_rates;
-		size = ARRAY_SIZE(bxt_rates);
-	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-		*source_rates = skl_rates;
-		size = ARRAY_SIZE(skl_rates);
-	} else {
-		*source_rates = default_rates;
-		size = ARRAY_SIZE(default_rates);
-	}
-
-	/* This depends on the fact that 5.4 is last value in the array */
-	if (!intel_dp_source_supports_hbr2(intel_dp))
-		size--;
-
-	return size;
-}
-
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
 		   struct intel_crtc_state *pipe_config)
@@ -1343,42 +1529,6 @@ intel_dp_set_clock(struct intel_encoder *encoder,
 	}
 }
 
-static int intersect_rates(const int *source_rates, int source_len,
-			   const int *sink_rates, int sink_len,
-			   int *common_rates)
-{
-	int i = 0, j = 0, k = 0;
-
-	while (i < source_len && j < sink_len) {
-		if (source_rates[i] == sink_rates[j]) {
-			if (WARN_ON(k >= DP_MAX_SUPPORTED_RATES))
-				return k;
-			common_rates[k] = source_rates[i];
-			++k;
-			++i;
-			++j;
-		} else if (source_rates[i] < sink_rates[j]) {
-			++i;
-		} else {
-			++j;
-		}
-	}
-	return k;
-}
-
-static int intel_dp_common_rates(struct intel_dp *intel_dp,
-				 int *common_rates)
-{
-	const int *source_rates, *sink_rates;
-	int source_len, sink_len;
-
-	sink_len = intel_dp_sink_rates(intel_dp, &sink_rates);
-	source_len = intel_dp_source_rates(intel_dp, &source_rates);
-
-	return intersect_rates(source_rates, source_len,
-			       sink_rates, sink_len,
-			       common_rates);
-}
 
 static void snprintf_int_array(char *str, size_t len,
 			       const int *array, int nelem)
@@ -1436,6 +1586,9 @@ intel_dp_max_link_rate(struct intel_dp *intel_dp)
 	int rates[DP_MAX_SUPPORTED_RATES] = {};
 	int len;
 
+	if (intel_dp->max_link_rate_upfront)
+		return intel_dp->max_link_rate_upfront;
+
 	len = intel_dp_common_rates(intel_dp, rates);
 	if (WARN_ON(len <= 0))
 		return 162000;
@@ -1472,7 +1625,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	enum port port = dp_to_dig_port(intel_dp)->port;
 	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
-	int lane_count, clock;
+	int lane_count, clock = 0;
 	int min_lane_count = 1;
 	int max_lane_count = intel_dp_max_lane_count(intel_dp);
 	/* Conveniently, the link BW constants become indices with a shift...*/
@@ -1551,11 +1704,23 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	for (; bpp >= 6*3; bpp -= 2*3) {
 		mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
 						   bpp);
+		if (!is_edp(intel_dp) && intel_dp->upfront_done) {
+			clock = max_clock;
+			lane_count = intel_dp->max_lanes_upfront;
+			link_clock = intel_dp->max_link_rate_upfront;
+			link_avail = intel_dp_max_data_rate(link_clock, lane_count);
+			mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
+							   bpp);
+			if (mode_rate <= link_avail)
+				goto found;
+			else
+				continue;
+		}
 
 		for (clock = min_clock; clock <= max_clock; clock++) {
 			for (lane_count = min_lane_count;
-				lane_count <= max_lane_count;
-				lane_count <<= 1) {
+			     lane_count <= max_lane_count;
+			     lane_count <<= 1) {
 
 				link_clock = common_rates[clock];
 				link_avail = intel_dp_max_data_rate(link_clock,
@@ -1565,6 +1730,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 					goto found;
 				}
 			}
+
 		}
 	}
 
@@ -1585,7 +1751,6 @@ found:
 	}
 
 	pipe_config->lane_count = lane_count;
-
 	pipe_config->pipe_bpp = bpp;
 	pipe_config->port_clock = common_rates[clock];
 
@@ -4244,7 +4409,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 	struct drm_device *dev = connector->dev;
 	enum drm_connector_status status;
 	enum intel_display_power_domain power_domain;
-	u8 sink_irq_vector = 0;
+	u8 sink_irq_vector;
 
 	power_domain = intel_display_port_aux_power_domain(intel_encoder);
 	intel_display_power_get(to_i915(dev), power_domain);
@@ -4337,9 +4502,12 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
 	}
 
 out:
-	if ((status != connector_status_connected) &&
-	    (intel_dp->is_mst == false))
+	if (status != connector_status_connected) {
 		intel_dp_unset_edid(intel_dp);
+		intel_dp->upfront_done = false;
+		intel_dp->max_lanes_upfront = 0;
+		intel_dp->max_link_rate_upfront = 0;
+	}
 
 	intel_display_power_put(to_i915(dev), power_domain);
 	return;
@@ -5587,6 +5755,12 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 	if (type == DRM_MODE_CONNECTOR_eDP)
 		intel_encoder->type = INTEL_OUTPUT_EDP;
 
+	/* Initialize upfront link training vfunc for DP */
+	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
+		if (IS_BROXTON(dev_priv))
+			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
+	}
+
 	/* eDP only on port B and/or C on vlv/chv */
 	if (WARN_ON((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
 		    is_edp(intel_dp) && port != PORT_B && port != PORT_C))
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 60fb39c..e58442a 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -232,7 +232,6 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp)
 static void
 intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 {
-	bool channel_eq = false;
 	int tries, cr_tries;
 	u32 training_pattern;
 
@@ -248,7 +247,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	tries = 0;
 	cr_tries = 0;
-	channel_eq = false;
+	intel_dp->channel_eq_status = false;
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
 
@@ -276,7 +275,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 		if (drm_dp_channel_eq_ok(link_status,
 					 intel_dp->lane_count)) {
-			channel_eq = true;
+			intel_dp->channel_eq_status = true;
 			break;
 		}
 
@@ -302,7 +301,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	intel_dp_set_idle_link_train(intel_dp);
 
-	if (channel_eq)
+	if (intel_dp->channel_eq_status)
 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8c68ae8..3d5f330 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -869,6 +869,15 @@ struct intel_dp {
 	enum hdmi_force_audio force_audio;
 	bool limited_color_range;
 	bool color_range_auto;
+
+	/* Whether Channel Equalization was achieved during Link training */
+	bool channel_eq_status;
+
+	/* Upfront link train parameters */
+	int max_link_rate_upfront;
+	uint8_t max_lanes_upfront;
+	bool upfront_done;
+
 	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
 	uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
 	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
@@ -926,6 +935,10 @@ struct intel_dp {
 	/* This is called before a link training is starterd */
 	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
 
+	/* For Upfront link training */
+	bool (*upfront_link_train)(struct intel_dp *intel_dp, int clock,
+				   uint8_t lane_count, bool link_mst);
+
 	/* Displayport compliance testing */
 	unsigned long compliance_test_type;
 	unsigned long compliance_test_data;
@@ -1145,6 +1158,9 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
+bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+				  int clock, uint8_t lane_count,
+				  bool link_mst);
 
 unsigned int intel_fb_align_height(struct drm_device *dev,
 				   unsigned int height,
-- 
1.9.1

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

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

* [PATCH 6/9] drm/i915: Split skl_get_dpll()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (13 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH v10 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-29 18:32   ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx

From: Jim Bride <jim.bride@linux.intel.com>

Split out the DisplayPort and HDMI pll setup code into separate
functions and refactor the DP code does not directly depend on
crtc state, so that the code can be used for upfront link training.

Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   4 ++
 2 files changed, 87 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 61d2311..8ce220e 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1172,75 +1172,110 @@ skip_remaining_dividers:
 	return true;
 }
 
-static struct intel_shared_dpll *
-skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
-	     struct intel_encoder *encoder)
+static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc,
+				      struct intel_crtc_state *crtc_state,
+				      int clock)
 {
-	struct intel_shared_dpll *pll;
 	uint32_t ctrl1, cfgcr1, cfgcr2;
-	int clock = crtc_state->port_clock;
+	struct skl_wrpll_params wrpll_params = { 0, };
 
 	/*
 	 * See comment in intel_dpll_hw_state to understand why we always use 0
 	 * as the DPLL id in this function.
 	 */
-
 	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
 
-	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		struct skl_wrpll_params wrpll_params = { 0, };
+	ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
 
-		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+	if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
+		return false;
 
-		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
-			return NULL;
+	cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+		DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+		wrpll_params.dco_integer;
+
+	cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+		DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+		DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+		DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+		wrpll_params.central_freq;
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
+	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
+	return true;
+}
+
+
+bool skl_ddi_dp_set_dpll_hw_state(int clock,
+				  struct intel_dpll_hw_state *dpll_hw_state)
+{
+	uint32_t ctrl1;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+	switch (clock / 2) {
+	case 81000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
+		break;
+	case 135000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
+		break;
+	case 270000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
+		break;
+		/* eDP 1.4 rates */
+	case 162000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
+		break;
+	case 108000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
+		break;
+	case 216000:
+		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
+		break;
+	}
 
-		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
-			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
-			 wrpll_params.dco_integer;
+	dpll_hw_state->ctrl1 = ctrl1;
+	return true;
+}
 
-		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
-			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
-			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
-			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
-			 wrpll_params.central_freq;
+static struct intel_shared_dpll *
+skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
+{
+	struct intel_shared_dpll *pll;
+	int clock = crtc_state->port_clock;
+	bool bret;
+	struct intel_dpll_hw_state dpll_hw_state;
+
+	memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock);
+		if (!bret) {
+			DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
+			return NULL;
+		}
 	} else if (encoder->type == INTEL_OUTPUT_DP ||
 		   encoder->type == INTEL_OUTPUT_DP_MST ||
 		   encoder->type == INTEL_OUTPUT_EDP) {
-		switch (crtc_state->port_clock / 2) {
-		case 81000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
-			break;
-		case 135000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
-			break;
-		case 270000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
-			break;
-		/* eDP 1.4 rates */
-		case 162000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
-			break;
-		case 108000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
-			break;
-		case 216000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
-			break;
+		bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state);
+		if (!bret) {
+			DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
+			return NULL;
 		}
-
-		cfgcr1 = cfgcr2 = 0;
+		crtc_state->dpll_hw_state = dpll_hw_state;
 	} else {
 		return NULL;
 	}
 
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
-	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
-	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
-	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
-
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		pll = intel_find_shared_dpll(crtc, crtc_state,
 					     DPLL_ID_SKL_DPLL0,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 11a85a5..cb28f8d 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -164,4 +164,8 @@ void intel_shared_dpll_init(struct drm_device *dev);
 bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 			  struct intel_dpll_hw_state *dpll_hw_state);
 
+/* SKL dpll related functions */
+bool skl_ddi_dp_set_dpll_hw_state(int clock,
+				  struct intel_dpll_hw_state *dpll_hw_state);
+
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH v2 7/9] drm/i915/dp: Enable upfront link training on SKL
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (14 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx

From: Jim Bride <jim.bride@linux.intel.com>

Split the PLL selection code out of the BXT upfront link training
implementation and into a stand-alone function in order to allow
for the implementation of a platform neutral upfront link training
function, and then enable upfront link training for Skylake.

v2:
* Change the macro to use dev_priv instead of dev (David Weinehall)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 56 ++++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_dp.c       |  4 +--
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 38 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  2 ++
 drivers/gpu/drm/i915/intel_drv.h      |  4 ++-
 5 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 3921230..ef63b4b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2378,8 +2378,43 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
 	return connector;
 }
 
+struct intel_shared_dpll *
+intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
+{
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_encoder *encoder = connector->encoder;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_shared_dpll *pll = NULL;
+	struct intel_shared_dpll_config tmp_pll_config;
+	enum intel_dpll_id dpll_id;
+
+	if (IS_BROXTON(dev_priv)) {
+		dpll_id =  (enum intel_dpll_id)dig_port->port;
+		/*
+		 * Select the required PLL. This works for platforms where
+		 * there is no shared DPLL.
+		 */
+		pll = &dev_priv->shared_dplls[dpll_id];
+		if (WARN_ON(pll->active_mask)) {
+
+			DRM_ERROR("Shared DPLL in use. active_mask:%x\n",
+				  pll->active_mask);
+			pll = NULL;
+		}
+		tmp_pll_config = pll->config;
+		if (!bxt_ddi_dp_set_dpll_hw_state(clock,
+						  &pll->config.hw_state)) {
+			DRM_ERROR("Could not setup DPLL\n");
+			pll->config = tmp_pll_config;
+		}
+	} else if (IS_SKYLAKE(dev_priv)) {
+		pll = skl_find_link_pll(dev_priv, clock);
+	}
+	return pll;
+}
 
-bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
 				  int clock, uint8_t lane_count,
 				  bool link_mst)
 {
@@ -2388,28 +2423,15 @@ bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_shared_dpll *pll;
 	struct intel_shared_dpll_config tmp_pll_config;
-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-	enum intel_dpll_id dpll_id = (enum intel_dpll_id)dig_port->port;
 
-	/*
-	 * FIXME: Works only for BXT.
-	 * Select the required PLL. This works for platforms where
-	 * there is no shared DPLL.
-	 */
-	pll = &dev_priv->shared_dplls[dpll_id];
-	if (WARN_ON(pll->active_mask)) {
-		DRM_ERROR("Shared DPLL already in use. active_mask:%x\n", pll->active_mask);
+	pll = intel_ddi_get_link_dpll(intel_dp, clock);
+	if (pll == NULL) {
+		DRM_ERROR("Could not find DPLL for link training.\n");
 		return false;
 	}
 
 	tmp_pll_config = pll->config;
 
-	if (!bxt_ddi_dp_set_dpll_hw_state(clock, &pll->config.hw_state)) {
-		DRM_ERROR("Could not setup DPLL\n");
-		pll->config = tmp_pll_config;
-		return false;
-	}
-
 	/* Enable PLL followed by port */
 	pll->funcs.enable(dev_priv, pll);
 	intel_ddi_pre_enable_dp(encoder, clock, lane_count, pll, link_mst);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 165d029..e7a67ed 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5757,8 +5757,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev_priv))
-			intel_dp->upfront_link_train = intel_bxt_upfront_link_train;
+		if (IS_BROXTON(dev_priv) || IS_SKYLAKE(dev_priv))
+			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
 	}
 
 	/* eDP only on port B and/or C on vlv/chv */
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 8ce220e..e5c025e 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -24,6 +24,44 @@
 #include "intel_drv.h"
 
 struct intel_shared_dpll *
+skl_find_link_pll(struct drm_i915_private *dev_priv, int clock)
+{
+	struct intel_shared_dpll *pll = NULL;
+	struct intel_dpll_hw_state dpll_hw_state;
+	enum intel_dpll_id i;
+	bool found = false;
+
+	if (!skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state))
+		return pll;
+
+	for (i = DPLL_ID_SKL_DPLL1; i <= DPLL_ID_SKL_DPLL3; i++) {
+		pll = &dev_priv->shared_dplls[i];
+
+		/* Only want to check enabled timings first */
+		if (pll->config.crtc_mask == 0)
+			continue;
+
+		if (memcmp(&dpll_hw_state, &pll->config.hw_state,
+			   sizeof(pll->config.hw_state)) == 0) {
+			found = true;
+			break;
+		}
+	}
+
+	/* Ok no matching timings, maybe there's a free one? */
+	for (i = DPLL_ID_SKL_DPLL1;
+	     ((found == false) && (i <= DPLL_ID_SKL_DPLL3)); i++) {
+		pll = &dev_priv->shared_dplls[i];
+		if (pll->config.crtc_mask == 0) {
+			pll->config.hw_state = dpll_hw_state;
+			break;
+		}
+	}
+
+	return pll;
+}
+
+struct intel_shared_dpll *
 intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
 			    enum intel_dpll_id id)
 {
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index cb28f8d..ec0fe66 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -167,5 +167,7 @@ bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 /* SKL dpll related functions */
 bool skl_ddi_dp_set_dpll_hw_state(int clock,
 				  struct intel_dpll_hw_state *dpll_hw_state);
+struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv,
+					    int clock);
 
 #endif /* _INTEL_DPLL_MGR_H_ */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3d5f330..55bb39d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1158,9 +1158,11 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 			 struct intel_crtc_state *pipe_config);
 void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
 uint32_t ddi_signal_levels(struct intel_dp *intel_dp);
-bool intel_bxt_upfront_link_train(struct intel_dp *intel_dp,
+bool intel_ddi_upfront_link_train(struct intel_dp *intel_dp,
 				  int clock, uint8_t lane_count,
 				  bool link_mst);
+struct intel_shared_dpll *intel_ddi_get_link_dpll(struct intel_dp *intel_dp,
+						  int clock);
 
 unsigned int intel_fb_align_height(struct drm_device *dev,
 				   unsigned int height,
-- 
1.9.1

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

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

* [PATCH 8/9] drm/i915: Split hsw_get_dpll()
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (15 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH v2 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  2016-08-23  1:41 ` [PATCH v2 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx

Split out the DisplayPort and HDMI pll setup code into separate
functions and refactor the DP code that calculates the pll
so that it doesn't depend on crtc state.
This will be used for acquiring port pll when doing
upfront link training.

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 90 ++++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  6 +++
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index e5c025e..93f7aae 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -705,11 +705,65 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 	*r2_out = best.r2;
 }
 
+static struct intel_shared_dpll *hsw_ddi_hdmi_get_dpll(int clock,
+						       struct intel_crtc *crtc,
+						       struct intel_crtc_state *crtc_state)
+{
+	struct intel_shared_dpll *pll;
+	uint32_t val;
+	unsigned p, n2, r2;
+
+	hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+
+	val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
+	      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
+	      WRPLL_DIVIDER_POST(p);
+
+	crtc_state->dpll_hw_state.wrpll = val;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state,
+				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+
+	if (!pll)
+		return NULL;
+
+	return pll;
+}
+
+struct intel_shared_dpll *hsw_ddi_dp_get_dpll(struct intel_encoder *encoder,
+					      int clock)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id pll_id;
+
+	switch (clock / 2) {
+	case 81000:
+		pll_id = DPLL_ID_LCPLL_810;
+		break;
+	case 135000:
+		pll_id = DPLL_ID_LCPLL_1350;
+		break;
+	case 270000:
+		pll_id = DPLL_ID_LCPLL_2700;
+		break;
+	default:
+		DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
+		return NULL;
+	}
+
+	pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+
+	if (!pll)
+		return NULL;
+
+	return pll;
+}
+
 static struct intel_shared_dpll *
 hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	     struct intel_encoder *encoder)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll;
 	int clock = crtc_state->port_clock;
 
@@ -717,41 +771,12 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	       sizeof(crtc_state->dpll_hw_state));
 
 	if (encoder->type == INTEL_OUTPUT_HDMI) {
-		uint32_t val;
-		unsigned p, n2, r2;
-
-		hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-
-		val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
-		      WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
-		      WRPLL_DIVIDER_POST(p);
-
-		crtc_state->dpll_hw_state.wrpll = val;
-
-		pll = intel_find_shared_dpll(crtc, crtc_state,
-					     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+		pll = hsw_ddi_hdmi_get_dpll(clock, crtc, crtc_state);
 
 	} else if (encoder->type == INTEL_OUTPUT_DP ||
 		   encoder->type == INTEL_OUTPUT_DP_MST ||
 		   encoder->type == INTEL_OUTPUT_EDP) {
-		enum intel_dpll_id pll_id;
-
-		switch (clock / 2) {
-		case 81000:
-			pll_id = DPLL_ID_LCPLL_810;
-			break;
-		case 135000:
-			pll_id = DPLL_ID_LCPLL_1350;
-			break;
-		case 270000:
-			pll_id = DPLL_ID_LCPLL_2700;
-			break;
-		default:
-			DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
-			return NULL;
-		}
-
-		pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 
 	} else if (encoder->type == INTEL_OUTPUT_ANALOG) {
 		if (WARN_ON(crtc_state->port_clock / 2 != 135000))
@@ -774,7 +799,6 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	return pll;
 }
 
-
 static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
 	.enable = hsw_ddi_wrpll_enable,
 	.disable = hsw_ddi_wrpll_disable,
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index ec0fe66..f438535 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -164,10 +164,16 @@ void intel_shared_dpll_init(struct drm_device *dev);
 bool bxt_ddi_dp_set_dpll_hw_state(int clock,
 			  struct intel_dpll_hw_state *dpll_hw_state);
 
+
 /* SKL dpll related functions */
 bool skl_ddi_dp_set_dpll_hw_state(int clock,
 				  struct intel_dpll_hw_state *dpll_hw_state);
 struct intel_shared_dpll *skl_find_link_pll(struct drm_i915_private *dev_priv,
 					    int clock);
 
+
+/* HSW dpll related functions */
+struct intel_shared_dpll *hsw_ddi_dp_get_dpll(struct intel_encoder *encoder,
+					      int clock);
+
 #endif /* _INTEL_DPLL_MGR_H_ */
-- 
1.9.1

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

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

* [PATCH v2 9/9] drm/i915: Enable upfront link training support for HSW/BDW
       [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
                   ` (16 preceding siblings ...)
  2016-08-23  1:41 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
@ 2016-08-23  1:41 ` Manasi Navare
  17 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-23  1:41 UTC (permalink / raw)
  To: intel-gfx

Get the PLLs for HSW/BDW using the platform specific function
and add hooks for enabling upfront link training on HSW and BDW.

v2:
* Change the macro to use dev_priv instead of dev (David Weinehall)

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/intel_dp.c  | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ef63b4b..1d3ab8a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
 		}
 	} else if (IS_SKYLAKE(dev_priv)) {
 		pll = skl_find_link_pll(dev_priv, clock);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 	}
 	return pll;
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e7a67ed..a309754 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5757,7 +5757,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev_priv) || IS_SKYLAKE(dev_priv))
+		if (IS_BROXTON(dev_priv) || IS_SKYLAKE(dev_priv) ||
+		    IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
 			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
 	}
 
-- 
1.9.1

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

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

* Re: [PATCH 6/9] drm/i915: Split skl_get_dpll()
  2016-08-23  1:41 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
@ 2016-08-29 18:32   ` Manasi Navare
  0 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-29 18:32 UTC (permalink / raw)
  To: intel-gfx

On Mon, Aug 22, 2016 at 06:41:05PM -0700, Manasi Navare wrote:
> From: Jim Bride <jim.bride@linux.intel.com>
> 
> Split out the DisplayPort and HDMI pll setup code into separate
> functions and refactor the DP code does not directly depend on
> crtc state, so that the code can be used for upfront link training.
> 
> Signed-off-by: Jim Bride <jim.bride@linux.intel.com>
  Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>


> ---
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++-------------
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   4 ++
>  2 files changed, 87 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 61d2311..8ce220e 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -1172,75 +1172,110 @@ skip_remaining_dividers:
>  	return true;
>  }
>  
> -static struct intel_shared_dpll *
> -skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
> -	     struct intel_encoder *encoder)
> +static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc *crtc,
> +				      struct intel_crtc_state *crtc_state,
> +				      int clock)
>  {
> -	struct intel_shared_dpll *pll;
>  	uint32_t ctrl1, cfgcr1, cfgcr2;
> -	int clock = crtc_state->port_clock;
> +	struct skl_wrpll_params wrpll_params = { 0, };
>  
>  	/*
>  	 * See comment in intel_dpll_hw_state to understand why we always use 0
>  	 * as the DPLL id in this function.
>  	 */
> -
>  	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
>  
> -	if (encoder->type == INTEL_OUTPUT_HDMI) {
> -		struct skl_wrpll_params wrpll_params = { 0, };
> +	ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
>  
> -		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
> +	if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
> +		return false;
>  
> -		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
> -			return NULL;
> +	cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> +		DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> +		wrpll_params.dco_integer;
> +
> +	cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> +		DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> +		DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> +		DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> +		wrpll_params.central_freq;
> +
> +	memset(&crtc_state->dpll_hw_state, 0,
> +	       sizeof(crtc_state->dpll_hw_state));
> +
> +	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
> +	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
> +	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
> +	return true;
> +}
> +
> +
> +bool skl_ddi_dp_set_dpll_hw_state(int clock,
> +				  struct intel_dpll_hw_state *dpll_hw_state)
> +{
> +	uint32_t ctrl1;
> +
> +	/*
> +	 * See comment in intel_dpll_hw_state to understand why we always use 0
> +	 * as the DPLL id in this function.
> +	 */
> +	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
> +	switch (clock / 2) {
> +	case 81000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
> +		break;
> +	case 135000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
> +		break;
> +	case 270000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
> +		break;
> +		/* eDP 1.4 rates */
> +	case 162000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
> +		break;
> +	case 108000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
> +		break;
> +	case 216000:
> +		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
> +		break;
> +	}
>  
> -		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
> -			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
> -			 wrpll_params.dco_integer;
> +	dpll_hw_state->ctrl1 = ctrl1;
> +	return true;
> +}
>  
> -		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
> -			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
> -			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
> -			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> -			 wrpll_params.central_freq;
> +static struct intel_shared_dpll *
> +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
> +	     struct intel_encoder *encoder)
> +{
> +	struct intel_shared_dpll *pll;
> +	int clock = crtc_state->port_clock;
> +	bool bret;
> +	struct intel_dpll_hw_state dpll_hw_state;
> +
> +	memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
> +
> +	if (encoder->type == INTEL_OUTPUT_HDMI) {
> +		bret = skl_ddi_hdmi_pll_dividers(crtc, crtc_state, clock);
> +		if (!bret) {
> +			DRM_DEBUG_KMS("Could not get HDMI pll dividers.\n");
> +			return NULL;
> +		}
>  	} else if (encoder->type == INTEL_OUTPUT_DP ||
>  		   encoder->type == INTEL_OUTPUT_DP_MST ||
>  		   encoder->type == INTEL_OUTPUT_EDP) {
> -		switch (crtc_state->port_clock / 2) {
> -		case 81000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
> -			break;
> -		case 135000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
> -			break;
> -		case 270000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
> -			break;
> -		/* eDP 1.4 rates */
> -		case 162000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
> -			break;
> -		case 108000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
> -			break;
> -		case 216000:
> -			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
> -			break;
> +		bret = skl_ddi_dp_set_dpll_hw_state(clock, &dpll_hw_state);
> +		if (!bret) {
> +			DRM_DEBUG_KMS("Could not set DP dpll HW state.\n");
> +			return NULL;
>  		}
> -
> -		cfgcr1 = cfgcr2 = 0;
> +		crtc_state->dpll_hw_state = dpll_hw_state;
>  	} else {
>  		return NULL;
>  	}
>  
> -	memset(&crtc_state->dpll_hw_state, 0,
> -	       sizeof(crtc_state->dpll_hw_state));
> -
> -	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
> -	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
> -	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
> -
>  	if (encoder->type == INTEL_OUTPUT_EDP)
>  		pll = intel_find_shared_dpll(crtc, crtc_state,
>  					     DPLL_ID_SKL_DPLL0,
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> index 11a85a5..cb28f8d 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> @@ -164,4 +164,8 @@ void intel_shared_dpll_init(struct drm_device *dev);
>  bool bxt_ddi_dp_set_dpll_hw_state(int clock,
>  			  struct intel_dpll_hw_state *dpll_hw_state);
>  
> +/* SKL dpll related functions */
> +bool skl_ddi_dp_set_dpll_hw_state(int clock,
> +				  struct intel_dpll_hw_state *dpll_hw_state);
> +
>  #endif /* _INTEL_DPLL_MGR_H_ */
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-09 19:29 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
@ 2016-08-16 17:25   ` R, Durgadoss
  0 siblings, 0 replies; 27+ messages in thread
From: R, Durgadoss @ 2016-08-16 17:25 UTC (permalink / raw)
  To: Navare, Manasi D, intel-gfx

> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Manasi Navare
> Sent: Wednesday, August 10, 2016 12:59 AM
> To: intel-gfx@lists.freedesktop.org
> Subject: [Intel-gfx] [PATCH 9/9] drm/i915: Enable upfront link training
> support for HSW/BDW
> 
> Get the PLLs for HSW/BDW using the platform specific function
> and add hooks for enabling upfront link training on HSW and BDW.
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>

Thanks,
Durga

> ---
>  drivers/gpu/drm/i915/intel_ddi.c | 2 ++
>  drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> b/drivers/gpu/drm/i915/intel_ddi.c
> index ed9ebca..fd0c538 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp,
> int clock)
>  		}
>  	} else if (IS_SKYLAKE(dev_priv)) {
>  		pll = skl_find_link_pll(dev_priv, clock);
> +	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> +		pll = hsw_ddi_dp_get_dpll(encoder, clock);
>  	}
>  	return pll;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index 572119e..25190fa 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -5762,8 +5762,10 @@ intel_dp_init_connector(struct intel_digital_port
> *intel_dig_port,
> 
>  	/* Initialize upfront link training vfunc for DP */
>  	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
> -		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
> +		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
> +		    IS_BROADWELL(dev) || IS_HASWELL(dev))
>  			intel_dp->upfront_link_train =
> intel_ddi_upfront_link_train;
> +
>  	}
> 
>  	/* eDP only on port B and/or C on vlv/chv */
> --
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-09 19:29 [PATCH 0/9] Enable upfront link training on DDI platforms Manasi Navare
@ 2016-08-09 19:29 ` Manasi Navare
  2016-08-16 17:25   ` R, Durgadoss
  0 siblings, 1 reply; 27+ messages in thread
From: Manasi Navare @ 2016-08-09 19:29 UTC (permalink / raw)
  To: intel-gfx

Get the PLLs for HSW/BDW using the platform specific function
and add hooks for enabling upfront link training on HSW and BDW.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ed9ebca..fd0c538 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
 		}
 	} else if (IS_SKYLAKE(dev_priv)) {
 		pll = skl_find_link_pll(dev_priv, clock);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 	}
 	return pll;
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 572119e..25190fa 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5762,8 +5762,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
+		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
+		    IS_BROADWELL(dev) || IS_HASWELL(dev))
 			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
+
 	}
 
 	/* eDP only on port B and/or C on vlv/chv */
-- 
1.9.1

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

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

* [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW
  2016-08-09  2:33 [PATCH 0/9] Enable upfront link training on DDI platforms Manasi Navare
@ 2016-08-09  2:33 ` Manasi Navare
  0 siblings, 0 replies; 27+ messages in thread
From: Manasi Navare @ 2016-08-09  2:33 UTC (permalink / raw)
  To: intel-gfx

Get the PLLs for HSW/BDW using the platform specific function
and add hooks for enabling upfront link training on HSW and BDW.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c | 2 ++
 drivers/gpu/drm/i915/intel_dp.c  | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ed9ebca..fd0c538 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2410,6 +2410,8 @@ intel_ddi_get_link_dpll(struct intel_dp *intel_dp, int clock)
 		}
 	} else if (IS_SKYLAKE(dev_priv)) {
 		pll = skl_find_link_pll(dev_priv, clock);
+	} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
+		pll = hsw_ddi_dp_get_dpll(encoder, clock);
 	}
 	return pll;
 }
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 572119e..25190fa 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5762,8 +5762,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
 
 	/* Initialize upfront link training vfunc for DP */
 	if (intel_encoder->type != INTEL_OUTPUT_EDP) {
-		if (IS_BROXTON(dev) || IS_SKYLAKE(dev))
+		if (IS_BROXTON(dev) || IS_SKYLAKE(dev) ||
+		    IS_BROADWELL(dev) || IS_HASWELL(dev))
 			intel_dp->upfront_link_train = intel_ddi_upfront_link_train;
+
 	}
 
 	/* eDP only on port B and/or C on vlv/chv */
-- 
1.9.1

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

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

end of thread, other threads:[~2016-08-29 18:18 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1470770143-5163-1-git-send-email-manasi.d.navare@intel.com>
2016-08-19 23:33 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
2016-08-19 23:33 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
2016-08-19 23:33 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
2016-08-19 23:33 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
2016-08-19 23:33 ` [PATCH v9 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
2016-08-20  9:51   ` David Weinehall
2016-08-19 23:33 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
2016-08-19 23:33 ` [PATCH 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
2016-08-20  9:52   ` David Weinehall
2016-08-19 23:33 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
2016-08-19 23:33 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
2016-08-20  9:46   ` David Weinehall
2016-08-22 18:11     ` Manasi Navare
2016-08-22 18:17     ` Manasi Navare
2016-08-23  1:41 ` [PATCH 1/9] drm/i915: Don't pass crtc_state to intel_dp_set_link_params() Manasi Navare
2016-08-23  1:41 ` [PATCH v2 2/9] drm/i915: Remove ddi_pll_sel from intel_crtc_state Manasi Navare
2016-08-23  1:41 ` [PATCH v2 3/9] drm/i915: Split intel_ddi_pre_enable() into DP and HDMI versions Manasi Navare
2016-08-23  1:41 ` [PATCH v2 4/9] drm/i915: Split bxt_ddi_pll_select() Manasi Navare
2016-08-23  1:41 ` [PATCH v10 5/9] drm/i915/dp: Enable Upfront link training for typeC DP support on BXT Manasi Navare
2016-08-23  1:41 ` [PATCH 6/9] drm/i915: Split skl_get_dpll() Manasi Navare
2016-08-29 18:32   ` Manasi Navare
2016-08-23  1:41 ` [PATCH v2 7/9] drm/i915/dp: Enable upfront link training on SKL Manasi Navare
2016-08-23  1:41 ` [PATCH 8/9] drm/i915: Split hsw_get_dpll() Manasi Navare
2016-08-23  1:41 ` [PATCH v2 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
2016-08-09 19:29 [PATCH 0/9] Enable upfront link training on DDI platforms Manasi Navare
2016-08-09 19:29 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare
2016-08-16 17:25   ` R, Durgadoss
  -- strict thread matches above, loose matches on Subject: below --
2016-08-09  2:33 [PATCH 0/9] Enable upfront link training on DDI platforms Manasi Navare
2016-08-09  2:33 ` [PATCH 9/9] drm/i915: Enable upfront link training support for HSW/BDW Manasi Navare

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.